深入浅出设计模式之策略模式、观察者模式
来源:互联网 发布:阿里云备案文件 编辑:程序博客网 时间:2024/06/06 14:11
第一章 入门
1.这里讲了一个简单的例子,鸭子的例子。鸭子都会叫,都会走,都会游泳(不变的部分)。但是有的鸭子会飞,有的鸭子的外观不一样等等(变得部分),如何设计呢?采取分离的策略,将不变的部分和可变的部分分离,因此引出我们第一个设计原则:找出应用中可能需要的变化之处,把它们独立出来,不要和哪些不需要变化的代码混在一起。
2.如何设计呢?对于上面的鸭子的例子,我们知道我们要增强我们的代码弹性, 就是说要更容易修改,引出第二个设计原则:针对接口编程,而不是针对实现编程。具体来讲,对于我们鸭子的每个可变行为,比如飞行行为,单独拿出来作为一个接口。如下图
3.接下来,你就应该要整合鸭子的行为了。前面的过程,我们将鸭子的可变行为委托(delegate)给了FlayBehavior和QuackBehavior。具体的做法是让鸭子类持有FlyBehavior和QuackBehavior的两个实例变量,然后写两个方法,比如飞行方法,如下所示
public void performFly(){ flyBehavior.fly();}
这样鸭子就有了自己的飞行行为,我们只需要在实例化这个鸭子的时候,比如在构造函数中初始化对应的飞行和名叫的具体的类即可。
4.第三个设计原则:多用组合,少用继承。
上述就讲述了一个设计模式策略模式,而且是一个多策略模式,有飞行的策略,有名叫的策略,不同的策略下面又有不同的实现。
观察者模式
观察者模式适用于经常变化且需要被监测的对象。课本上举的例子是气象站的一个类WebData,这个Webdata能获得最新的气象数据并及时的更新到三个布告板。布告板也不能仅仅只有3个,知识说现在有三个, 以后可能会有更多的布告板展示其他的数据(可拓展性)。
怎么办呢?
基本的过程呢,我们用一个简单的例子来解释:假设观察者是订阅报纸的人,简称狗,鸭子,猫和老鼠,他们都订阅了某个报社的报纸(假设鸭子还没订阅)。而被订阅的报社呢,是被观察者,就叫他们报社。整体的工作流程如下:
某天,鸭子向报社说,我想订阅一份报纸(鸭子相当观察者了),这个过程称作注册;
报社街道订阅通知,将鸭子添加到自己的订阅列表;
好,现在鸭子也加入到了观察者里面,开始等待报社送报纸(发送通知);
报社印出了新的报纸,并告诉观察者们报纸已经好了;
老鼠不想当观察者了,想订阅另一个报社的报纸,于是老鼠向报社发送请求,然后老鼠离开了,删除了一个观察者。
报社又产生了新的报纸,只不过老鼠已经接收不到通知了。
那么我们基本就了解了观察者模式的工作流程了,那么观察者模式应该具体怎么实现呢?我们来看类图
一定要注意这几个方法,对于被观察者(主题,Subject),registerObserver,RemoveObserver,NotifyObserver,对于观察者,只需要一个update。这是一个松耦合的设计,观察者只需要等待主题的通知,而主题只知道观察者只有一个update 方法。剩下的就比较简单了。你可以写一个Client类,这个类通过持有观察者和被观察者两个接口,不断的向被观察者内部注册观察者或者移除观察者。或者当被观察者需要通知观察者时,由Client调用notifyObservers()方法。
java内部实现了观察者模式,Observervable抽象类负责被观察者,Observer接口负责观察者,如下图所示
java内置的观察者模式必须要经过两步。即当被观察者更新内容后,必须先setChange(),然后才能调用notifyObserver()看下面的代码
观察者
import java.util.Observable;import java.util.Observer;public class BlackBoard implements Observer{@Overridepublic void update(Observable o, Object arg) {// TODO Auto-generated method stubif(o instanceof Teacher){Teacher teacher = (Teacher)o;System.out.println(teacher.getContent());}}}被观察者
import java.util.Observable;public class Teacher extends Observable{private String content;public Teacher(){}public void measurementsChanged(){setChanged();notifyObservers();}public void setContent(String content){this.content=content;measurementsChanged();}public String getContent() {// TODO Auto-generated method stubreturn content;}}客户端:
public class Client {public static void main(String[] args){Teacher t = new Teacher();t.addObserver(new BlackBoard());t.setContent("Course Content");//t.measurementsChanged();t.setContent("new Content");}}
总结一下,观察者模式需要以下步骤:
1、创建观察者和被观察者,这里观察者需要有update()方法,被观察者需要有addObserver(),removeObserver(),notifyOverver()方法。甚至还有自己的状态setChange()表示当前数据有没有更新。
2、在被观察者内部注册观察者,这个可以在客户端或者观察者内部甚至被观察者内部执行,都无所谓的。
3、被观察者更新内容,设置setChange(),通知所有客户端notifyObservers()。
0 0
- 深入浅出设计模式之策略模式、观察者模式
- 深入浅出设计模式之观察者设计模式
- 设计模式 之 策略模式和观察者模式
- 设计模式之策略模式、观察者模式浅析
- 设计模式---策略模式And 观察者模式
- 设计模式---策略模式和观察者模式
- 设计模式[策略模式和观察者模式]
- 深入浅出设计模式笔记之十六:观察者模式
- 深入浅出设计模式笔记之十七:策略模式
- 设计模式之观察者模式
- 设计模式之观察者模式
- 设计模式之观察者模式
- 设计模式之观察者模式
- 设计模式之观察者模式
- 设计模式之观察者模式
- 设计模式之观察者模式
- 设计模式之观察者模式
- 设计模式之观察者模式
- js的基本数据类型有哪些? ECMAScript中有5中简单数据类型(也称为基本数据类型): Undefined、Null、Boolean、Number和String。还有1中复杂的数据类型————
- 朴灵:基于MongoDB与NodeJS构建物联网系统
- Ioc和Di
- 2017.3.22 我的第一篇技术博客
- 推荐系统冷启动问题
- 深入浅出设计模式之策略模式、观察者模式
- ns2相关学习——TCL脚本编写(3)
- 去哪儿网机票搜索系统的高并发架构设计(2017-03-20 蒋志伟)
- CSS实现背景透明,文字不透明,兼容所有浏览器
- 用gzip进行了压缩后的bin文件,没压缩前bin文件的大小,在压缩了后的bin中的位置
- 完全复制一个UIView
- JDK、JRE、JVM的关系
- Spring和SpringMVC的区别和比较
- 如何使用C++创建COM组件(ATL项目)