架构设计七之解释器模式、模板模式、观察者模式
来源:互联网 发布:德国统一 知乎 编辑:程序博客网 时间: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也是观察者模式的一种,只不过是一种单向的观察者模式。
- 架构设计七之解释器模式、模板模式、观察者模式
- 设计模式之七 --- 观察者模式(Observer)
- 设计模式之七 --- 观察者模式(Observer)
- 设计模式之七 --- 观察者模式(Observer)
- 设计模式(七)之观察者模式
- 设计模式之七 --- 观察者模式(Observer)
- 设计模式 - 建造者模式、解释器模式、模板模式
- 设计模式笔记--行为型模式之七Observer--观察者
- 设计模式介绍之七:观察者模式(observer)
- 23种设计模式4--行为型模式(策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式)
- 23种设计模式4--行为型模式(策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式)
- 设计模式之观察者模式
- 设计模式之观察者模式
- 设计模式之观察者模式
- 设计模式之观察者模式
- 设计模式之观察者模式
- 设计模式之观察者模式
- 设计模式之观察者模式
- POJ 1069 The Bermuda Triangle 笔记
- Unity GrabPass 实现高斯模糊毛玻璃
- 用bootstrap实现图片的轮播
- Android多线程通讯之AsyncTask使用详解
- 课设
- 架构设计七之解释器模式、模板模式、观察者模式
- NOIP 2008 提高组 复赛 message 传字条
- 如何定位web前后台的BUG
- Spring 注解方式集成 Junit4 进行单元测试
- 总结1
- 带触屏的语音助手是客厅的新宠?亚马逊新一代 Echo 也许能告诉你答案
- java-栈、队列、数组、链表、Hash、树以及集合(二)
- 第2章 配置指南
- R语言dplyr包介绍 introduction to dplyr