架构设计七之解释器模式、模板模式、观察者模式

来源:互联网 发布:德国统一 知乎 编辑:程序博客网 时间:2024/05/18 00:21

前言

        这篇博客继续学习解释器、模板、观察者三种模式。

解释器模式

        解释器是一种用的比较少的行为模式,其提供了一种解释语言的语法,或者表达式的方式。该模式定义了一个表达式的接口。

使用场景

使用场景最为频繁的就是手机号码验证
移动:134、135、136、137、138、139、150、151、157(TD)、158、159、187、188
联通:130、131、132、152、155、156、185、186
电信:133、153、180、189、(1349卫通)
其实上面的号码验证需要使用正则表达式”^((13[0-9])|(15[^4,\D])|(18[0,5-9]))\d{8}$”,但是计算机并不认识正则表达式,这个时候就需要有一个正则表达式的解释器来解释此表达式。

重点:

必须有一个抽象接口以及构建语法树

实现如下:

这里以处理一个四则运算为例:3 * 2 * 4 / 6 % 5,计算机是不知道如何去运算的,所以就需要利用解释器来进行先后顺序的运算。

抽象表达式:Node.Javapublic interface Node  {      public int interpret();  }  非终结表达式:ValueNode.java。主要用解释该表达式的值public class ValueNode implements Node  {      private int value;      public ValueNode(int value)      {          this.value=value;      }      public int interpret()      {          return this.value;      }  }  终结表达式抽象类,由于该终结表达式需要解释多个运算符号,同时用来构建抽象语法树:public abstract class SymbolNode implements Node  {      protected Node left;      protected Node right;      public SymbolNode(Node left,Node right)      {          this.left=left;          this.right=right;      }  }  MulNode.javapublic class MulNode extends SymbolNode  {      public MulNode(Node left,Node right)      {          super(left,right);      }      public int interpret()      {          return left.interpret() * right.interpret();      }  }  ModNode.javapublic class ModNode extends SymbolNode{      public ModNode(Node left,Node right){          super(left,right);      }      public int interpret(){          return super.left.interpret() % super.right.interpret();      }  }  DivNode.javapublic class DivNode extends SymbolNode{      public DivNode(Node left,Node right){          super(left,right);      }      public int interpret(){          return super.left.interpret() / super.right.interpret();      }  }  Calculator.javapublic class Calculator{      private String statement;      private Node node;      public void build(String statement){          Node left=null,right=null;          Stack stack=new Stack();          String[] statementArr=statement.split(" ");          for(int i=0;i<statementArr.length;i++){                  if(statementArr[i].equalsIgnoreCase("*")){                  left=(Node)stack.pop();                  int val=Integer.parseInt(statementArr[++i]);                  right=new ValueNode(val);                   stack.push(new MulNode(left,right));              }              else if(statementArr[i].equalsIgnoreCase("/")){                  left=(Node)stack.pop();                      int val=Integer.parseInt(statementArr[++i]);                      right=new ValueNode(val);                   stack.push(new DivNode(left,right));                              }              else if(statementArr[i].equalsIgnoreCase("%")){                  left=(Node)stack.pop();                      int val=Integer.parseInt(statementArr[++i]);                      right=new ValueNode(val);                   stack.push(new ModNode(left,right));                             }              else{                  stack.push(new ValueNode(Integer.parseInt(statementArr[i])));              }          }          this.node=(Node)stack.pop();      }      public int compute()          return node.interpret();      }  }  客户端:Client.javapublic class Client{      public static void main(String args[]){          String statement = "3 * 2 * 4 / 6 % 5";          Calculator calculator = new Calculator();          calculator.build(statement);          int result = calculator.compute();          System.out.println(statement + " = " + result);          }  }  

优缺点:

优点
1、 可扩展性比较好,灵活。
2、 增加了新的解释表达式的方式。
3、 易于实现文法。
缺点
1、 执行效率比较低,可利用场景比较少。
2、 对于复杂的文法比较难维护。

模板方法模式

定义

        定义一个操作中的算法框架,而将一些步骤延迟到子类中,使得子类不改变算法的结构即可重复定义算法的某些特点步骤.

角色

        AbstractClass抽象类,定义算法结构,还可以提供通用实现
        ConcreteClass具体实现类 选择性的重定义算法中某些特定步骤

实现如下:

public abstract class Game {       abstract void initialize();       abstract void startPlay();       abstract void endPlay();       public final void play()       {              System.out.println("游戏开机");              //初始化游戏              initialize();              //开始游戏              startPlay();              //结束游戏              endPlay();              System.out.println("游戏关机");       }}public class LoLGame extends Game{    @Override    void initialize() {        System.out.println("初始化英雄联盟");    }    @Override    void startPlay() {        System.out.println("攻入敌方战场");    }    @Override    void endPlay() {        System.out.println("每打赢,失败,退出游戏");    }}public class Client {    public static void main(String[] args) {        Game game=new LoLGame();        game.play();    }}

模板方法模式是使用最简单也是使用最频繁的设计模式。

观察者设计模式

定义:

       观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态上发生变化时,会通知所有观察者对象,使它们能够自动更新自己。

角色:

抽象主题(Subject)角色
       抽象主题角色把所有对观察者对象的引用保存在一个聚集(比如ArrayList对象)里,每个主题都可以有任何数量的观察者。抽象主题提供一个接口,可以增加和删除观察者对象,抽象主题角色又叫做抽象被观察者(Observable)角色。

具体主题(ConcreteSubject)角色

       将有关状态存入具体观察者对象;在具体主题的内部状态改变时,给所有登记过的观察者发出通知。具体主题角色又叫做具体被观察者(Concrete Observable)角色。

抽象观察者(Observer)角色
       为所有的具体观察者定义一个接口,在得到主题的通知时更新自己,这个接口叫做更新接口。

具体观察者(ConcreteObserver)角色
       存储与主题的状态自恰的状态。具体观察者角色实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题的状态 像协调。如果需要,具体观察者角色可以保持一个指向具体主题对象的引用。

实现如下:

/** * 抽象被观察者 * @author Administrator * */public class AbstractSubject {    /**     * 保存注册观察者对象     */    private List<Observer> list=new ArrayList<>();    /**     * 添加观察者     * @param observer     */    public void attach(Observer observer)    {        list.add(observer);    }    /**     * 删除观察者     * @param observer     */    public void detach(Observer observer)    {        list.remove(observer);    }    /**     * 更新所有注册的观察者     * @param content     */    public  void notifyObservers(String content)    {        for(Observer observer:list)        {            observer.update(content);        }    }}public interface Observer {    /**     * 更新接口     * @param state     */    public void update(String state);}public class ConcreteObserver  implements Observer{    private String name;    public ConcreteObserver(String name) {        this.name = name;    }    @Override    public void update(String content) {        System.out.println(name+":   "+content);    }}public class Client {        public static void main(String[] args) {            ConcreteSubject subject=new ConcreteSubject();            Observer observer1=new ConcreteObserver("观察者一");            Observer observer2=new ConcreteObserver("观察者二");            Observer observer3=new ConcreteObserver("观察者三");            subject.attach(observer1);            subject.attach(observer2);            subject.attach(observer3);            subject.notifyObservers("被观察者 发生了变化");        }}

观察者模式也是使用比较广泛的设计模式之一,安卓中的setOnClickListener也是观察者模式的一种,只不过是一种单向的观察者模式。

0 0