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

前言

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

解释器模式

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

使用场景

使用场景最为频繁的就是手机号码验证
移动: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.Java
public 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.java
public class MulNode extends SymbolNode  
{  
    public MulNode(Node left,Node right)  
    {  
        super(left,right);  
    }  

    public int interpret()  
    {  
        return left.interpret() * right.interpret();  
    }  
}  

ModNode.java
public class ModNode extends SymbolNode{  
    public ModNode(Node left,Node right){  
        super(left,right);  
    }  

    public int interpret(){  
        return super.left.interpret() % super.right.interpret();  
    }  
}  

DivNode.java
public class DivNode extends SymbolNode{  
    public DivNode(Node left,Node right){  
        super(left,right);  
    }  

    public int interpret(){  
        return super.left.interpret() / super.right.interpret();  
    }  
}  

Calculator.java
public 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.java
public 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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值