设计模式-观察者模式(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) 观察者模式的定义: 定义对象间的一种一对多的依赖关系.当一个对象的状态发生改变时,所有依赖于它的 ...
随机推荐
- C++ Standard Library
C++ Standard Library *注:内容主要是对參考1的学习记录.知识点与图片大都来源于该书, 部分知识点与图片来源于參考2. 详细參考信息,见最下方參考. * C++98中新支持的语言特 ...
- 解决 Out of range value adjusted for column 'ID' at row 1
MySQL升级到5.0.17后,在执行sql语句INSERT INTO `news` (`ID`, `Title`, `Content`) VALUES ('', '标题', '正文');时出现错误: ...
- cocos2d-js 粒子系统使用自定义图片,还原原来的图片宽高
粒子系统使用自定义图片很简单只需要在plist最后一行设置png的名称即可.但是,在实际使用中,发现自定义图片无法使用原来的形状,例如设置了一长条的图片,结果出来确实一个个圆球. 翻了plist和cc ...
- spring boot mybatis没有扫描jar中的Mapper接口
只需要在spring boot启动类上加上注解,并指定jar包中接口文件包路径即可 如下: @ComponentScan(basePackages = "com.xx") @Map ...
- ios中屏幕适配
- (void)viewDidLoad { [super viewDidLoad]; // 左上角 // 固定左边和上边,伸缩右边和下边 self.leftTop.autoresizingMask = ...
- Guice与Spring框架的区别
2007-4-23 再借斧子的例子说一说spring与guice的区别 看下边对于不同社会形态下一个人(java对象,调用者)需要一把斧子(java对象,被调用者)的例子: (1),原始社会 ...
- Swift3 文件操作常用方法汇总
基于swift3的一些常用文件操作方法: 1.创建文件(文件夹) 2.读取文件(根据名称) 3.读取文件(根据路径) 4.判断文件是否存在(根据名称) 5.判断文件是否存在(根据路径) 6.删除指定名 ...
- WordPress固定链接修改后访问文章页面404
如题, 修改固定链接为自定义结构后, 访问文章页面出现404的nginx错误. 解决:修改nginx.conf配置文件(/usr/local/nginx/conf/nginx.conf). 在serv ...
- java hibernate session create
public class RegisterStory { private SysUserCDao sysUserCDao; @Test public void test() { SessionFact ...
- Nginx 504 Gateway Time-out问题解决
今天站群VPS上面的所有站出现的 504 网关错误,现在小色还是菜菜的,斗胆解决下.在网上面搜解决方案,尝试设置ngxin的fast-cgi_buffers 和重启ngxin来解决,但是错误依旧.怀疑 ...