首页 > 技术文章 > 设计模式学习笔记(四)-行为型模式(Behavioral Pattern)

kintanx 2019-09-02 00:31 原文

行为型模式(Behavioral Pattern)

  1. 职责链模式(Chain of Responsibility)
    • 多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系, 将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理他为止
    • 典型应用:servlet filter
  2. 命令模式(Command)
    • 命令模式是一种对象行为型模式,其别名为动作(Action)模式或事务(Transaction)模式
    • 将一个请求封装为一个对象,从而使我们可用不同的请求对客户进行参数化;
    • 对请求排队或者记录请求日志,以及支持可撤销的操作。
    • 命令模式的本质是对命令进行封装,将发出命令的责任和执行命令的责任分割开
    • 五个角色:
      • Command: 抽象命令类
      • ConcreteCommand: 具体命令类:持有一个接受者Receiver的引用,绑定一个特定的操作
      • Invoker: 调用者
      • Receiver: 命令接收者
      • Client:客户类
    //抽象命令
    public interface Command {
        void execute();
    }
    //具体命令:开灯
    public class LightOnCommand implements Command {
        private Light light;
        public LightOnCommand(Light light) {
            this.light = light;
        }
        public void execute() {
            light.lightOn();
        }
    }
    //具体命令:关灯
    public class LightOffCommand implements Command {
        private Light light;
        public LightOffCommand(Light light) {
            this.light = light;
        }
        public void execute() {
            light.lightOff();
        }
    }
    //调用者Invoker
    public class XiaoAi {
        private Command command;
        public void setCommand(Command command) {
            this.command = command;
        }
        public void doCommand() {
            command.execute();
        }
    }
    //命令接收者Receiver
    public class Light {
        public void lightOn() {
            System.out.println("灯打开了!!");
        }
        public void lightOff() {
            System.out.println("灯关上了!!");
        }
    }
    //客户类
    public class Client {
        public static void main(String[] args) {
            XiaoAi xiaoAi = new XiaoAi();
            Light light = new Light();
            System.out.println("帮我把灯开一下!");
            LightOnCommand lightOnCommand = new LightOnCommand(light);
            xiaoAi.setCommand(lightOnCommand);
            xiaoAi.doCommand();
    
            System.out.println("帮我关一下灯!");
            LightOffCommand lightOffCommand = new LightOffCommand(light);
            xiaoAi.setCommand(lightOffCommand);
            xiaoAi.doCommand();
        }
    }
    
  3. 解释器模式(Interpreter)
    • 解释器模式是类的行为模式。
    • 给定一个语言之后,解释器模式可以定义出其文法的一种表示,并同时提供一个解释器。
    • 客户端可以使用这个解释器来解释这个语句中的句子。
    • 典型应用:解析四则混合运算,解析xml文档
  4. 迭代器模式(Iterator)
    • 提供一种方法顺序访问一个聚合对象中的各种元素,而又不暴露该对象的内部表示
    • 典型应用: Java中的Iterator
  5. 中介者模式(Mediator)
    • 中介者模式又称为调停者模式,它是一种对象行为型模式。
    • 用一个中介对象来封装一系列的对象交互,中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
    • 典型应用:多人聊天室,MVC架构(controller是中介者),GUI开发中多界面的引用和控制
    • 四个角色:(同事类方法中传入中介者对象)
      • Mediator: 抽象中介者
      • ConcreteMediator: 具体中介者
      • Colleague: 抽象同事类
      • ConcreteColleague: 具体同事类
  6. 备忘录模式(Memento)
    • 备忘录对象是一个用来存储另外一个对象内部状态的快照(snapshot)的对象。
    • 备忘录模式的用意是在不破坏封装的条件下,将一个对象的状态捕捉住,并外部化,存储起来,从而可以在将来适合的时候把这个对象还原到存储起来的状态。
    • 典型应用:
      • 0、Session和Cookie的使用都是备忘录模式。
      • 1、后悔药。
      • 2、打游戏时的存档。
      • 3、Windows 里的 ctrl + z。
      • 4、IE 中的后退。
      • 5、数据库的事务管理。
  7. 观察者模式(Observer)
    • 四个角色:(观察者持有目标对象,并在初始化时向目标注册自己。目标发生变化时,通知观察者)
      • Subject: 目标
      • ConcreteSubject: 具体目标
      • Observer: 观察者
      • ConcreteObserver: 具体观察者
    • Java自带接口:Observable, Observer
    • vs中介者模式:
      • 中介者(mediator)强调的是同事(colleague)类之间的交互
      • 而观察者(observer)中的目标类(subject)强调是目标改变后对观察者进行统一的通讯
  8. 状态模式(State)
    • 别名为状态对象(Objects for States),状态模式是一种对象行为型模式
    • 允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类。
    • 状态模式的关键是引入了一个抽象类来专门表示对象的状态,这个类我们叫做抽象状态类,而对象的每一种具体状态类都继承了该类,并在不同具体状态类中实现了不同状态的行为,包括各种状态之间的转换
    • 三个角色:
      • Context: 环境类
      • State: 抽象状态类
      • ConcreteState: 具体状态类
    public class Context {
        private State state;
        public void setState(State state) {
            this.state = state;
        }
        public void request(String sampleParameter) {
            state.handle(sampleParameter);
        }
    }
    public interface State {
        public void handle(String sampleParameter);
    }
    public class ConcreteStateA implements State {
        public void handle(String sampleParameter) {
            System.out.println("ConcreteStateA handle :" + sampleParameter);
        }
    }
    public class ConcreteStateB implements State {
        public void handle(String sampleParameter) {
            System.out.println("ConcreteStateB handle :" + sampleParameter);
        }
    }
    public class Client {
        public static void main(String[] args){
            State state = new ConcreteStateB();
            Context context = new Context();
            context.setState(state);
            context.request("test");
        }
    }
    
  9. 策略模式(Strategy)
    • 定义一系列算法,将每一个算法封装起来,并让它们可以相互替换。
    • 策略模式让算法独立于使用它的客户而变化,也称为政策模式(Policy)。
    • 策略模式是一种对象行为型模式。
    • vs状态模式:
      • 策略模式将具体策略类暴露出去,调用者需要具体明白每个策略的不同之处以便正确使用。
      • 而状态模式状态的改变是由其内部条件来改变的,与外界无关
      • 状态对象是环境类的一个成员变量,策略对象是环境类的一个方法参数
    • 三个角色:
      • Context: 环境类
      • Strategy: 抽象策略类
      • ConcreteStrategy: 具体策略类
  10. 模板方法模式(Template Method)
    • 一个抽象类公开定义了执行它的方法的方式/模板,其子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行
    • 典型实例:servlet中service() doGet() doPost() 方法
  11. 访问者模式(Visitor)
    • 五个角色:
      • 抽象访问者:为对象结构中的每一个具体元素类声明一个访问操作。
      • 具体访问者:实现对每一具体元素的访问方法。
      • 抽象元素:声明accept方法,接收访问者的访问操作,通常是抽象类和接口。
      • 具体元素:实现accept方法,调用访问者的对应的访问方法。
      • 对象结构:存放元素对象并提供遍历方法,可以使用组合模式实现
    • 一种将数据操作与数据结构分离的设计模式
    • 类似Java重载,不同的方法入参就是不同的方法实现
    interface Visitor {
        void visit(Games games);
        void visit(Photos photos);
    }
    interface Computer {
        void accept(Visitor visitor);
    }
    
    class ZhangSan implements Visitor {
        public void visit(Games games) {
            games.play();
        }
        public void visit(Photos photos) {
            photos.watch();
        }
    }
    class LiSi implements Visitor {
        public void visit(Games games) {
            games.play();
        }
        public void visit(Photos photos) {
            photos.watch();
        }
    }
    class Games implements Computer {
        public void accept(Visitor visitor) {
            visitor.visit(this);
        }
        public void play() {
            System.out.println("play lol");
        }
    }
    class Photos implements Computer {
        public void accept(Visitor visitor) {
            visitor.visit(this);
        }
        public void watch() {
            System.out.println("watch scenery photo");
        }
    }
    
    class ObjectStructure {
        private List<Computer> computers = new ArrayList<Computer>();
        public void action(Visitor visitor) {
            computers.forEach(c -> {
                c.accept(visitor);
            });
        }
        public void add(Computer computer) {
            computers.add(computer);
        }
    
        public static void main(String[] args) {
            ObjectStructure os = new ObjectStructure();
            os.add(new Games());
            os.add(new Photos());
            // 创建一个访问者
            Visitor visitor = new ZhangSan();
            os.action(visitor);
    
        }
    }
    

推荐阅读