设计模式-观察者模式(Observer Pattern)
观察者模式(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)的更多相关文章
- 设计模式 - 观察者模式(Observer Pattern) 详细说明
观察者模式(Observer Pattern) 详细说明 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26583157 版权全部 ...
- 设计模式 - 观察者模式(Observer Pattern) 详细解释
观察者模式(Observer Pattern) 详细解释 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26583157 版权全部 ...
- 设计模式 - 观察者模式(Observer Pattern) Java内置 用法
观察者模式(Observer Pattern) Java内置 用法 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26601659 ...
- C#设计模式——观察者模式(Observer Pattern)1
一.概述在软件设计工作中会存在对象之间的依赖关系,当某一对象发生变化时,所有依赖它的对象都需要得到通知.如果设计的不好,很容易造成对象之间的耦合度太高,难以应对变化.使用观察者模式可以降低对象之间的依 ...
- C#设计模式——观察者模式(Observer Pattern)
一.概述在软件设计工作中会存在对象之间的依赖关系,当某一对象发生变化时,所有依赖它的对象都需要得到通知.如果设计的不好,很容易造成对象之间的耦合度太高,难以应对变化.使用观察者模式可以降低对象之间的依 ...
- 23种设计模式--观察者模式-Observer Pattern
一.观察者模式的介绍 观察者模式从字面的意思上理解,肯定有两个对象一个是观察者,另外一个是被观察者,观察者模式就是当被观察者发生改变得时候发送通知给观察者,当然这个观察者可以是多个对象,在项 ...
- 乐在其中设计模式(C#) - 观察者模式(Observer Pattern)
原文:乐在其中设计模式(C#) - 观察者模式(Observer Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 观察者模式(Observer Pattern) 作者:weba ...
- 二十四种设计模式:观察者模式(Observer Pattern)
观察者模式(Observer Pattern) 介绍定义对象间的一种一对多的依赖关系,以便当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动刷新. 示例有一个Message实体类,某些对象 ...
- java设计模式--观察者模式(Observer)
java设计模式--观察者模式(Observer) java设计模式--观察者模式(Observer) 观察者模式的定义: 定义对象间的一种一对多的依赖关系.当一个对象的状态发生改变时,所有依赖于它的 ...
随机推荐
- 解决java网络编程IPv6问题
如果系统中开启了IPV6协议(比如window7),java网络编程经常会获取到IPv6的地址,这明显不是我们想要的结果,搜索发现很多蹩脚的做法是:禁止IPv6协议.其实查看官方文档有详细的说明: j ...
- 一起talk C栗子吧(第八十五回:C语言实例--使用信号进行进程间通信二)
各位看官们,大家好,上一回中咱们说的是使用信号进行进程间通信的样例,这一回咱们接着上一回的内容,继续说该样例.闲话休提.言归正转. 让我们一起talk C栗子吧. 我们在上一回中举了使用信号进行进程间 ...
- Knockout学习之组合监控属性
组合监控属性 顾名思义,就是我们可以将多个属性合并为一个属性.这样在显示的时候就是整体了,并且其中任何一个属性发生改变,这个属性也都会随之发生改变从而更新视图,而这些只需要使用computed函数就可 ...
- fiddler怎么修改服务器返回参数并发送
在进行使用fiddler中提供了较多的功能进行使用的,那么进行就可以对当前的网页中的暂停之后,在进行使用fiddler中把拦截起的后,在进行修改的服务器参数的之后,在把参数修改完成之后,把进行发送出去 ...
- 使用eclipse生成文档(javadoc)主要有三种方法:
使用eclipse生成文档(javadoc)主要有三种方法: 1,在项目列表中按右键,选择Export(导出),然后在Export(导出)对话框中选择java下的javadoc,提交到下一步. 在Ja ...
- 理解 LDA 主题模型
前言 gamma函数 0 整体把握LDA 1 gamma函数 beta分布 1 beta分布 2 Beta-Binomial 共轭 3 共轭先验分布 4 从beta分布推广到Dirichlet 分布 ...
- Centos7.4和Ubuntu18.04安装PHP7.2
安装依赖 yum install gcc-c++ libxml2 libxml2-devel openssl openssl-devel bzip2 bzip2-devel libcurl libcu ...
- Arduino和C51开发DS1302时钟
技术:51单片机.Arduino.DS1302时钟.串口通信 概述 本文实现51单片机和Arduino串口实时显示时钟功能,让读者对DS1302能够更好的理解,这次功能也和上节课学到的串口通信运用 ...
- ASP.NET之通过JS向服务端(后台)发出请求(__doPostBack is undefined)
ASP.NET回发数据是通过函数__doPostBack来实现的.该函数在加入了服务端控件,并将AutoPostBack设置为true之后,将自己主动生成,详细能够參看以下的图. watermark/ ...
- Delphi2010怎样获取程序内部自身版本?
用原来的GetFileVersionInfo仅仅能获取Delpi7的程序版本,用在Delphi2010中就无论用了 //------ 获取文件版本 function F_GetFileVersion( ...