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

观察者模式在实现时,有两种方式,一种是推(push),一种是拉(pull)。

一直在用,却不知道什么是观察者模式。看到一篇文章,关于观察者模式的,说白了就是一个对象(被观察者)持有一堆对象(观察者)的引用,这些引用都放在一个列表中,当被观察者的状态改变时,就调用引用(观察者)的 update() 方法,让所有的观察者知道被观察者的状态改变了,然后自己也跟着变化。

其中关键点:

1. 一对多的关系,一个被观察者(object),一个或者多个观察者(observer)

2. 被观察者持有每个观察者的引用

3. 被观察者有注册和取消注册的方法

4. 在被观察者的类中,用列表存放观察者的引用

5. 当被观察者的状态改变时,调用相关的 notify() 方法,在 notify() 方法中调用每个观察者的 update() 方法来让观察者知道该事件。

自己撸了一段代码:(使用的是交通灯的案例,

1. 交通灯是被观察者,汽车是观察者

2. 当白天的时候需要看红绿灯,交通灯状态为绿色时,汽车行驶,交通灯状态为红色时,汽车等待

3. 当凌晨12点到4点的时候,不需要看红绿灯,可以自由通过,这个时候交通灯的红绿灯就对汽车不起作用了。)

被观察者(TrafficLight)

 public class TrafficLight {
private static final String TAG = "TrafficLight";
private TrafficLightStatus defaultStatus = TrafficLightStatus.GREEN;
private List<ICar> observerList = new ArrayList<>(); public TrafficLightStatus getLightStatus() {
return defaultStatus;
} public void setTrafficLightStatus(TrafficLightStatus status) {
defaultStatus = status;
} public void notifyStatusChange() {
if (observerList.size() > 0) {
for (int i = 0; i < observerList.size(); i++) {
if (defaultStatus == TrafficLightStatus.GREEN) {
observerList.get(i).move();
} else {
observerList.get(i).stop();
}
}
}
} public void registerTrafficLight(ICar car) {
if (!observerList.contains(car)) {
observerList.add(car);
}
} public void unRegisterTrafficLight(ICar car) {
if (observerList.contains(car))
observerList.remove(car);
}
}

观察者(ICar)

 public interface ICar {
void move();
void stop();
}

观察者的实现类(ToytaCar...)

 public class ToytaCar implements ICar {
private static final String TAG = "ToytaCar"; @Override
public void move() {
Log.e(TAG, "ToytaCar,绿灯,行驶");
} @Override
public void stop() {
Log.e(TAG, "ToytaCar,红灯,等待");
}
}

MainActivity,4个 Button,分别是注册,取消注册,状态改变(绿灯,红灯)

 public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private List<ICar> carList = new ArrayList<>();
Button btnRedLight, btnGreenLight, btnFreeLight, btnLimitLight; TrafficLight trafficLight;
ICar toytaCar, nissanCar, mazdaCar, hondaCar, fordCar, bydCar, bmwCar, audiCar; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnRedLight = (Button) findViewById(R.id.btn_red_light);
btnGreenLight = (Button) findViewById(R.id.btn_green_light);
btnFreeLight = (Button) findViewById(R.id.btn_free_light);
btnLimitLight = (Button) findViewById(R.id.btn_limit_light);
btnRedLight.setOnClickListener(this);
btnGreenLight.setOnClickListener(this);
btnFreeLight.setOnClickListener(this);
btnLimitLight.setOnClickListener(this);
trafficLight = new TrafficLight();
toytaCar = new ToytaCar();
nissanCar = new NissanCar();
mazdaCar = new MazdaCar();
hondaCar = new HondaCar();
fordCar = new FordCar();
bydCar = new BYDCar();
bmwCar = new BWMCar();
audiCar = new AudiCar();
carList.add(toytaCar);
carList.add(nissanCar);
carList.add(mazdaCar);
carList.add(hondaCar);
carList.add(bydCar);
carList.add(bmwCar);
carList.add(audiCar);
carList.add(fordCar); } @Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_green_light:
trafficLight.setTrafficLightStatus(TrafficLightStatus.GREEN);
trafficLight.notifyStatusChange();
break;
case R.id.btn_red_light:
trafficLight.setTrafficLightStatus(TrafficLightStatus.RED);
trafficLight.notifyStatusChange();
break;
case R.id.btn_free_light:
for (int i = 0; i < carList.size(); i++) {
trafficLight.unRegisterTrafficLight(carList.get(i));
}
break;
case R.id.btn_limit_light:
for (int i = 0; i < carList.size(); i++) {
trafficLight.registerTrafficLight(carList.get(i));
}
break;
default:
break;
}
}
}

log 输出:

1. 当点击按钮-看红绿灯(注册),点击红绿灯按钮就可以调用 ICar 的 move() 或者 stop() 方法,打印出来日志

 01-09 22:32:54.454 6900-6900/cc.lijingbo.pattern_observer E/ToytaCar: ToytaCar,红灯,等待
01-09 22:32:54.454 6900-6900/cc.lijingbo.pattern_observer E/NissanCar: NissanCar,红灯,等待
01-09 22:32:54.454 6900-6900/cc.lijingbo.pattern_observer E/MazdaCar: MazdaCar,红灯,等待
01-09 22:32:54.454 6900-6900/cc.lijingbo.pattern_observer E/HondaCar: HondaCar,红灯,等待
01-09 22:32:54.454 6900-6900/cc.lijingbo.pattern_observer E/BYDCar: BYDCar,红灯,等待
01-09 22:32:54.454 6900-6900/cc.lijingbo.pattern_observer E/BWMCar: BWMCar,红灯,等待
01-09 22:32:54.454 6900-6900/cc.lijingbo.pattern_observer E/AudiCar: AudiCar,红灯,等待
01-09 22:32:54.454 6900-6900/cc.lijingbo.pattern_observer E/FordCar: FordCar,红灯,等待
01-09 22:32:56.844 6900-6900/cc.lijingbo.pattern_observer E/ToytaCar: ToytaCar,绿灯,行驶
01-09 22:32:56.854 6900-6900/cc.lijingbo.pattern_observer E/NissanCar: NissanCar,绿灯,行驶
01-09 22:32:56.854 6900-6900/cc.lijingbo.pattern_observer E/MazdaCar: MazdaCar,绿灯,行驶
01-09 22:32:56.854 6900-6900/cc.lijingbo.pattern_observer E/HondaCar: HondaCar,绿灯,行驶
01-09 22:32:56.854 6900-6900/cc.lijingbo.pattern_observer E/BYDCar: BYDCar,绿灯,行驶
01-09 22:32:56.854 6900-6900/cc.lijingbo.pattern_observer E/BWMCar: BWMCar,绿灯,行驶
01-09 22:32:56.854 6900-6900/cc.lijingbo.pattern_observer E/AudiCar: AudiCar,绿灯,行驶
01-09 22:32:56.854 6900-6900/cc.lijingbo.pattern_observer E/FordCar: FordCar,绿灯,行驶

2. 当点击按钮-自由通过(取消注册),这个时候点击红绿灯按钮不起作用,不打印日志

 

参考:

《对象间的联动——观察者模式》:http://blog.csdn.net/lovelion/article/details/7720232

《面试被问设计模式?不要怕看这里:观察者模式》:http://mp.weixin.qq.com/s/pH7ifcOPzVxdrAIk4W8HiQ

《设计模式之观察者模式》:http://www.jianshu.com/p/d55ee6e83d66#

设计模式-观察者模式(Observer Pattern)的更多相关文章

  1. 设计模式 - 观察者模式(Observer Pattern) 详细说明

    观察者模式(Observer Pattern) 详细说明 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26583157 版权全部 ...

  2. 设计模式 - 观察者模式(Observer Pattern) 详细解释

    观察者模式(Observer Pattern) 详细解释 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26583157 版权全部 ...

  3. 设计模式 - 观察者模式(Observer Pattern) Java内置 用法

    观察者模式(Observer Pattern) Java内置 用法 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26601659 ...

  4. C#设计模式——观察者模式(Observer Pattern)1

    一.概述在软件设计工作中会存在对象之间的依赖关系,当某一对象发生变化时,所有依赖它的对象都需要得到通知.如果设计的不好,很容易造成对象之间的耦合度太高,难以应对变化.使用观察者模式可以降低对象之间的依 ...

  5. C#设计模式——观察者模式(Observer Pattern)

    一.概述在软件设计工作中会存在对象之间的依赖关系,当某一对象发生变化时,所有依赖它的对象都需要得到通知.如果设计的不好,很容易造成对象之间的耦合度太高,难以应对变化.使用观察者模式可以降低对象之间的依 ...

  6. 23种设计模式--观察者模式-Observer Pattern

    一.观察者模式的介绍      观察者模式从字面的意思上理解,肯定有两个对象一个是观察者,另外一个是被观察者,观察者模式就是当被观察者发生改变得时候发送通知给观察者,当然这个观察者可以是多个对象,在项 ...

  7. 乐在其中设计模式(C#) - 观察者模式(Observer Pattern)

    原文:乐在其中设计模式(C#) - 观察者模式(Observer Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 观察者模式(Observer Pattern) 作者:weba ...

  8. 二十四种设计模式:观察者模式(Observer Pattern)

    观察者模式(Observer Pattern) 介绍定义对象间的一种一对多的依赖关系,以便当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动刷新. 示例有一个Message实体类,某些对象 ...

  9. java设计模式--观察者模式(Observer)

    java设计模式--观察者模式(Observer) java设计模式--观察者模式(Observer) 观察者模式的定义: 定义对象间的一种一对多的依赖关系.当一个对象的状态发生改变时,所有依赖于它的 ...

随机推荐

  1. cmake常用编译选项

    1.openmp加载,cmake3.9之后内置了openmp find_package(OpenMP) if (OPENMP_FOUND OR OpenMP_CXX_FOUND) set (CMAKE ...

  2. Linux下设置oracle环境变量

    Linux设置Oracle环境变量 方法一:直接运行export命令定义变量,该变量只在当前的shell(BASH)或其子shell(BASH)下是有效的,shell关闭了,变量也就失效了,再打开新s ...

  3. V-rep学习笔记:机器人模型创建4—定义模型

    完成之前的操作后终于来到最后一步——定义模型,即将之前创建的几何体.关节等元素按层级关系组织成为一个整体. 将最后一个连杆robot_link_dyn6拖放到相应的关节(robot_joint6)下, ...

  4. JAVA内存模型及垃圾回收自我总结

    本文为原创,根据<深入理解java虚拟机>和自己的一些理解进行整理,单纯和看其他人的博客感觉不如自己一点点的画和记录来的印象深刻. JAVA内存模型: 上图中:局部变量表所需的内存在编译期 ...

  5. CentOS下递归遍历文件夹下所有文件,查找指定字符

    命令如下: find . | xargs grep -ri "XXX"

  6. Spring Cloud开发实践 - 03 - 接口实现和下游调用

    接口实现 Scot Commons Impl 接口实现模块 scot-commons-impl, 一方面实现了 scot-commons-api 的接口, 一方面将自己暴露为 REST 服务. 有4个 ...

  7. android.database.sqlite.SQLiteException: near "FROM"

      07-20 00:19:30.496: E/JavaBinder(6807): *** Uncaught remote exception!  (Exceptions are not yet su ...

  8. 前台导出Word文档思路步骤总结(freemarker)

    1. 需求是导出word带表格,表格列数不变,行数由数据库的值决定: 2. 导出最开始想的是直接前端导出,使用了jquery-wordexport插件,导出后,表格边框全没了,无法使用: 3. 采用了 ...

  9. ios中自定义图层

    图层和VIEW的区别 1:view不具备显示功能,是因view内部有一个图层,才能显示出来 2:图层不具备事件功能,VIEW继承UIRespone具有处理事件功能 3:自定义的图层有一个影式动画,VI ...

  10. (原)ubuntu挂载及开机自动挂载网络端的文件夹的方法

    转载请注明出处: http://www.cnblogs.com/darkknightzh/p/7160792.html 参考网址: http://blog.csdn.net/tlight/articl ...