打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
设计模式:(四)行为型模式
行为型模式.png
一、策略模式
策略模式.png
策略模式通用类图.png
策略模式使用的就是面向对象的继承和多态机制,非常容易理解和掌握,策略模式的三个角色:
Context封装角色
它也叫做上下文角色,起承上启下封装作用,屏蔽高层模块对策略、算法的直接访问,封装可能存在的变化。
Strategy抽象策略角色
策略、算法家族的抽象,通常为接口,定义每个策略或算法必须具有的方法和属性。,类图中的AlgorithmInterface是什么意思,algorithm是“运算法则”的意思,结合起来意思就明白了。
ConcreteStrategy具体策略角色
实现抽象策略中的操作,该类含有具体的算法。
//抽象的策略角色public interface Strategy { //策略模式的运算法则 public void doSomething();}//具体策略也是非常普通的一个实现类,只要实现接口中的方法就可以public class ConcreteStrategy1 implements Strategy { public void doSomething() { System.out.println("具体策略1的运算法则"); }}public class ConcreteStrategy2 implements Strategy { public void doSomething() { System.out.println("具体策略2的运算法则"); }}//封装角色public class Context { //抽象策略 private Strategy strategy = null; //构造函数设置具体策略 public Context(Strategy _strategy){ this.strategy = _strategy; } //封装后的策略方法 public void doAnythinig(){ this.strategy.doSomething(); }}//高层模块public class Client { public static void main(String[] args) { //声明一个具体的策略 Strategy strategy = new ConcreteStrategy1(); //声明上下文对象 Context context = new Context(strategy); //执行封装后的方法 context.doAnythinig(); }}
策略模式的重点就是封装角色,它是借用了代理模式的思路,大家可以想想,它和代理模式有什么差别,差别就是策略模式的封装角色和被封装的策略类不用是同一个接口,如果是同一个接口那就成为了代理模式。
二、模板方法模式
模板方法模式.png
模板方法模式.png
模板方法模式确实非常简单,仅仅使用了Java的继承机制,但它是一个应用非常广泛的模式。其中,AbstractClass叫做抽象模板,它的方法分为两类:
基本方法
基本方法也叫做基本操作,是由子类实现的方法,并且在模板方法被调用。
模板方法
可以有一个或几个,一般是一个具体方法,也就是一个框架,实现对基本方法的调度,完成固定的逻辑。
为了防止恶意的操作,一般模板方法都加上final关键字,不允许被覆写。
在类图中还有一个角色:具体模板。ConcreteClass1和ConcreteClass2属于具体模板,实现父类所定义的一个或多个抽象方法,也就是父类定义的基本方法在子类中得以实现。
//抽象模板类public abstract class AbstractClass { //基本方法 protected abstract void doSomething(); //基本方法 protected abstract void doAnything(); //模板方法 public void templateMethod(){ /* * 调用基本方法,完成相关的逻辑 */ this.doAnything(); this.doSomething(); }}// 具体模板类public class ConcreteClass1 extends AbstractClass { //实现基本方法 protected void doAnything() { //业务逻辑处理 } protected void doSomething() { //业务逻辑处理 }}public class ConcreteClass2 extends AbstractClass { //实现基本方法 protected void doAnything() { //业务逻辑处理 } protected void doSomething() { //业务逻辑处理 }}//场景类public class Client { public static void main(String[] args) { AbstractClass class1 = new ConcreteClass1(); AbstractClass class2 = new ConcreteClass2(); //调用模板方法 class1.templateMethod(); class2.templateMethod(); }}
抽象模板中的基本方法尽量设计为protected类型,符合迪米特法则,不需要暴露的属性或方法尽量不要设置为protected类型。实现类若非必要,尽量不要扩大父类中的访问权限。
三、观察者模式
观察者模式.png
观察者模式通用类图
Subject被观察者
定义被观察者必须实现的职责,它必须能够动态地增加、取消观察者。它一般是抽象类或者是实现类,仅仅完成作为被观察者必须实现的职责:管理观察者并通知观察者。
Observer观察者
观察者接收到消息后,即进行update(更新方法)操作,对接收到的信息进行处理。
ConcreteSubject具体的被观察者
定义被观察者自己的业务逻辑,同时定义对哪些事件进行通知。
ConcreteObserver具体的观察者
每个观察在接收到消息后的处理反应是不同,各个观察者有自己的处理逻辑。
// 被观察者public abstract class Subject { //定义一个观察者数组 private Vector<Observer> obsVector = new Vector<Observer>(); //增加一个观察者 public void addObserver(Observer o){ this.obsVector.add(o); } //删除一个观察者 public void delObserver(Observer o){ this.obsVector.remove(o); } //通知所有观察者 public void notifyObservers(){ for(Observer o:this.obsVector){ o.update(); } }} //具体被观察者public class ConcreteSubject extends Subject { //具体的业务 public void doSomething(){ /* * do something */ super.notifyObservers(); }}//观察者public interface Observer { //更新方法 public void update();}//具体观察者public class ConcreteObserver implements Observer { //实现更新方法 public void update() { System.out.println("接收到信息,并进行处理!"); }}//场景类public class Client { public static void main(String[] args) { //创建一个被观察者 ConcreteSubject subject = new ConcreteSubject(); //定义一个观察者 Observer obs= new ConcreteObserver(); //观察者观察被观察者 subject.addObserver(obs); //观察者开始活动了 subject.doSomething(); }}
被观察者的职责非常简单,就是定义谁能够观察,谁不能观察,程序中使用ArrayList和Vector没有太大的差别,ArrayList是线程异步,不安全;Vector是线程同步,安全——就这点区别。
四、迭代模式
迭代模式.png
迭代器是为容器服务的,那什么是容器呢? 能容纳对象的所有类型都可以称之为容器,例如Collection集合类型、Set类型等,迭代器模式就是为解决遍历这些容器中的元素而诞生的
迭代器模式通用类图.png
Iterator抽象迭代器
抽象迭代器负责定义访问和遍历元素的接口,而且基本上是有固定的3个方法:first()获得第一个元素,next()访问下一个元素,isDone()是否已经访问到底部(Java叫做hasNext()方法)。
ConcreteIterator具体迭代器
具体迭代器角色要实现迭代器接口,完成容器元素的遍历。
Aggregate抽象容器
容器角色负责提供创建具体迭代器角色的接口,必然提供一个类似createIterator()这样的方法,在Java中一般是iterator()方法。
Concrete Aggregate具体容器
具体容器实现容器接口定义的方法,创建出容纳迭代器的对象。
//抽象迭代器public interface Iterator { //遍历到下一个元素 public Object next(); //是否已经遍历到尾部 public boolean hasNext(); //删除当前指向的元素 public boolean remove();}//具体迭代器public class ConcreteIterator implements Iterator { private Vector vector = new Vector(); //定义当前游标 public int cursor = 0; @SuppressWarnings("unchecked") public ConcreteIterator(Vector _vector){ this.vector = _vector; } //判断是否到达尾部 public boolean hasNext() { if(this.cursor == this.vector.size()){ return false; }else{ return true; } } //返回下一个元素 public Object next() { Object result = null; if(this.hasNext()){ result = this.vector.get(this.cursor++); }else{ result = null; } return result; } //删除当前元素 public boolean remove() { this.vector.remove(this.cursor); return true; }}//抽象容器public interface Aggregate { //是容器必然有元素的增加 public void add(Object object); //减少元素 public void remove(Object object); //由迭代器来遍历所有的元素 public Iterator iterator();}//具体容器public class ConcreteAggregate implements Aggregate { //容纳对象的容器 private Vector vector = new Vector(); //增加一个元素 public void add(Object object) { this.vector.add(object); } //返回迭代器对象 public Iterator iterator() { return new ConcreteIterator(this.vector); } //删除一个元素 public void remove(Object object) { this.remove(object); }}//场景类public class Client { public static void main(String[] args) { //声明出容器 Aggregate agg = new ConcreteAggregate(); //产生对象数据放进去 agg.add("abc"); agg.add("aaa"); agg.add("1234"); //遍历一下 Iterator iterator = agg.iterator(); while(iterator.hasNext()){ System.out.println(iterator.next()); } }}
五、责任链模式
责任链模式.png
责任链模式的重点是在“链”上,由一条链去处理相似的请求在链中决定谁来处理这个请求,并返回相应的结果。
责任链模式通用类图.png
//抽象处理者public abstract class Handler { private Handler nextHandler; //每个处理者都必须对请求做出处理 public final Response handleMessage(Request request){ Response response = null; //判断是否是自己的处理级别 if(this.getHandlerLevel().equals(request.getRequestLevel())){ response = this.echo(request); }else{ //不属于自己的处理级别 //判断是否有下一个处理者 if(this.nextHandler != null){ response = this.nextHandler.handleMessage(request); }else{ //没有适当的处理者,业务自行处理 } } return response; } //设置下一个处理者是谁 public void setNext(Handler handler){ this.nextHandler = handler; } //每个处理者都有一个处理级别 protected abstract Level getHandlerLevel(); //每个处理者都必须实现处理任务 protected abstract Response echo(Request request);}//具体处理者public class ConcreteHandler1 extends Handler { //定义自己的处理逻辑 protected Response echo(Request request) { //完成处理逻辑 return null; } //设置自己的处理级别 protected Level getHandlerLevel() { //设置自己的处理级别 return null; }}public class ConcreteHandler2 extends Handler { //定义自己的处理逻辑 protected Response echo(Request request) { //完成处理逻辑 return null; } //设置自己的处理级别 protected Level getHandlerLevel() { //设置自己的处理级别 return null; }}public class ConcreteHandler3 extends Handler { //定义自己的处理逻辑 protected Response echo(Request request) { //完成处理逻辑 return null; } //设置自己的处理级别 protected Level getHandlerLevel() { //设置自己的处理级别 return null; }}//场景类public class Client { public static void main(String[] args) { //声明所有的处理节点 Handler handler1 = new ConcreteHandler1(); Handler handler2 = new ConcreteHandler2(); Handler handler3 = new ConcreteHandler3(); //设置链中的阶段顺序1-->2-->3 handler1.setNext(handler2); handler2.setNext(handler3); //提交请求,返回结果 Response response = handler1.handlerMessage(new Request()); }}
六、命令模式
命令模式.png
命令模式通用类图.png
Receiver接收者角色
该角色就是干活的角色,命令传递到这里是应该被执行的。
Command命令角色
需要执行的所有命令都在这里声明。
Invoker调用者角色
接收到命令,并执行命令
//通用Receiver类public abstract class Receiver { //抽象接收者,定义每个接收者都必须完成的业务 public abstract void doSomething();}//具体的Receiver类public class ConcreteReciver1 extends Receiver{ //每个接收者都必须处理一定的业务逻辑 public void doSomething(){ }}public class ConcreteReciver2 extends Receiver{ //每个接收者都必须处理一定的业务逻辑 public void doSomething(){ }}//抽象的Command类public abstract class Command { //每个命令类都必须有一个执行命令的方法 public abstract void execute();}//具体的Command类public class ConcreteCommand1 extends Command { //对哪个Receiver类进行命令处理 private Receiver receiver; //构造函数传递接收者 public ConcreteCommand1(Receiver receiver){ this.receiver = receiver; } //必须实现一个命令 public void execute() { //业务处理 this.receiver.doSomething(); }}public class ConcreteCommand2 extends Command { //哪个Receiver类进行命令处理 private Receiver receiver; //构造函数传递接收者 public ConcreteCommand2(Receiver receiver){ this.receiver = receiver; } //必须实现一个命令 public void execute() { //业务处理 this.receiver.doSomething(); }}//调用者Invoker类public class Invoker { private Command command; //受气包,接受命令 public void setCommand(Command command){ this.command = command; } //执行命令 public void action(){ this.command.execute(); }}//场景类public class Client { public static void main(String[] args) { //首先声明调用者Invoker Invoker invoker = new Invoker(); //定义接收者 Receiver receiver = new ConcreteReciver1(); //定义一个发送给接收者的命令 Command command = new ConcreteCommand1(receiver); //把命令交给调用者去执行 invoker.setCommand(command); invoker.action(); }}
七、备忘录模式
备忘录模式.png
备忘录模式通用类图.png
Originator发起人角色
记录当前时刻的内部状态,负责定义哪些属于备份范围的状态,负责创建和恢复备忘录数据。
Memento备忘录角色
负责存储Originator发起人对象的内部状态,在需要的时候提供发起人需要的内部状态。
Caretaker备忘录管理员角色
对备忘录进行管理、保存和提供备忘录。
//发起人角色public class Originator { //内部状态 private String state = ""; public String getState() { return state; } public void setState(String state) { this.state = state; } //创建一个备忘录 public Memento createMemento(){ return new Memento(this.state); } //恢复一个备忘录 public void restoreMemento(Memento _memento){ this.setState(_memento.getState()); }}//备忘录角色public class Memento { //发起人的内部状态 private String state = ""; //构造函数传递参数 public Memento(String _state){ this.state = _state; } public String getState() { return state; } public void setState(String state) { this.state = state; }}//备忘录管理员角色public class CareTaker { private List<Memento> mementoList = new ArrayList<Memento>(); public void add(Memento state){ mementoList.add(state); } public Memento get(int index){ return mementoList.get(index); }}//场景类public class Client { public static void main(String[] args) { Originator originator = new Originator(); CareTaker careTaker = new CareTaker(); originator.setState("State #1"); originator.setState("State #2"); careTaker.add(originator.saveStateToMemento()); originator.setState("State #3"); careTaker.add(originator.saveStateToMemento()); originator.setState("State #4"); System.out.println("Current State: " + originator.getState()); originator.restoreMemento(careTaker.get(0)); System.out.println("First saved State: " + originator.getState()); originator.restoreMemento(careTaker.get(1)); System.out.println("Second saved State: " + originator.getState()); }}
八、状态模式
状态模式.png
状态模式通用类图.png
State——抽象状态角色
接口或抽象类,负责对象状态定义,并且封装环境角色以实现状态切换。
ConcreteState——具体状态角色
每一个具体状态必须完成两个职责:本状态的行为管理以及趋向状态处理,通俗地说,就是本状态下要做的事情,以及本状态如何过渡到其他状态。
Context——环境角色
定义客户端需要的接口,并且负责具体状态的切换。
//抽象状态角色public abstract class State { //定义一个环境角色,提供子类访问 protected Context context; //设置环境角色 public void setContext(Context _context){ this.context = _context; } //行为1 public abstract void handle1(); //行为2 public abstract void handle2();}//状态角色public class ConcreteState1 extends State { @Override public void handle1() { //本状态下必须处理的逻辑 } @Override public void handle2() { //设置当前状态为stat2 super.context.setCurrentState(Context.STATE2); //过渡到state2状态,由Context实现 super.context.handle2(); }}public class ConcreteState2 extends State { @Override public void handle1() { //设置当前状态为state1 super.context.setCurrentState(Context.STATE1); //过渡到state1状态,由Context实现 super.context.handle1(); } @Override public void handle2() { //本状态下必须处理的逻辑 }}//具体环境角色public class Context { //定义状态 public final static State STATE1 = new ConcreteState1(); public final static State STATE2 = new ConcreteState2(); //当前状态 private State CurrentState; //获得当前状态 public State getCurrentState() { return CurrentState; } //设置当前状态 public void setCurrentState(State currentState) { this.CurrentState = currentState; //切换状态 this.CurrentState.setContext(this); } //行为委托 public void handle1(){ this.CurrentState.handle1(); } public void handle2(){ this.CurrentState.handle2(); }}
环境角色有两个不成文的约束:
把状态对象声明为静态常量,有几个状态对象就声明几个静态常量。
环境角色具有状态抽象角色定义的所有行为,具体执行使用委托方式。
九、访问者模式
访问者模式.png
访问者模式通用类图.png
Visitor——抽象访问者
抽象类或者接口,声明访问者可以访问哪些元素,具体到程序中就是visit方法的参数定义哪些对象是可以被访问的。
ConcreteVisitor——具体访问者
它影响访问者访问到一个类后该怎么干,要做什么事情。
Element——抽象元素
接口或者抽象类,声明接受哪一类访问者访问,程序上是通过accept方法中的参数来定义的。
ConcreteElement——具体元素
实现accept方法,通常是visitor.visit(this),基本上都形成了一种模式了。
ObjectStruture——结构对象
“元素产生者,一般容纳在多个不同类、不同接口的容器,如List、Set、Map等,在项目中,一般很少抽象出这个角色。
//抽象元素public abstract class Element { //定义业务逻辑 public abstract void doSomething(); //允许谁来访问 public abstract void accept(IVisitor visitor);}//具体元素public class ConcreteElement1 extends Element{ //完善业务逻辑 public void doSomething(){ //业务处理 } //允许那个访问者访问 public void accept(IVisitor visitor){ visitor.visit(this); }}public class ConcreteElement2 extends Element{ //完善业务逻辑 public void doSomething(){ //业务处理 } //允许那个访问者访问 public void accept(IVisitor visitor){ visitor.visit(this); }}//抽象访问者public interface IVisitor { //可以访问哪些对象 public void visit(ConcreteElement1 el1); public void visit(ConcreteElement2 el2);}//具体访问者public class Visitor implements IVisitor { //访问el1元素 public void visit(ConcreteElement1 el1) { el1.doSomething(); } //访问el2元素 public void visit(ConcreteElement2 el2) { el2.doSomething(); }}// 结构对象public class ObjectStruture { //对象生成器,这里通过一个工厂方法模式模拟 public static Element createElement(){ Random rand = new Random(); if(rand.nextInt(100) > 50){ return new ConcreteElement1(); }else{ return new ConcreteElement2(); } }}// 场景类public class Client { public static void main(String[] args) { for(int i=0;i<10;i++){ //获得元素对象 Element el = ObjectStruture.createElement(); //接受访问者访问 el.accept(new Visitor()); } }}
十、中介者模式
中介者模式.png
中介者模式通用类图.png
Mediator 抽象中介者角色
抽象中介者角色定义统一的接口,用于各同事角色之间的通信。
Concrete Mediator 具体中介者角色
具体中介者角色通过协调各同事角色实现协作行为,因此它必须依赖于各个同事角色。
Colleague 同事角色
每一个同事角色都知道中介者角色,而且与其他的同事角色通信的时候,一定要通过中介者角色协作
//通用抽象中介者public abstract class Mediator { //定义同事类 protected ConcreteColleague1 c1; protected ConcreteColleague2 c2; //通过getter/setter方法把同事类注入进来 public ConcreteColleague1 getC1() { return c1; } public void setC1(ConcreteColleague1 c1) { this.c1 = c1; } public ConcreteColleague2 getC2() { return c2; } public void setC2(ConcreteColleague2 c2) { this.c2 = c2; } //中介者模式的业务逻辑 public abstract void doSomething1(); public abstract void doSomething2();}// 通用中介者public class ConcreteMediator extends Mediator { @Override public void doSomething1() { //调用同事类的方法,只要是public方法都可以调用 super.c1.selfMethod1(); super.c2.selfMethod2(); } public void doSomething2() { super.c1.selfMethod1(); super.c2.selfMethod2(); }}// 抽象同事类public abstract class Colleague { protected Mediator mediator; public Colleague(Mediator _mediator){ this.mediator = _mediator; }}// 具体同事类public class ConcreteColleague1 extends Colleague { //通过构造函数传递中介者 public ConcreteColleague1(Mediator _mediator){ super(_mediator); } //自有方法 self-method public void selfMethod1(){ //处理自己的业务逻辑 } //依赖方法 dep-method public void depMethod1(){ //处理自己的业务逻辑 //自己不能处理的业务逻辑,委托给中介者处理 super.mediator.doSomething1(); }}public class ConcreteColleague2 extends Colleague { //通过构造函数传递中介者 public ConcreteColleague2(Mediator _mediator){ super(_mediator); } //自有方法 self-method public void selfMethod2(){ //处理自己的业务逻辑 } //依赖方法 dep-method public void depMethod2“(){ //处理自己的业务逻辑 //自己不能处理的业务逻辑,委托给中介者处理 super.mediator.doSomething2(); }}
十一、解释器模式
解释器模式.png
解释器模式通用类图.png
TerminalExpression——终结符表达式
实现与文法中的元素相关联的解释操作,通常一个解释器模式中只有一个终结符表达式,但有多个实例,对应不同的终结符。具体到我们例子就是VarExpression类,表达式中的每个终结符都在栈中产生了一个VarExpression对象。
NonterminalExpression——非终结符表达式
文法中的每条规则对应于一个非终结表达式,具体到我们的例子就是加减法规则分别对应到AddExpression和SubExpression两个类。非终结符表达式根据逻辑的复杂程度而增加,原则上每个文法规则都对应一个非终结符表达式。
Context——环境角色
//抽象表达式public abstract class Expression { //每个表达式必须有一个解析任务 public abstract Object interpreter(Context ctx);}//终结符表达式public class TerminalExpression extends Expression { //通常终结符表达式只有一个,但是有多个对象 public Object interpreter(Context ctx) { return null; }}// 非终结符表达式public class NonterminalExpression extends Expression { //每个非终结符表达式都会对其他表达式产生依赖 public NonterminalExpression(Expression... expression){ } public Object interpreter(Context ctx) { //进行文法处理 return null; }}//客户类public class Client { public static void main(String[] args) { Context ctx = new Context(); //通常定一个语法容器,容纳一个具体的表达式,通常为ListArray、LinkedList、Stack等类型 Stack&Expression> stack = null; for(;;){ //进行语法判断,并产生递归调用 } //产生一个完整的语法树,由各个具体的语法分析进行解析 Expression exp = stack.pop(); //具体元素进入场景 exp.interpreter(ctx); }}
上一篇:设计模式:(三)结构性模式
下一篇:设计模式:(五)相似模式比较
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
状态模式(state)解析例子
设计模式:策略模式,Java集合定制排序的核心思想
适配器模式(2)
设计模式之策略模式
2W 字详解设计模式
android的四种设计模式
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服