观察者模式(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. Struts 2相关配置与基本操作演示(案例Demo)

    基本介绍 Struts 2        Struts 2是Struts的下一代产品,是在 struts 1和WebWork的技术基础上进行了合并的全新的Struts 2框架.其全新的Struts 2 ...

  2. 深入理解JVM(三)——垃圾收集策略具体解释

    Java虚拟机的内存模型分为五个部分.各自是:程序计数器.Java虚拟机栈.本地方法栈.堆.方法区. 这五个区域既然是存储空间,那么为了避免Java虚拟机在执行期间内存存满的情况,就必须得有一个垃圾收 ...

  3. X240 Ubuntu18.04安装流水帐

    U盘安装 使用Startup Disk Creator和下载好的iso文件创建启动U盘 (在win7下官网建议的刻录软件是Rufus, https://rufus.akeo.ie/) Nautilus ...

  4. gnu screen的用法

    在使用ssh或者telnet登录远程主机后执行一些耗时的命令, 如果此时ssh或者telnet中断, 那么远程主机上正在执行的程序或者说命令也会被迫终止. screen能够很好地解决这个问题, scr ...

  5. win8下硬盘安装Ubuntu12.04双系统成功记录

    一开始是在windows下VirtualBox虚拟机中搞了一个Ubuntu玩,时间一长,感觉卡的厉害,浪费时间,那就装个双系统! 在win8下磁盘管理中的最后一个盘中压缩出20G左右的空闲硬盘分区: ...

  6. 【WEB2.0】 网页调用QQ聊天(PC+M站)

    很多时候,我们在网站中需要加入联系QQ的功能,我下面就来说下在web页面中调用QQ聊天是如何实现的,直接上代码: <!DOCTYPE HTML> <html> <head ...

  7. Dubbo创建提供者&消费者工程

    1. 前言 Dubbo采用全Spring配置方式,透明化接入应用,对应用没有任何API侵入,只需用Spring加载Dubbo的配置即可,Dubbo基于Spring的Schema扩展进行加载.如果不想使 ...

  8. Linux-使用ctags、vim查看数据类型所在头文件

    安装 ctags yum -y install ctags 生成 tags 文件 cd /usr/include ctags -R . 在 vim 中配置 tags #修改 vim 配置文件.或者使用 ...

  9. Swift3 JSON字符串和字典互转(JSON字符串转字典和字典转JSON字符串)

    直接上代码吧 1.JSONString转换为字典 /// JSONString转换为字典 /// /// - Parameter jsonString: <#jsonString descrip ...

  10. Tensorflow高级封装

    Tensorflow比较灵活,但是它提供的操作比较低级,于是许多封装库应运而生. slim 导入方式 import tensorflow as tf import tensorflow.contrib ...