1.观察者模式(Observer/Event)

1.动机

  • 在软件构建过程中,需要为某些对象建立一种“通知依赖关系”——一个对象(目标)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知。如果这样的依赖关系过于紧密,将使软件不能很好地抵御变化。
  • 使用面向对象技术,可以将这种依赖关系弱化,并形成一种稳定的依赖关系,从而实现软件体系结构的松耦合。

2.模式定义

  • 定义对象间的一种一对多(变化)的依赖关系,以便当一个对象(Subject)的状态发生改变时,所有依赖于它的所有对象都得到通知并自动更新。——《设计模式》GoF

3.结构图

4.模式的组成

有上面结构图可以看出,在观察者模式的结构图有一下角色:

  1. 抽象主题角色(Subject):抽象主题把所有观察者对象的引用保存在一个列表中,并提供增加和删除观察者对象的操作,抽象主题角色又叫做抽象被观察者角色,一般由抽象类或接口实现。
  2. 抽象观察者角色(Observer):为所有具体观察者定义一个接口,在得到主题通知时更新自己,一般由抽象类或接口实现。
  3. 具体主题角色(ConcerteSubject):实现抽象主题接口,具体主题角色又叫做具体被观察者角色。
  4. 具体观察者角色(ConcreteObserver):实现抽象观察者角色所要求的的接口,以便使自身转台与主题的状态相协调。

2.例子实现

1.描述

订阅银行短信业务,当我们账户余额发生改变,我们就会收到相应的短信。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace Pattern
{//抽象观察者public abstract class abstractDepositor{private string name;//账户唯一的IDprivate int balance;//账户余额private bool moneyChanged = false;//账户余额未发生变化private DateTime datetime;//账户余额发生变化的时间/// <summary>/// 初始化/// </summary>/// <param name="name"></param>/// <param name="total"></param>public abstractDepositor(string name,int total){this.name = name;this.balance = total;}/// <summary>/// 取钱/// </summary>/// <param name="money"></param>public void GetMoney(int money){this.balance = this.balance - money;this.datetime = DateTime.Now;this.moneyChanged = true;}public int  _balance{get { return balance; }set{balance = value;}}public bool _IsChanged{get { return moneyChanged; }set { moneyChanged = value; }}public DateTime _datetime{get{return datetime;}set{datetime=value;}}public string _name{get { return name; }set { name = value; }}//更新账户状态public abstract void UpdateMoney(int money,DateTime datetime);}//抽象通知机制,支持多个观察者,在这里Subject和ConcreteSubject可以写一块,也可以抽取出来。public class Subject{public List<abstractDepositor> observers = new List<abstractDepositor>();//添加储户public void _add(abstractDepositor observer){if(!observers.Exists(x=>x._name==observer._name))observers.Add(observer);}//删除储户public void _remove(abstractDepositor observer){if (observers.Exists(x => x._name == observer._name))observers.Remove(observer);}//通知储户账户变化情况public void onNotify(){foreach (abstractDepositor observer in observers){if(observer._IsChanged){observer.UpdateMoney(observer._balance,observer._datetime);}}}}public class Person1 : abstractDepositor{public Person1(string name,int total):base (name,total){}public override void UpdateMoney(int currentbalance,DateTime datetime){Console.WriteLine("{0}的账户余额在{1}的时候发生变化,剩余余额为:{2}",this._name,datetime,currentbalance);}}public class Person2 : abstractDepositor{public Person2(string name, int total) : base(name, total) { }public override  void UpdateMoney(int currentbalance,DateTime datetime){Console.WriteLine("您的账户余额在{0}的时候发生变化,剩余余额为:{1}", datetime,currentbalance);}}class Program{static void Main(string[] args){Subject subject = new Subject();Person1 person1 = new Person1("dangxiaochun",50000);Person2 person2 = new Person2("zhumiao",300000);subject._add(person1);subject._add(person2);person1.GetMoney(5000);subject.onNotify();person1.GetMoney(300);person2.GetMoney(400);subject.onNotify();Console.ReadKey();}}
}

3.要点总结

  • 使用面向对象的抽象,Observer模式使得我们可以独立地改变目标与观察者,从而使二者之间的依赖关系达至松耦合。
  • 目标发送通知时,无需指定观察者,通知(可以携带通知信息作为参数)会自动传播。
  • 观察者自己决定是否需要订阅通知,目标对象对此一无所知。
  • Observer模式是基于事件的UI框架中常常用的设计模式,也是MVC模式的一个重要组成部分

优点:

(1)、观察者模式实现了表示层和数据逻辑层的分离,并定义了稳定的更新消息传递机制,并抽象了更新接口,使得可以有各种各样不同的表示层,即观察者。

(2)、观察者模式在被观察者和观察者之间建立了一个抽象的耦合,被观察者并不知道任何一个具体的观察者,只是保存着抽象观察者的列表,每个具体观察者都符合一个抽象观察者的接口。

(3)、观察者模式支持广播通信。被观察者会向所有的注册过的观察者发出通知。

缺点:

(1)、如果一个被观察者有很多直接和间接的观察者时,将所有的观察者都通知到会花费很多时间。

(2)、虽然观察者模式可以随时使观察者知道所观察的对象发送了变化,但是观察者模式没有相应的机制使观察者知道所观察的对象是怎样发生变化的。

(3)、如果在被观察者之间有循环依赖的话,被观察者会触发它们之间进行循环调用,导致系统崩溃,在使用观察者模式应特别注意这点。

4.参考

C#设计模式之十六观察者模式(Observer Pattern)【行为型】

李建忠设计模式——观察者模式

李建忠设计模式——观察者模式相关推荐

  1. 李建忠设计模式——策略模式Strategy

    目录 1.策略模式定义 1.动机 2.模式定义 3.结构 2.实现例子 1.问题描述 2.代码实现 3.要点总结 4.参考 1.策略模式定义 1.动机 软件构建过程中,某些对象使用的算法可能多种多样, ...

  2. 清华李建忠设计模式课程感想

    最近又看了一波设计模式的东西,又有一些新的认识,设计模式一般是重构到模式,模式不是一蹴而就的,很多最开始在实现产品经理的需求时,第一版是不太能识别模式的,当然如果后期的迭代需求方向明确也可做提前设计, ...

  3. 李建忠设计模式-组件协作模式-模板方法模式

    目录 1.前言 2.模板方法模式(Template Method) 1.动机 2.例子 3.定义 1.结构图 2.模板方法模式适用情形 3.模式特点 参考 1.前言 现代软件专业分工后的第一个结果是& ...

  4. 李建忠设计模式之“组件协作”模式

    文章目录 模板方法模式(Template Method) 定义 动机 结构图 代码 要点 总结 策略模式(Strategy) 定义 动机 结构图 代码 要点 总结 观察者模式(Observer/Eve ...

  5. 李建忠设计模式之总结

    总结 一个目标:管理变化,提高复用! 两个手段:分解 && 抽象 八大原则 依赖倒置原则(DIP) 开放封闭原则(OCP) 单一职责原则(SRP) Liskov 替换原则(LSP) 接 ...

  6. 李建忠设计模式——装饰模式

    1."单一职责"模式 在软件组件的设计中,如果责任划分不清晰,使用继承得到的结果往往是随着需求的变化,子类急剧膨胀,同时充斥着重复代码,这时候的关键是划清责任. 典型模式 Deco ...

  7. 李建忠设计模式(二)

    目录 1.23种设计模式的分类 1.GOF-23模式分类 2.从封装变化校对对模式分类 3.重构关键技法 1.23种设计模式的分类 设计模式的最大作用:在变化和稳定中间寻找隔离点,然后来分离它们,从而 ...

  8. 李建忠设计模式——桥模式

    目录 1.桥模式 1.动机 2.模式定义 3.结构图 4.模式的组成 2.实例 1.描述 2.代码实现 要点总结 参考: 1.桥模式 1.动机 由于某些类型的固有的实现逻辑,使得他们具有两个变化的维度 ...

  9. 李建忠设计模式(一)

    目录 1.软件设计的目标 2.面向对象设计原则 1.重新认识面向对象 2.面向对象设计原则 1.依赖倒置原则(DIP) 2.开放封闭原则(OCP) 3.单一职责原则(SRP) 4.Liskov替换原则 ...

最新文章

  1. 一个web蠕虫的简单实现
  2. 您现在只需免费与相机捆绑即可购买一个PSVR
  3. boost::stl_interfaces::iterator_interface相关的测试程序
  4. 54. Spiral Matrix (Matrix)
  5. [蓝桥杯][2018年第九届真题]版本分支(离线LCA模板)
  6. C#开发微信公众平台-就这么简单(附Demo)(转)
  7. JAVA集合框架及其常用方法
  8. Magento 自定义分页代码 How to change pagination design in product listing page in magen
  9. (办公)eclipse连接github cannot open git-upload-pack(git-receive-pack)
  10. git理解HEAD,master
  11. r语言c50算法的过程,【机器学习与R语言】5-规则学习算法
  12. 【强化学习】83篇文献-万字总结
  13. win10下安装Ubuntu16.04双系统 (gtx1050ti)(联想legion)
  14. C++-灰度图上色GrayToColor
  15. 天网系统服务器码,天网管理系统
  16. IDEA-Translation插件更新TKK失败
  17. stm32不使用外部晶振管脚怎么处理_stm32103如果不用32k晶振,那引脚是悬空还是接地?...
  18. SEO优化收徒蜘蛛池是什么
  19. 大数据工程师技术栈探讨
  20. 细侃那些悬而未决的数学趣味谜题

热门文章

  1. 为什么我带的00后后辈在职场平步青云,比我还先升职了该走还是留?
  2. 计算机网络里面ap是什么,无线AP是什么
  3. 已经一点经纬度和距离,计算另一点的经纬度
  4. 计算机专业看重CPU还是显卡,电脑大神告诉你处理器和显卡哪个重要
  5. 我的QT Creator学习笔记(二十一)——Qt国际化和Qt插件
  6. 抖音seo搜索是什么?源码部署-seo排名系统源码分析
  7. 怎么保存网页为html格式,怎样保存网页部分内容为html格式?
  8. java程序设计 计算器_java 编程一(计算器)
  9. 栈+模拟(大鱼吃小鱼)
  10. 括号配对c语言,括号匹配(c语言实现)