博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【设计模式基础】行为模式 - 1 - 观察者(Observer)
阅读量:4005 次
发布时间:2019-05-24

本文共 2502 字,大约阅读时间需要 8 分钟。

1. 模式意图

观察者模式又叫做发布-订阅(Publish - Subscribe)模式,模型-视图(Model - View)模式、源-监听器(Source - Listener)模式,依赖(Dependents)模式。

观察者模式定义了对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知并被自动更新。

这一模式中的关键对象是目标(subject)和观察者(observer)。一个目标可以有任意数目的依赖它的观察者。一旦目标的状态发生改变,所有观察者都得到通知。作为对这个通知的响应,每个观察者都将查询目标以使其状态与目标的状态同步。

这种交互也称为发布-订阅。目标是通知的发布者。它发出通知时并不需知道谁是它的观察者。可以有任意数目的观察者订阅并接收通知。

Observer模式的优点是实现了表示层和数据逻辑层的分离,并定义了稳定的更新消息传递机制。

其缺点是每个外观对象必须继承这个抽象出来的观察者接口类。虽然观察者模式可以随时使观察者知道所观察的对象发生了变化,但是观察者模式没有相应的机制使观察者知道所观察的对象是怎么发生变化的。

2. 模式定义

Subject(目标):                                  把所有观察者对象的引用保存在一个聚集里,每个subject可以有任意数量的观察者;提供注册和删除观察者对象的接口。

Observer(观察者):                          为所有的具体观察者定义一个接口;在得到subject的通知时更新自己;

ConcreteSubject(具体目标):       将有关状态存入具体观察者对象;在具体目标的内部状态改变时,给所有登记过的观察者发出通知。

ConcreteObserver(具体观察者):维护一个指向ConcreteSubject对象的引用;存储有关状态,这些状态应与目标的状态保持一致;实现Observer的更新接口。

3. 模式实现

3.1 C#中的观察者模式

// Observer pattern -- Structural example  using System;using System.Collections;// "Subject"abstract class Subject{  // Fields  private ArrayList observers = new ArrayList();  // Methods  public void Attach( Observer observer )  {    observers.Add( observer );  }  public void Detach( Observer observer )  {    observers.Remove( observer );  }  public void Notify()  {    foreach( Observer o in observers )      o.Update();  }}// "ConcreteSubject"class ConcreteSubject : Subject{  // Fields  private string subjectState;  // Properties  public string SubjectState  {    get{ return subjectState; }    set{ subjectState = value; }  }}// "Observer"abstract class Observer{  // Methods  abstract public void Update();}// "ConcreteObserver"class ConcreteObserver : Observer{  // Fields  private string name;  private string observerState;  private ConcreteSubject subject;  // Constructors  public ConcreteObserver( ConcreteSubject subject,      string name )  {    this.subject = subject;    this.name = name;  }  // Methods  override public void Update()  {    observerState = subject.SubjectState;    Console.WriteLine( "Observer {0}'s new state is {1}",      name, observerState );  }  // Properties  public ConcreteSubject Subject  {    get { return subject; }    set { subject = value; }  }}/// /// Client test/// public class Client{  public static void Main( string[] args )  {    // Configure Observer structure    ConcreteSubject s = new ConcreteSubject();    s.Attach( new ConcreteObserver( s, "1" ) );    s.Attach( new ConcreteObserver( s, "2" ) );    s.Attach( new ConcreteObserver( s, "3" ) );    // Change subject and notify observers    s.SubjectState = "ABC";    s.Notify();  }}

4. 模式应用

你可能感兴趣的文章
第一性原理:戳中问题本质的人是怎么思考的?
查看>>
No.147 - LeetCode1108
查看>>
No.148 - LeetCode771
查看>>
No.174 - LeetCode1305 - 合并两个搜索树
查看>>
No.175 - LeetCode1306
查看>>
No.176 - LeetCode1309
查看>>
FE:http状态码
查看>>
No.182 - LeetCode1325 - C指针的魅力
查看>>
mac:移动python包路径
查看>>
mysql:sql create database新建utf8mb4 数据库
查看>>
mysql:sql alter database修改数据库字符集
查看>>
mysql:sql alter table 修改列属性的字符集
查看>>
mysql:sql drop table (删除表)
查看>>
mysql:sql truncate (清除表数据)
查看>>
scrapy:xpath string(.)非常注意问题
查看>>
yuv to rgb 转换失败呀。天呀。谁来帮帮我呀。
查看>>
yuv420 format
查看>>
单纯的把Y通道提取出来能正确显示出灰度图来为什么我的Qt就显示不出来呢转换有问题呀?
查看>>
YUV420只绘制Y通道
查看>>
yuv420 还原为RGB图像
查看>>