Design Pattern 设计模式【观察者】
观察者设计模式中存在两种角色: 观察者和被观察者。
最经典的例子就是“猫叫了,老鼠跑了,惊醒了主人。”,这个例子也是我以前去微软面试的时候碰到的一个面试题,当时就是让我设计一下这个过程的实现框架。
在这个例子中,老鼠和主人其实就是观察者,而猫属于被观察者,老鼠和主人观察猫的变化,猫有了动作,老鼠和主人就要做出响应。被观察者,就是这个过程,也可以叫做整个事件的根本原因,亦可以叫直接导火索。
从上面这个例子不难看出,观察者和被观察者的关系通常是n:1,也就是多个多个观察者观察一个被观察者。
这样就给我们一个小小的提示,通过这个提示就可以很容易的找出被观察者。猫,也就是观察的内容,或者观察的被动者,猫所在的角色就是被观察者;老鼠和主人,也就是观察的主体,动作的出发者,他们的角色就是观察者。
当然了,实际的项目中,这个过程肯定没有这么简单,这时候需要我们把大过程,分解成很多的小过程,分层级的找出观察者和被观察者,分层级的使用观察者模式。
下面给出我写的一个完整代码,欢迎大家一起讨论。
完整代码:/Files/virusswb/BeautyCode.DesignPattern.Observer.rar
代码包括两个部分,首先是普通的观察者模式,也就是在被观察者中注册观察者,多个观察者通过一个荣起来管理,然后向观察者发送通知。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApp
{
/// <summary>
/// 观察者接口
/// </summary>
public interface IObserver
{
void Notify(object obj);
}
/// <summary>
/// 被观察者接口
/// </summary>
public interface IObservable
{
void Register(IObserver observer);
void UnRegister(IObserver observer);
void Notify(object obj);
}
class Mouse:IObserver
{
public void Run()
{
}
#region IObserver 成员
public void Notify(object obj)
{
Console.WriteLine(string.Format("{0},老鼠跑了",obj.ToString()));
}
#endregion
}
class Master:IObserver
{
public void Wake()
{
}
#region IObserver 成员
public void Notify(object obj)
{
Console.WriteLine(string.Format("{0},主人被惊醒",obj.ToString()));
}
#endregion
}
class Dog : IObserver
{
#region IObserver 成员
public void Notify(object obj)
{
Console.WriteLine(string.Format("{0},狗拿耗子,多管闲事", obj.ToString()));
}
#endregion
}
class Cat:IObservable
{
private Dictionary<IObserver, IObserver> _observerContainer = new Dictionary<IObserver, IObserver>();
public void Cry()
{
Console.WriteLine("猫叫了");
}
#region IObservable 成员
public void Register(IObserver observer)
{
if (_observerContainer.ContainsKey(observer))
_observerContainer.Remove(observer);
_observerContainer.Add(observer,observer );
}
public void UnRegister(IObserver observer)
{
if (_observerContainer.ContainsKey(observer))
_observerContainer.Remove(observer);
}
public void Notify(object obj)
{
foreach (IObserver o in _observerContainer.Keys)
{
_observerContainer[o].Notify(obj);
}
}
#endregion
}
}
第二种是在.NET 框架的基础之上的观察者,也就是事件委托类型的观察者,不需要在被观察者中注册观察者,降低了观察者和被观察者的耦合度。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApp
{
public delegate void ObserverEventHandler(object sender, EventObjectArgs e);
/// <summary>
/// 被观察者
/// </summary>
public interface IEventObserable
{
event ObserverEventHandler ObserverEvent;
void OnObserverEvent(EventObjectArgs e);
void RaiseObserverMethod();
}
/// <summary>
/// 观察者
/// </summary>
public interface IEventObserver
{
}
public class EventObjectArgs : EventArgs
{
private string _message;
public string Message
{
get { return _message; }
}
public EventObjectArgs()
{
}
public EventObjectArgs(string message)
{
this._message = message;
}
}
class EventCat : IEventObserable
{
#region IEventObserable 成员
public event ObserverEventHandler ObserverEvent;
public void OnObserverEvent(EventObjectArgs e)
{
if (null != ObserverEvent)
{
ObserverEvent(this, e);
}
}
public void RaiseObserverMethod()
{
Console.WriteLine("猫叫了");
OnObserverEvent(new EventObjectArgs("猫叫了"));
}
#endregion
}
class EventMouse : IEventObserver
{
public EventMouse() { }
public EventMouse(IEventObserable observable)
{
observable.ObserverEvent += new ObserverEventHandler(observable_ObserverEvent);
}
public void observable_ObserverEvent(object sender, EventObjectArgs e)
{
Console.WriteLine(string.Format("{0},所有老鼠被吓跑了", e.Message));
}
}
class EventDog : IEventObserver
{
public EventDog(IEventObserable observable)
{
observable.ObserverEvent += new ObserverEventHandler(observable_ObserverEvent);
}
public void observable_ObserverEvent(object sender, EventObjectArgs e)
{
Console.WriteLine(string.Format("{0},所有老鼠被吓跑了,但是狗拿耗子多管闲事", e.Message));
}
}
class EventMaster : IEventObserver
{
public EventMaster(IEventObserable observable)
{
observable.ObserverEvent += new ObserverEventHandler(observable_ObserverEvent);
}
public void observable_ObserverEvent(object sender, EventObjectArgs e)
{
Console.WriteLine(string.Format("{0},所有老鼠被吓跑了,但是狗拿耗子多管闲事,主人生气了,要打死这些动物", e.Message));
}
}
}
下面是他们的调用代码,是一个Console应用程序
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApp
{
public class Model
{
public object ModelState { get; set; }
}
public class Command
{
public void DoCommand()
{ }
}
public class Selection : EventArgs
{
public object State { get; set; }
}
public class Interactor
{
public delegate void AddItemEventHandler(object sender, Selection e);
public event AddItemEventHandler ItemAdded;
protected virtual void OnItemAdded(Selection e)
{
if (ItemAdded != null)
ItemAdded(this, e);
}
public void AddItem(object value)
{
Selection selection = new Selection() { State = value };
OnItemAdded(selection);
}
}
public class Presenter
{
private readonly Command command;
private readonly Interactor interactor;
private readonly Model model;
private readonly View view;
public Presenter(Interactor interactor)
{
this.command = new Command();
this.model = new Model();
this.view = new View();
this.interactor = interactor;
this.interactor.ItemAdded += new Interactor.AddItemEventHandler(interactor_ItemAdded);
}
void interactor_ItemAdded(object sender, Selection e)
{
this.command.DoCommand();
this.model.ModelState = e.State;
this.view.Update ("Processed " + e.State);
}
}
public class View
{
private object ViewState;
static void Main(string[] args)
{
#region Model View Presenter Design Pattern
Interactor interactor = new Interactor();
Presenter presenter = new Presenter(interactor);
interactor.AddItem("Message from the UI");
#endregion
#region 普通观察着模式
Mouse mouse = new Mouse();
Master master = new Master();
Dog dog = new Dog();
Cat cat = new Cat();
cat.Register(mouse);
cat.Register(master);
cat.Register(dog);
cat.Cry();
cat.Notify("猫叫了");
cat.UnRegister(mouse);
cat.UnRegister(master);
cat.UnRegister(dog );
#endregion
#region 基于事件和委托的观察者模式
EventCat eventCat = new EventCat();
EventMouse eventMouse = new EventMouse(eventCat);
EventDog eventDog = new EventDog(eventCat);
EventMaster eventMaster = new EventMaster(eventCat);
eventCat.RaiseObserverMethod();
#endregion
Console.ReadLine();
}
public void Update(object state)
{
ViewState = state;
}
}
}
转载于:https://www.cnblogs.com/virusswb/archive/2009/11/26/1611046.html
Design Pattern 设计模式【观察者】相关推荐
- DP什么意思 design pattern 设计模式 面向对象 概念大全
DP design pattern 大话设计模式 中的DP 是设计模式的意思 设计模式的书 ,最经典最原始的就是 GOF 的<设计模式>了. 设计模式的书基本上大多是以这 20 多个模 ...
- 设计模式(Design Pattern)详细整理(含思维导图)
设计模式(Design Pattern) 设计模式(Design pattern)代表了最佳的实践,是软件开发人员在软件开发过程中面临的一般问题的解决方案.这些解决方案是众多软件开发人员经过相当长的一 ...
- 设计模式(Design Pattern)
简介 设计模式(Design Pattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用.设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案.这些解决方案是众多软件开发人 ...
- 说说设计模式~大话目录(Design Pattern)
回到占占推荐博客索引 设计模式(Design pattern)与其它知识不同,它没有华丽的外表,没有吸引人的工具去实现,它是一种心法,一种内功,如果你希望在软件开发领域有一种新的突破,一个质的飞越,那 ...
- 初读设计模式-----《design pattern explained》读后感
从网上淘来了一本<design pattern explained>,用了半个月的时间细细的读完了这本书. 本打算单单的从技术角度进行总结的,但是却全然没有头绪.说说自己的粗浅的感悟吧.. ...
- 巧用代理设计模式(Proxy Design Pattern)改善前端图片加载体验
这篇文章介绍一种使用代理设计模式(Proxy Design Pattern)的方法来改善您的前端应用里图片加载的体验. 假设我们的应用里需要显示一张尺寸很大的图片,位于远端服务器.我们用一些前端框架的 ...
- 设计模式(Design pattern—
设计模式(Design Pattern)系列视频教程(附PDF文档) 设计模式(Design pattern-使用设计模式是为了可重用代码.让代码更容易被他人理解.保证代码可靠性. 毫无疑问,设计模式 ...
- C# 版本设计模式(Design Pattern)(转)
C# 版本设计模式(Design Pattern)---------------总序 今天在写代码的时候,突然想到了一个非常有趣的问题,就是非常经典的一个问题:猫叫了,老师跑了,主人醒了. 也不知道自 ...
- 几种常用的设计模式 (Design Pattern)
文章目录 设计模式(Design Pattern) 一.设计模式的分类 1. 基础型模式 (Fundamental Pattern) 2. 创建型模式 (Creational Pattern) 3. ...
最新文章
- 在Ubuntu 12.04 桌面上设置启动器(快捷方式)
- LeetCode 375. Guess Number Higher or Lower II
- myeclipse 删除历史工作空间记录
- less 函数_Python中的函数式编程教程,学会用一行代码搞定所有内容
- 将您的基于 Accelerator 的 SAP Commerce Cloud Storefront 迁移到 Spartacus Storefront
- 什么是单工、半双工和双工通信?有哪些实际应用的例子
- leadshop开源商城系统
- 最全HTML与CSS基础总结,不进来看看吗?
- python接口自动化(四十三)-公共模块 pymysql 连接mysql数据库(单独说明)
- flex4自定义皮肤
- tongweb自动部署_用apache配置TongWeb集群
- java 操作 led_Java中使用反射机制操作LED
- java天津与深圳,国内最可惜的城市:GDP曾是深圳的38倍,如今GDP被反超万亿!
- 解读BLM业务领先模型中的业务设计
- 基于知识图谱+机器学习,搭建风控模型的项目落地
- macOS安装homebrew与更新gcc
- PHP八字强弱计算,八字强弱计算法
- php 去掉转义引号的反斜杠,PHP去掉json字符串中的反斜杠\及去掉双引号前的反斜杠...
- “浅薄”绝不该是中国程序员的性格特征
- 超融合架构hci之路坦力nutanix之硬件规格及软件配置之一
热门文章
- 机器学习算法与Python实践之逻辑回归(Logistic Regression)
- postman测试websocket_还在手工写接口测试文档,已经out了
- java中常见英文单词_JAVA中常见的英文单词
- 华为鸿蒙描述文件,华为鸿蒙HarmonyOS Beta3 2.0.0.110
- 1e-5 java_内功心法 -- java.util.LinkedListE (5)
- Ubuntu开发问题集
- 纯新手DSP编程--5.22-总结
- c语言链表复数,[蓝桥杯][算法提高VIP]复数求和-链表初学者看过来(C语言代码)...
- jsp人事管理系统_人事管理系统(论文+源码)(SSH+MYSQL+JSP+HTML5)
- 将汉字转换成笔画代码_0基础学习五笔输入法之汉字的拆分