博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
设计模式学习笔记-观察者模式(转)
阅读量:6071 次
发布时间:2019-06-20

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

1. 概述

  有时被称作发布/订阅模式,观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。

2. 解决的问题

  将一个系统分割成一个一些类相互协作的类有一个不好的副作用,那就是需要维护相关对象间的一致性。我们不希望为了维持一致性而使各类紧密耦合,这样会给维护、扩展和重用都带来不便。观察者就是解决这类的耦合关系的。

3. 模式中的角色

  3.1 抽象主题(Subject):它把所有观察者对象的引用保存到一个聚集里,每个主题都可以有任何数量的观察者。抽象主题提供一个接口,可以增加和删除观察者对象。

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

  3.3 抽象观察者(Observer):为所有的具体观察者定义一个接口,在得到主题通知时更新自己。

  3.4 具体观察者(ConcreteObserver):实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题状态协调。

4. 模式解读

  4.1 观察者模式的类图  

  

  4.2 观察者模式的代码

///     /// 抽象主题类    ///     public abstract class Subject    {        private IList
observers = new List
(); ///
/// 增加观察者 /// ///
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(); } } } ///
/// 抽象观察者类,为所有具体观察者定义一个接口,在得到通知时更新自己 /// public abstract class Observer { public abstract void Update(); } ///
/// 具体观察者或具体通知者,将有关状态存入具体观察者对象;在具体主题的内部状态改变时,给所有登记过的观察者发出通知。具体主题角色通常用一个具体子类实现。 /// public class ConcreteSubject : Subject { private string subjectState; ///
/// 具体观察者的状态 /// public string SubjectState { get { return subjectState; } set { subjectState = value; } } } ///
/// 具体观察者,实现抽象观察者角色所要求的更新接口,已是本身状态与主题状态相协调 /// public class ConcreteObserver : Observer { private string observerState; private string name; private ConcreteSubject subject; ///
/// 具体观察者用一个具体主题来实现 /// public ConcreteSubject Subject { get { return subject; } set { subject = value; } } public ConcreteObserver(ConcreteSubject subject, string name) { this.subject = subject; this.name = name; } ///
/// 实现抽象观察者中的更新操作 /// public override void Update() { observerState = subject.SubjectState; Console.WriteLine("The observer's state of {0} is {1}", name, observerState); } }

  4.3 客户端代码

class Program    {        static void Main(string[] args)        {            // 具体主题角色通常用具体自来来实现            ConcreteSubject subject = new ConcreteSubject();            subject.Attach(new ConcreteObserver(subject, "Observer A"));            subject.Attach(new ConcreteObserver(subject, "Observer B"));            subject.Attach(new ConcreteObserver(subject, "Observer C"));            subject.SubjectState = "Ready";            subject.Notify();            Console.Read();        }    }

  运行结果

  

5. 模式总结

  5.1 优点

    5.1.1 观察者模式解除了主题和具体观察者的耦合,让耦合的双方都依赖于抽象,而不是依赖具体。从而使得各自的变化都不会影响另一边的变化。

  5.2 缺点

    5.2.1 依赖关系并未完全解除,抽象通知者依旧依赖抽象的观察者。

  5.3 适用场景

    5.3.1 当一个对象的改变需要给变其它对象时,而且它不知道具体有多少个对象有待改变时。

    5.3.2 一个抽象某型有两个方面,当其中一个方面依赖于另一个方面,这时用观察者模式可以将这两者封装在独立的对象中使它们各自独立地改变和复用。

 

转载于:https://www.cnblogs.com/mumuli/p/4375167.html

你可能感兴趣的文章
MonoDB的数据准备
查看>>
AngularJS------命令行
查看>>
价值1400美元的CEH(道德黑客)认证培训课程长啥样?(3)工具集
查看>>
Docker数据卷
查看>>
vscode常用设置
查看>>
程序员之---C语言细节20(符号和有符号之间转换、两数相加溢出后数值计算)...
查看>>
zookeeper学习
查看>>
【mac】mac上安装软件,报错 鉴定错误,但是安装包都是好的
查看>>
设计模式的6大原则
查看>>
【转】观看视频时启用硬件加速有什么用?如果关闭硬件加速又有什么区别呢?...
查看>>
Weblogic12c 单节点安装
查看>>
CentOS7下安装Docker-Compose操作记录
查看>>
【wpf】在win10系统上弹出toast和notification
查看>>
.axf 转化 .bin文件 的方法
查看>>
sql server无log ldf日志文件附件mdf数据库重新生成ldf日志文件
查看>>
Chapter 4 Invitations——15
查看>>
Spring Boot 2.0 Release Notes
查看>>
谈一谈python的垃圾回收机制
查看>>
windows上使用的免费连接linux终端xshell6,xftp6下载
查看>>
LeetCode 总结
查看>>