美文网首页Android技术知识Java设计模式
设计模式:(四)行为型模式

设计模式:(四)行为型模式

作者: 小村医 | 来源:发表于2018-11-23 00:27 被阅读7次
行为型模式.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);
     }
}

相关文章

网友评论

    本文标题:设计模式:(四)行为型模式

    本文链接:https://www.haomeiwen.com/subject/xzwdxqtx.html