设计模式中的第三类是行为型模式,共11种,分别为:
策略、模板方法、观察者、责任链、 迭代子、备忘录、状态、命令、解释器、访问者、调停者
package com.jelly.mypattern.strategy; /** * 计算折扣 基接口 * @author jelly * */ public interface CalcDiscount { /** * 折扣 抽象方法 * @param price 原始价格 * @return 折扣后价格 */ public abstract double discount(double price); }
package com.jelly.mypattern.strategy; /** * 无折扣 * @author jelly * */ public class NoDiscount implements CalcDiscount { /** * * 折扣价 与原价相等 */ @Override public double discount(double price) { return price; } }
package com.jelly.mypattern.strategy; /** * 固定折扣 1 * @author jelly * */ public class FixedDiscount implements CalcDiscount{ @Override public double discount(double price) { return price-1; } }
package com.jelly.mypattern.strategy; public class PercentDiscount implements CalcDiscount{ @Override public double discount(double price) { return price *0.9; } }
package com.jelly.mypattern.strategy; /** * 客户端 上下文 * @author jelly * */ public class StrategyTest { public static void main(String[] args) { double goodsPrice=2000; CalcDiscount calcDiscount=new PercentDiscount(); double discountPrice=calcDiscount.discount(goodsPrice); System.out.println("商品原价为:"+goodsPrice); System.out.println("商品折扣价为:"+discountPrice); } }
注:享元工厂往往也是为单例的或静态的,称为单例享元工厂和静态享元工厂。单例与静态的区别在于,单例类可以被继承以重写其方法,因而是便于扩展的,
而静态方法因为无法被子类重写,故静态类不便于扩展。
下面是使用策略+享元工厂的实现。package com.jelly.mypattern.strategy; import java.util.HashMap; import java.util.Map; /** * 折扣享元工厂 类 * @author jelly * */ public class CalcDiscountFactory { private static CalcDiscountFactory instance=new CalcDiscountFactory(); private static final String NO_DISCOUNT ="noDiscount"; private static final String FIXED_DISCOUNT="fixedDiscount"; private static final String PERCENT_DISCOUNT="percentDiscount"; private Map<String,CalcDiscount> calcDiscountMap=new HashMap<String,CalcDiscount>(); public static CalcDiscountFactory getInstance(){ return instance; } public synchronized CalcDiscount getNoDiscount(){ CalcDiscount calcDiscount= calcDiscountMap.get(NO_DISCOUNT); if(calcDiscount==null){ calcDiscount=new NoDiscount(); calcDiscountMap.put(NO_DISCOUNT, calcDiscount); } return calcDiscount; } public synchronized CalcDiscount getFixedDiscount(){ CalcDiscount calcDiscount= calcDiscountMap.get(FIXED_DISCOUNT); if(calcDiscount==null){ calcDiscount=new FixedDiscount(); calcDiscountMap.put(FIXED_DISCOUNT, calcDiscount); } return calcDiscount; } public synchronized CalcDiscount getPercentDiscount(){ CalcDiscount calcDiscount= calcDiscountMap.get(PERCENT_DISCOUNT); if(calcDiscount==null){ calcDiscount=new PercentDiscount(); calcDiscountMap.put(PERCENT_DISCOUNT, calcDiscount); } return calcDiscount; } }
public class StrategyTest { /*public static void main(String[] args) { double goodsPrice=2000; CalcDiscount calcDiscount=new PercentDiscount(); double discountPrice=calcDiscount.discount(goodsPrice); System.out.println("商品原价为:"+goodsPrice); System.out.println("商品折扣价为:"+discountPrice); }*/ public static void main(String[] args) { double goodsPrice=2000; CalcDiscountFactory factory= CalcDiscountFactory.getInstance(); double discountPrice=factory.getFixedDiscount().discount(goodsPrice); System.out.println("商品原价为:"+goodsPrice); System.out.println("商品折扣价为:"+discountPrice); } }
package com.jelly.mypattern.templateMethod; /** * 抽象模板 基类 * @author jelly * */ public abstract class AbstractTemplate { /** * 模板方法 定义顶层逻辑。 * 这个操作方法虽然是具体方法 * 但其中operation2 operation3 operation4 都是 * 抽象的,需要推迟到子类中完成。 */ public void operation(){ operation1(); int a=10;int b=20; if(a<b){ operation2(); } operation3(); doHookMethod(); } public void operation1(){ System.out.println("aaaaa"); } public abstract void operation2(); public abstract void operation3(); public abstract void operation4(); /** * 钩子方法 一般以do开头,在java中是一种标准的做法。 * 在模板方法模式中,钩子方法一般是具体的,且提供空实现。这样可选择性地让子类去重写。 * 在子类中,你可以选择重写,或者保持默认(使用父类中的钩子方法)均可。 */ protected void doHookMethod(){ } }
package com.jelly.mypattern.templateMethod; /** * TemplateC 继承AbstractTemplate * 并实现了父类中所有抽象方法,所以TemplateC 直接就是具体类, * 可以被实例化。 * @author jelly * */ public class TemplateC extends AbstractTemplate { @Override public void operation2() { System.out.println("2222"); } @Override public void operation3() { System.out.println("33333"); } @Override public void operation4() { System.out.println("44444"); } }
package com.jelly.mypattern.templateMethod; /** * 抽象模板方法的实现类, * 由于只实现了operation2 operation3 方法,operation4 还不知道如何实现 * 故此类也是抽象类,其operation4 方法等待自己的子类去实现。 * @author jelly * */ public abstract class TemplateA extends AbstractTemplate{ @Override public void operation2() { System.out.println("执行 operation2..."); } @Override public void operation3() { System.out.println("执行 operation3..."); } public abstract void operation4() ; @Override protected void doHookMethod() { System.out.println("do someThing... "); } }
package com.jelly.mypattern.templateMethod; /** * TemplateB 继承TemplateA 实现了父类的operation4 抽象方法 * 并选择性地重写了父类中doHookMethod 抽象方法。 * 这样TemplateB才成为一个具体的类 * @author jelly * */ public class TemplateB extends TemplateA { @Override public void operation4() { System.out.println("xxxxxx"); } @Override protected void doHookMethod() { super.doHookMethod(); System.out.println("do something2..."); } }
package com.jelly.mypattern.templateMethod; public class TemplateMethodTest { public static void main(String[] args) { AbstractTemplate temMethod=new TemplateC(); temMethod.operation(); System.out.println("------------"); AbstractTemplate temMethod2=new TemplateB(); temMethod2.operation(); } }
package com.jelly.mypattern.observer; import java.util.ArrayList; /** * 抽象主题角色 * 定义管理观察者聚集的方法 * * @author jelly * */ public abstract class Subject { /** * 维护 观察者聚集 集合 */ private ArrayList<Observer> observerList=new ArrayList<Observer>(); /** * 添加 注册观察者 * @param observer */ public void attach(Observer observer) { if(observer==null){ throw new NullPointerException(); } if(!observerList.contains(observer)){ observerList.add(observer); } } /** * 删除 取消注册观察者 * @param observer */ public void detach(Observer observer) { observerList.remove(observer); } /** * 主题状态发生变更,通知所有已注册的观察者 */ public void notifyObservers() { for (Observer ob :observerList){ ob.update(); } } /** * 查询 返回主题中已注册的观察者, * @return */ @SuppressWarnings("unchecked") public ArrayList<Observer> observers(){ return (ArrayList<Observer>) observerList.clone(); } }
package com.jelly.mypattern.observer; /** * 具体主题角色 * @author jelly * */ public class ConcreteSubject extends Subject{ private String state; public ConcreteSubject() { } public ConcreteSubject(String state) { this.state=state; } public void change(String newState){ state=newState; this.notifyObservers(); } }
package com.jelly.mypattern.observer; /** * 观察者角色 * @author jelly * */ public interface Observer { /** * 接收到主题的变更通知,更新自身 */ public void update(); }
package com.jelly.mypattern.observer; /** * 具体观察者角色 * @author jelly * */ public class ConcreteObserver implements Observer{ @Override public void update() { System.out.println("观察者观察到主题状态发生了变更,开始更新自身..."); } }
package com.jelly.mypattern.observer; /** * 测试 代码 * @author jelly * */ public class ObserverTest { public static void main(String[] args) { ConcreteSubject subject=new ConcreteSubject(); Observer ob1= new ConcreteObserver(); Observer ob2= new ConcreteObserver(); subject.attach(ob1); subject.attach(ob2); subject.change("b"); } }
public interface Observer { void update(Observable o, Object arg); }
public class Observalbe{ private boolean changed=false; private Vector obs; public Observable(){ obs=new Vector(); } public synchronized void addObserver( Observer o){ if (o==null){ throw new NullPointerException(); } if(!obs.contains(o)){ obs.addElement(o); } } public synchronized void deleteObserver(Observer o) { obs.removeElement(o); } public void notifyObservers() { notifyObservers(null); } public void notifyObservers(Object arg) { Object[] arrLocal; synchronized (this) { if (!changed) return; arrLocal = obs.toArray(); clearChanged(); } for (int i = arrLocal.length-1; i>=0; i--) ((Observer)arrLocal[i]).update(this, arg); } public synchronized void deleteObservers() { obs.removeAllElements(); } protected synchronized void setChanged() { changed = true; } protected synchronized void clearChanged() { changed = false; } public synchronized boolean hasChanged() { return changed; } public synchronized int countObservers() { return obs.size(); } }
package com.jelly.mypattern.chainOfResponsibility; /** * 请求对象 封装客户端请求 * @author jelly * */ public class Request { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } public Request() { super(); } public Request(String name) { super(); this.name = name; } }
package com.jelly.mypattern.chainOfResponsibility; /** * 处理器, 处理链中的处理者 * @author jelly * */ public class Handler { //下一个处理者 private Handler nextHandler; private String handlerName; public Handler() { } public Handler(String hName) { this.handlerName=hName; } public Handler getNextHandler() { return nextHandler; } public void setNextHandler(Handler nextHandler) { this.nextHandler = nextHandler; } public void handleRequest(Request request){ String name=request.getName(); System.out.println(handlerName+"处理请求:"+name); if(nextHandler!=null){ System.out.println(handlerName+"将请求 "+name+" 传给下家..."); nextHandler.handleRequest(request); } } }
package com.jelly.mypattern.chainOfResponsibility; public class HandlerTest { public static void main(String[] args) { Request request=new Request("查询账户信息"); Handler handler1=new Handler("handler1"); Handler handler2=new Handler("handler2"); Handler handler3=new Handler("handler3"); Handler handler4=new Handler("handler4"); handler1.setNextHandler(handler2); handler2.setNextHandler(handler3); handler3.setNextHandler(handler4); handler1.handleRequest(request);//处理请求 } }
JAVA Web开发中,开发 javax.servlet.Filter(接口) 过滤器:获取访问者ip
package com.jelly.mypattern.chainOfResponsibility; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class MyFilter implements Filter { @Override public void destroy() { } /** * 拦截对servlet的请求 * 在执行servlet方法前, 打印访问者ip 和访问的页面。 * */ @Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletRequest request=(HttpServletRequest) req; HttpServletResponse response=(HttpServletResponse)res; String ip= request.getRemoteAddr(); String contextPath= request.getContextPath(); String uri= request.getRequestURI(); String requestPage=uri.replaceFirst(contextPath, "");//请求的页面 System.out.println(ip+" 请求页面:"+requestPage); chain.doFilter(request, response);//将请求向后传递,进入链中下一个对象 } @Override public void init(FilterConfig arg0) throws ServletException { } }
上一篇:java设计模式(四)
下一篇:java设计模式(六)
Copyright © 叮叮声的奶酪 版权所有
备案号:鄂ICP备17018671号-1