观察者模式(有时又被称为模型-视图(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. 使用Multiplayer Networking做一个简单的多人游戏例子-3/3(Unity3D开发之二十七)

    使用Multiplayer Networking做一个简单的多人游戏例子-1/3 使用Multiplayer Networking做一个简单的多人游戏例子-2/3 使用Multiplayer Netw ...

  2. java 项目得到jar和classes路径

    java 项目得到jar和classes路径 public static String getJarPath(Class clazz) { String path = clazz.getProtect ...

  3. Linux的常用命令(2) - 关机

    关机命令 shutdown‑h now 立即进行关机 shutdown‑r now 现在重新启动计算机 -t sec : -t后面加秒数,即"过几秒后关机" -k      : 不 ...

  4. 【Android 应用开发】AndroidUI设计之 布局管理器 - 详细解析布局实现

    写完博客的总结 : 以前没有弄清楚的概念清晰化 父容器与本容器属性 : android_layout...属性是本容器的属性, 定义在这个布局管理器的LayoutParams内部类中, 每个布局管理器 ...

  5. linux服务搭建----ftp与ftp yum源搭建

    ftp服务     如果没有ftp         yum -y install  vsftpd (前提是你在有yum源的情况下才可以使用这条命令)     service vsftpd  resta ...

  6. Unity Singleton 单例类(Unity3D开发之二十)

    猴子原创,欢迎转载.转载请注明: 转载自Cocos2Der-CSDN,谢谢! 原文地址: http://blog.csdn.net/cocos2der/article/details/47335197 ...

  7. 【53】java的多线程同步剖析

    synchronized关键字介绍: synchronized锁定的是对象,这个很重要 例子: class Sync { public synchronized void test() { Syste ...

  8. C++——虚函数问题小集

    学习C++ 不可避免地会遇到虚函数的问题,下面几个问题在学习初期或多或少会存在一些疑惑,所以便将其总结了下来. 1.为什么静态成员函数.构造函数不能定义为虚函数? 因为静态成员函数是一个大家共享的一个 ...

  9. SpringBoot的第一个例子

    1. 安装springboot的开发IDE,IntelliJ IDEA 2016.3.1这个工具,在IDE的官网上可以下载最新版本.https://www.jetbrains.com/idea/#ch ...

  10. miniui几个常用知识点汇总

    1.在表格中去除系统自带的序列号,请看代码: function allAndBrief(id) { if(id==1){ grid.set({ columns: [ { type: "ind ...