c#设计模式系列:观察者模式(Observer Pattern)
引言
在现实生活中,处处可见观察者模式,例如,微信中的订阅号,订阅博客和QQ微博中关注好友,这些都属于观察者模式的应用。在这一章将分享我对观察者模式的理解,废话不多说了,直接进入今天的主题。
观察者模式的介绍
2.1 观察者模式的定义
从生活中的例子可以看出,只要对订阅号进行关注的客户端,如果订阅号有什么更新,就会直接推送给订阅了的用户。从中,我们就可以得出观察者模式的定义。
观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象,这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己的行为。
2.2 观察者模式的结构图
可以看出,在观察者模式的结构图有以下角色:
- 抽象主题角色(Subject):抽象主题把所有观察者对象的引用保存在一个列表中,并提供增加和删除观察者对象的操作,抽象主题角色又叫做抽象被观察者角色,一般由抽象类或接口实现。
- 抽象观察者角色(Observer):为所有具体观察者定义一个接口,在得到主题通知时更新自己,一般由抽象类或接口实现。
- 具体主题角色(ConcreteSubject):实现抽象主题接口,具体主题角色又叫做具体被观察者角色。
- 具体观察者角色(ConcreteObserver):实现抽象观察者角色所要求的接口,以便使自身状态与主题的状态相协调。
2.3观察者模式的实现
下面我们已抖音为例,当你刷抖音时候,看到一个很不错的小视频,就关注了这个作者,以后作者每次更新视频的时候,系统都会给关注他的粉丝推送新的消息,下面是我写的第一版实现代码:

/// <summary>
/// 作者
/// </summary>
public class OAuth
{
private List<Fans> list = new List<Fans>();
public string name { get; set; } /// <summary>
/// 新增一个粉丝
/// </summary>
/// <param name="add"></param>
public void Add(Fans add)
{
list.Add(add);
}
/// <summary>
/// 减少一个粉丝
/// </summary>
/// <param name="remove"></param>
public void Remove(Fans remove)
{
list.Remove(remove);
}
public void Nofify()
{
foreach (Fans item in list)
{
item.Update();
}
}
}
/// <summary>
/// 粉丝
/// </summary>
public class Fans
{ private string name;
private OAuth sub;
public Fans(string name, OAuth sub)
{
this.name = name;
this.sub = sub;
}
public void Update()
{
Console.WriteLine("你好:{0},{1}发布了新的作品,点击查看",name,sub.name);
}
} /// <summary>
/// 客户端
/// </summary>
class Program
{
static void Main(string[] args)
{ OAuth oauth = new OAuth();
oauth.name = "小炒肉";
Fans a = new Fans("青椒",oauth);
Fans b = new Fans("胡萝卜",oauth);
oauth.Add(a);
oauth.Add(b); oauth.Nofify(); Console.ReadLine();
}
}
//结果显示
你好:青椒,小炒肉发布了新的作品,点击查看
你好:胡萝卜,小炒肉发布了新的作品,点击查看
看到这种代码我们首先想到的是 违反了面向对象的开发-封闭原则,其次是依赖倒转原则,类与类之间不应该相互依赖,而应该依赖与抽象,好了,我们得重新修改了,10分钟后第二版出来了

public abstract class Observer
{
protected string name;
protected Subject sub;
public Observer(string name, Subject sub)
{
this.name = name;
this.sub = sub;
}
public abstract void Update();
} public class Person : Observer
{
public Person(string name, Subject sub) : base(name, sub) { } public override void Update()
{
Console.WriteLine("你好:{0},{1}发布了新的作品,点击查看", name, sub.name);
}
}
public abstract class Subject
{
public string name { get; set; }
public abstract void Add(Observer ob);
public abstract void Remove(Observer ob);
public abstract void Notify();
}
public class Green : Subject
{
private List<Observer> list = new List<Observer>();
public override void Add(Observer ob)
{
list.Add(ob);
}
public override void Notify()
{
foreach (var item in list)
{
item.Update();
}
}
public override void Remove(Observer ob)
{
list.Remove(ob);
}
}
/// <summary>
/// 客户端
/// </summary>
class Program
{
static void Main(string[] args)
{
Subject ob = new Green();
ob.name = "小炒肉";
Observer a = new Person("青椒", ob);
Observer b = new Person("胡萝卜", ob);
ob.Add(a);
ob.Add(b);
ob.Notify();
Console.ReadLine();
}
}
///结果
你好:青椒,小炒肉发布了新的作品,点击查看
你好:胡萝卜,小炒肉发布了新的作品,点击查看
现在已经依赖接口编程,但是“抽象通知者”还是依赖 抽象观察者,也就是说,万一没有了抽象观察者这样的接口,我这通知的功能就完成不了,下面我们引入委托解耦实现通知者和观察者

public class Person
{
protected string name;
protected Subject sub;
public Person(string name, Subject sub)
{
this.name = name;
this.sub = sub;
}
public void UpdateTP()
{
Console.WriteLine("你好:{0},{1}发布了新的作品,点击查看", name, sub.name);
}
}
public delegate void EventHandler();
public interface Subject
{
string name { get; set; }
void Notify();
}
public class Green : Subject
{ public event EventHandler Update;
public string name { get; set; } public void Notify()
{
Update();
}
}
/// <summary>
/// 客户端
/// </summary>
class Program
{
static void Main(string[] args)
{
Green hand = new Green();
hand.name = "小王";
Person per = new Person("青椒",hand);
Person Ge = new Person("小炒肉", hand);
hand.Update += new EventHandler(per.UpdateTP);
hand.Update += new EventHandler(Ge.UpdateTP); hand.Notify(); Console.ReadLine();
}
}
总结
在C#的event中,委托充当了抽象的Observer接口,而提供事件的对象充当了目标对象。委托是比抽象Observer接口更为松耦合的设计。
好了在次复习下,观察者模式的定义,观察者模式定义了一种一对多的关系,让多个观察者对象可以同时监听某一个主题对象,这个主题对象在发送状态改变时,会通知所有观察者对象,时它们能够自动更新自己
c#设计模式系列:观察者模式(Observer Pattern)的更多相关文章
- 乐在其中设计模式(C#) - 观察者模式(Observer Pattern)
原文:乐在其中设计模式(C#) - 观察者模式(Observer Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 观察者模式(Observer Pattern) 作者:weba ...
- 二十四种设计模式:观察者模式(Observer Pattern)
观察者模式(Observer Pattern) 介绍定义对象间的一种一对多的依赖关系,以便当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动刷新. 示例有一个Message实体类,某些对象 ...
- [设计模式] 19 观察者模式 Observer Pattern
在GOF的<设计模式:可复用面向对象软件的基础>一书中对观察者模式是这样说的:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新.当一个 ...
- c#设计模式之观察者模式(Observer Pattern)
场景出发 一个月高风黑的晚上,突然传来了尖锐的猫叫,宁静被彻底打破,狗开始吠了,大人醒了,婴儿哭了,小偷跑了 这个过程,如果用面向对象语言来描述,简单莫过于下: public class Cat { ...
- 设计模式之观察者模式(Observer pattern)
最近参加了一次面试,其中笔试题有一道编程题,在更换掉试题的描述场景后,大意如下: 上课铃声响起,学生A/B/C/D进入教室:下课铃声响起,学生A/B/C/D离开教室. 要求使用设计模式的思想完成铃与学 ...
- 设计模式九: 观察者模式(Observer Pattern)
简介 观察者属于行为型模式的一种, 又叫发布-订阅模式. 如果一个对象的状态发生改变,依赖他的对象都将发生变化, 那么这种情况就适合使用观察者模式. 它包含两个术语,主题(Subject),观察者(O ...
- 【设计模式】观察者模式 Observer Pattern
定义:观察者模式定义了对象之间的一对多依赖.当“主题”(Object)状态改变事,所有依赖它的“观察者”(Observer)都会受到通知并自动更新.主题支持观察者订阅和退订. 观察者模式提供了一种对象 ...
- 【UE4 设计模式】观察者模式 Observer Pattern
概述 描述 定义对象间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新.观察者模式又叫做 发布-订阅(Publish/Subscribe)模式 模型-视图(M ...
- 设计模式-观察者模式(Observer Pattern)
观察者模式(Observer Pattern):定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象.这个主题对象在状态发生变化时,会通知所有观察者对象,使他们能够自动更新自己. 观察者 ...
- 设计模式 - 观察者模式(Observer Pattern) 详细说明
观察者模式(Observer Pattern) 详细说明 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26583157 版权全部 ...
随机推荐
- django admin 中实现word文档下载
为了实现此功能,需要用到的知识点: (1)django admin 自定义字段: 参考:http://www.cnblogs.com/wumingxiaoyao/p/6928297.html ...
- 在kindeditor 获取textarea 中 输入的值
要在kindeditor 获取textarea 中 输入的值 必须在kindeditor创建的时候添加下面红色字体的代码 kindeditor创建代码如下: var editor;KindEd ...
- ubuntu下使用sdk manager 安装sdk 其他版本
在终端运行SDK Manager 的脚本 sdk目录下的tools目录下的 android 脚本 就能打开sdk manager界面进行选择安装了.
- IDEA2018.2版本注册
IntelliJ IDEA 2018.2版本注册 1.到官网下载IDEA安装文件,windows版本ideaIU-2018.2.2.exe,然后安装: 2.下载补丁包JetbrainsCrack-3. ...
- C++Primer笔记-----day05
=======================================================================day05======================== ...
- hbase安装与配置-分布式
HBASE安装与配置 备注: 1:本文在hadoop的完全分布式基础上部署hbase 2:本文使用的是小博主自己搭建的zookpeer服务,未使用hbase本身的zookpeer服务 本文内容在以下前 ...
- TrinityCore3.3.5编译过程-官方指导-踩坑总结
官方指导:主页->how to compile -> windows 指导文档写得很详细,但有不少细节点没提到,这里把过程简化总结,说明重点,及易坑点 1,安装需求 编译工具:cmake, ...
- Tmux (转)
Tmux是一个优秀的终端复用软件,类似GNU Screen,但来自于OpenBSD,采用BSD授权.使用它最直观的好处就是,通过一个终端登录远程主机并运行tmux后,在其中可以开启多个控制台而无需再“ ...
- C#多线程学习-求和
1.代码如下 // *********************************************************************** // Assembly : Shar ...
- swarmkit
SwarmKit是用于在任何规模上编排分布式系统的工具包. 它包括节点发现的原语,基于raft的共识,任务调度等. 其主要优点是: 分布式:SwarmKit使用raft共识算法来协调,不依赖单一故障点 ...