观察者模式(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. C/C++与Java的区别

    转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/5827273.html     C/C++:             C/C++代码——编译(不同的系统编译出不 ...

  2. AVERAGE和averageif函数

    1.AVERAGE(Number1,Number2……) 其中: Number1,number2,...是要计算平均值的 1-30 个参数. 注意事项: average函数的参数可以是一个,也可以是多 ...

  3. MySQL与OLAP:分析型SQL查询最佳实践探索

    搞点多维分析,糙快猛的解决方式就是使用ROLAP(关系型OLAP)了.数据经维度建模后存储在MySQL,ROLAP引擎(比方开源的Mondrian)负责将OLAP请求转化为SQL语句提交给数据库.OL ...

  4. chrome配置文件校验初始化隐含參数的逆向

     这篇文章接上一篇文章进一步升华:花了4个小时获得该信息的计算方式 比方在 chrome文件夹下的\Chrome\User Data\Default文件夹下的Secure Preferences,须要 ...

  5. [JavaScript模块演化简史]摘要

    来源于:https://zhuanlan.zhihu.com/p/26231889 # JavaScript 模块化 早期的JavaScript并没有模块化解决方案.随着单页应用与富客户端的流行,出现 ...

  6. git clone时RPC failed; curl 18 transfer closed with outstanding read data remaining

    git clone时报RPC failed; curl 18 transfer closed with outstanding read data remaining 错误 原因1:缓存区溢出 解决方 ...

  7. ubuntu_thunder

    Thunder 出自Ubuntu中文 File:Http://forum.ubuntu.org.cn/download/file.php?id=123020&mode=view/wine-th ...

  8. JSP、Servlet中的相对路径和绝对路径 页面跳转问题

    转自:http://blog.csdn.net/wym19830218/article/details/5503533/ 1.JSP.Servlet中的相对路径和绝对路径 前提:假设你的Http地址为 ...

  9. php数组使用json_encode函数中文被编码成null的原因和解决办法

    大写的囧,提客户处理问题,前端的APP一直在叽叽咂咂,说收到的值是null,弄了半天原来是这个问题,记录下吧 json格式在开发中用的十分广泛.在php中json_encode函数可以直接将数组转成 ...

  10. 工欲善其事,必先利其器 软件工具开发关键词 protractor自动化测试工具 RegexBuddy正则 CodeSmith,LightSwitch:代码生成 CheatEngine:玩游戏修改内存值必备神器 ApkIDE:Android反编译工具 Reflector:反编译dll动态链接库

    工欲善其事,必先利其器 本文版权归翟士丹(Stan Zhai)和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利. 原文地址:http ...