观察者模式(有时又被称为模型-视图(View)模式、源-收听者(Listener)模式或从属者模式)是软件设计模式的一种。将观察者(watcher)和被观察者(subject)完美分离。

这里讲一个场景:话说赵丽颖小姐姐最近如日中天,受到很多粉丝喜爱,某天她开通了微博,迅速获得几千万粉丝关注。当然赵丽颖平常发发微博,她的”萤火虫“们收到她的微博的通知后会去评论和留言;当然也不乏有各种各样的喷子,她心情好可以不理这些人,过分的话,去你丫的,姐可以拉黑你!!!

下面就这个场景,我决定用观察者模式将之还原。

我们都知道观察者模式,有四个角色:抽象主题、具体主题、抽象观察者和具体观察者。

话不多说上代码:

AbstractBloger:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace Observer
{
/// <summary>
/// 开通微博的博主们
/// </summary>
public abstract class AbstractBloger
{
/// <summary>
/// 粉丝列表
/// </summary>
private List<AbstractFan> fans = new List<AbstractFan>(); /// <summary>
/// 博主姓名
/// </summary>
public string BlogerName { get; set; } /// <summary>
/// 博主构造函数
/// </summary>
/// <param name="name">博主姓名</param>s
public AbstractBloger(string name)
{
this.BlogerName = name;
} /// <summary>
/// 添加一个订阅者(粉丝)
/// </summary>
/// <param name="observer">具体的订阅者(粉丝)对象</param>
public void AddObserver(AbstractFan observer)
{
if (fans.Contains(observer))
{
return;
}
fans.Add(observer);
Console.WriteLine($"{observer.name}关注了她");
} /// <summary>
/// 删除一个订阅者(粉丝)
/// </summary>
/// <param name="observer">具体的订阅者(粉丝)对象</param>
public void RemoveObserver(AbstractFan observer)
{
if (fans.Contains(observer))
{
fans.Remove(observer);
}
} /// <summary>
/// 博主发表微博,此时粉丝会收到通知
/// </summary>
public void PublishBlog()
{
Console.WriteLine($"{this.BlogerName}发表了一条微博");
//遍历通知每一个订阅者(粉丝)
foreach (AbstractFan ob in fans)
{
if (ob != null)
{
ob.Receive(this);
}
}
} }
}

Bloger:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace Observer
{
/// <summary>
/// 具体的订阅博主类
/// </summary>
public class Bloger : AbstractBloger
{
public Bloger(string name)
: base(name)
{
Console.WriteLine($"{name}开通微博了");
}
}
}

AbstractFan:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace Observer
{
/// <summary>
/// 关注博主的粉丝们
/// </summary>
public abstract class AbstractFan
{
public string name { get; set; }
public AbstractFan(string name)
{
this.name = name;
}
public abstract void Receive(AbstractBloger bloger);
}
}

Fan:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace Observer
{
public class Fan:AbstractFan
{
/// <summary>
/// 观察者(粉丝)名字
/// </summary>
private string _Name;
public string Name
{
get { return _Name; }
set { _Name = value; }
} /// <summary>
/// 观察者(粉丝)构造函数
/// </summary>
/// <param name="name">观察者(粉丝)名字</param>
public Fan(string name):base(name)
{
this._Name = name;
} /// <summary>
/// 观察
/// </summary>
/// <param name="blog"></param>
public override void Receive(AbstractBloger bloger)
{
Console.WriteLine("{0}观察到了:{1}发布了一条微博", Name, bloger.BlogerName);
}
}
}

测试程序Program.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Observer; namespace ObserverTest
{
class Program
{
static void Main(string[] args)
{
//赵丽颖某天开通了微博
AbstractBloger bloger = new Bloger("赵丽颖");
//创建订阅者
AbstractFan me = new Fan("铁粉");
AbstractFan penzi = new Fan("喷子粉");
AbstractFan jiangshi = new Fan("僵尸粉");
Console.WriteLine("有很多粉丝都关注了她");
//添加对赵丽颖的关注
bloger.AddObserver(me);
bloger.AddObserver(penzi);
bloger.AddObserver(jiangshi);
//赵丽颖发布一条微博
bloger.PublishBlog();
Console.WriteLine("有个喷子经常喷赵丽颖");
Console.WriteLine("赵丽颖一怒之下将此喷子拉黑");
bloger.RemoveObserver(penzi);
bloger.PublishBlog();
Console.ReadLine();
}
}
}

测试结果:

C#通熟易懂观察者模式的更多相关文章

  1. JVM,Java虚拟机基础知识新手入门教程(超级通熟易懂)

    作者:请叫我红领巾,转载请注明出处http://www.cnblogs.com/xxzhuang/p/7453746.html,简书地址:http://www.jianshu.com/p/b963b3 ...

  2. EJB初识(通熟易懂)

    转载自http://blog.csdn.net/jojo52013145/article/details/5783677,讲的很透彻,佩服,膜拜学习 1. 我们不禁要问,什么是"服务集群&q ...

  3. stl的实现原理简单讲解,通熟易懂

    总结 需要经常随机访问请用vector 2.list list就是双向链表,元素也是在堆中存放,每个元素都是放在一块内存中,它的内存空间可以是不连续的,通过指针来进行数据的访问,这个特点使得它的随机存 ...

  4. 最通熟易懂的Hadoop HDFS实践攻略

    HDFS是用来解决什么问题?怎么解决的? 如何在命令行下操作HDFS? 如何使用Java API来操作HDFS? 在了解基本思路和操作方法后,进一步深究HDFS具体的读写数据流程 学习并实践本文教程后 ...

  5. 基于OpenCV的车辆检测与追踪的实现

    最近老师布置了一个作业,是做一个基于视频的车辆检测与追踪,用了大概两周的时间做了一个简单的,效果不是很理想,但抑制不住想把自己的一些认识写下来,这里就把一些网络上的博客整理一下分享给大家,希望帮助到大 ...

  6. (一)开篇—杂谈WebGIS

    文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.前言 我相信大家对百度地图,谷歌地图等相关应用已经是非常熟悉了.通过 ...

  7. Redis集群研究和实践(基于redis 3.0.5)

    前言 redis 是我们目前大规模使用的缓存中间件,由于它强大高效而又便捷的功能,得到了广泛的使用.现在的2.x的稳定版本是2.8.19,也是我们项目中普遍用到的版本. redis在年初发布了3.0. ...

  8. java IO基础操作

    java IO基础,通熟易懂,好久没复习java 基础了.这里是传送门... http://www.cnblogs.com/nerxious/archive/2012/12/15/2818848.ht ...

  9. IOS开发之多线程 -- GCD的方方面面

    前言:这篇GCD的博文是本人阅读了很多海内外大神的关于GCD的文章,以及结合之前自己对GCD的粗浅的认识,然后取其精华,去其槽粕,综合起来的笔记,而且是尽可能的以通熟易懂的并且是正确的理论论述方式呈现 ...

随机推荐

  1. LeetCode之“树”:Binary Tree Level Order Traversal && Binary Tree Level Order Traversal II

    Binary Tree Level Order Traversal 题目链接 题目要求: Given a binary tree, return the level order traversal o ...

  2. LeetCode之“动态规划”:Interleaving String

    题目链接 题目要求: Given s1, s2, s3, find whether s3 is formed by the interleaving of s1 and s2. For example ...

  3. myBatis源码之XMLConfigBuilder

    XMLConfigBuilder是对mybatis的配置文件进行解析的类,会对myabtis解析后的信息存放在Configuration对象中,Configuration对象会贯穿整个mybatis的 ...

  4. ubuntu 输入用户名密码又回到登陆界面

    问题描述: 输入正确的用户名密码,登陆后又返回登陆界面,重复出现. 问题解决: 环境变量出错,重新配置环境变量. 1.进入命令行模式Ctrl+Alt+F*,然后输入用户名密码: 2.登进去之后,以管理 ...

  5. CF633G

    题目大意: 给你一棵树,根节点为1 有2种操作,第一种是给u节点所在的子树的所有节点的权值+x 第二种是询问,假设v是子树u中的节点,有多少种质数满足av = p + m·k 做法:维护子树信息显然d ...

  6. vue学习:props,scope,slot,ref,is,slot,sync等知识点

    1.ref :为子组件指定一个索引 ID,给元素或者组件注册引用信息.refs是一个对象,包含所有的ref组件. <div id="parent"> <user- ...

  7. sql server对并发的处理-乐观锁和悲观锁

    https://www.cnblogs.com/dengshaojun/p/3955826.html sql server对并发的处理-乐观锁和悲观锁 假如两个线程同时修改数据库同一条记录,就会导致后 ...

  8. 百度AI技术QQ群

    百度语音QQ群 648968704 视频分析QQ群 632473158 DuerOSQQ群 604592023 图像识别QQ群 649285136 文字识别QQ群 631977213 理解与交互技术U ...

  9. mysql报错ERROR 2003 (HY000): Can't connect to MySQL server on 'localhost' (10061)

    23:29:02/2017-05-03 现象描述:在Command Line Client可以登陆,但是在命令提示符cmd下登陆出错. 我最终的解决办法是: 我先去看了一下我的my.ini配置文件. ...

  10. SpringBoot jar包中资源加载问题

    在IDE下调试怎么也没有发现问题,但是部署到服务器上,提示找不到资源,找了半天资料总算是找到了原因: Jar包中的资源加载不能使用File方式,只能使用InputStream方式读取.知道原因就好解决 ...