观察者模式深入实践

对于各位看官来说观察者模式都应该不陌生,我也看过一些介绍该模式的文章,但觉得例子中场景都设置的过于简单,未免有些千篇一律。所以,为了更深刻的理解观察者这

个设计模式也就有了下面的这些代码。例子场景的设置是热水壶烧水,水温每次变化时通知注册的观察者,并输出相关水温变化的信息。由调用端触发热水壶的Run()方法来开

启整个烧水和水温变化通知流程。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    //本例子实现的是热水壶烧水,水温变化时通知订阅者,订阅者输出水温变化信息
    #region 主题、观察者、热水壶接口定义
    public interface ISubject
    {
        string SubjectName { get; }
        void Attach(IObserver observer);
        void Detach(IObserver observer);
        void Notify();
    }

    public interface IObserver
    {
        void Update();
    }

    public interface IHotWaterPot : ISubject
    {
        /// <summary>
        /// 当前温度
        /// </summary>
        float CurrentTemp { get; }

        /// <summary>
        /// 温度变化
        /// </summary>
        void TempChanged();

        /// <summary>
        /// 开始烧水
        /// </summary>
        void Run();
    }
    #endregion

    #region 主题与观察者抽象类定义,目的是代码重用
    public abstract class Observer : IObserver
    {
        private ISubject _subject = null;

        public Observer(ISubject subject)
        {
            this._subject = subject;
        }

        public ISubject Subject
        {
            get
            {
                return this._subject;
            }
        }
        public abstract void Update();
    }

    public abstract class Subject : ISubject
    {
        private string _subjectName = string.Empty;
        private IList<IObserver> _observers = new List<IObserver>();

        public Subject(string subjectName)
        {
            this._subjectName = subjectName;
        }

        public void Attach(IObserver observer)
        {
            this._observers.Add(observer);
        }

        public void Detach(IObserver observer)
        {
            if (this._observers.Contains(observer))
            {
                this._observers.Remove(observer);
            }
        }

        public string SubjectName
        {
            get { return this._subjectName; }
        }

        public virtual void Notify() {
            foreach (IObserver item in this._observers)
            {
                item.Update();
            }
        }
    }
    #endregion

    #region 热水壶类定义,实现IHotWaterPot接口,具备了烧水的能力,同时本身也是一个Subject
    public class HotWaterPot : Subject, IHotWaterPot {
        private string _potName = string.Empty;
        private float _currentTemp = 0f;
        public HotWaterPot(string potName,float waterTemp)
            : base("热水壶烧水主题")
        {
            this._potName = potName;
            this._currentTemp = waterTemp;
        }

        public float CurrentTemp
        {
            get {
                return this._currentTemp;
            }
        }

        public void TempChanged()
        {
            base.Notify();
        }

        public void Run()
        {
            while(this._currentTemp < 100f) {
                this._currentTemp += 1;
                this.TempChanged();
                Thread.Sleep(1000);
            }

            Console.WriteLine("水烧开了。。。。");
        }
    }
    #endregion

    #region 热水壶观察者类定义
    public class WaterPotObserver : Observer
    {
        private string _name = string.Empty;
        private IHotWaterPot _waterPort = null;

        public WaterPotObserver(ISubject subject, string name)
            : base(subject)
        {
            this._name = name;
        }

        public override void Update()
        {
            this._waterPort = this.Subject as IHotWaterPot;
            if (this._waterPort != null) {
                Console.WriteLine("Time:{0},观察者:{1},收到主题名为:{2}的消息通知,当前温度是:{3}。。。。"
                    ,DateTime.Now, this._name, this.Subject.SubjectName,this._waterPort.CurrentTemp);
            }
        }
    }
    #endregion

    class Program
    {
        static void Main(string[] args)
        {
            #region 定义subject和observer实例,并进行关联与注册
            ISubject subject = new HotWaterPot("美的点热水壶", 80);
            IObserver observer1 = new WaterPotObserver(subject, "张三");
            IObserver observer2 = new WaterPotObserver(subject, "李四");

            subject.Attach(observer1);
            subject.Attach(observer2);
            #endregion

            //将subject转换为IHotWaterPot类型,并调用Run()方法触发烧水动作
            IHotWaterPot pot = (IHotWaterPot)subject;
            pot.Run();
            Console.ReadKey();
        }
    }
}

最终效果图

时间: 2024-10-06 23:44:09

观察者模式深入实践的相关文章

JavaScript 设计模式入门和框架中的实践 http://www.codeceo.com/article/javascript-design-pattern.html

在编写JS代码的过程中,运用一定的设计模式可以让我们的代码更加优雅.灵活. 下面笔者就结合诸如redux的subscribe.ES6的class.vue里面的$dispatch.jquery里面的on/off来给大家简单介绍下设计模式在这些库.语法和框架中的使用. 设计模式解决的问题 设计模式并不是很玄乎的知识,很多同学在编写JS代码的时候已经在不经意间用了不少设计模式了. 笔者认为把设计模式单独抽象出来探讨,就和算法中抽象出来冒泡.排序一样,是为了描述一种常用的JS pattern. 通过研习

JS设计模式入门和框架中的实践

JS设计模式入门和框架中的实践 在编写JS代码的过程中,运用一定的设计模式可以让我们的代码更加优雅.灵活. 下面笔者就结合诸如redux的subscribe.ES6的class.vue里面的$dispatch.jquery里面的on/off来给大家简单介绍下设计模式在这些库.语法和框架中的使用. 设计模式解决的问题 设计模式并不是很玄乎的知识,很多同学在编写JS代码的时候已经在不经意间用了不少设计模式了. 笔者认为把设计模式单独抽象出来探讨,就和算法中抽象出来冒泡.排序一样,是为了描述一种常用的

android源码大放送(实战开发必备),免费安卓demo源码,例子大全文件详细列表

免费安卓demo源码,例子大全文件详细列表 本列表源码永久免费下载地址:http://www.jiandaima.com/blog/android-demo 卷 yunpan 的文件夹 PATH 列表 卷序列号为 0000-73EC E:. │ jiandaima.com文件列表生成.bat │ 例子大全说明.txt │ 本例子永久更新地址~.url │ 目录列表2016.03.10更新.txt │ ├─前台界面 │ ├─3D标签云卡片热门 │ │ Android TagCloudView云标签

《JavaScript设计模式与开发实践》读书笔记之观察者模式

1.<JavaScript设计模式与开发实践>读书笔记之观察者模式 观察者模式定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知. JavaScript中通常采用事件模型替代传统的观察者模式 1.1 逐步实现观察者模式 以客户看房为例 首先指定谁充当发布者,如售楼处 然后给发布者添加一个缓存列表,用于存放回调函数以便通知订阅者.这里为了让订阅者只接收自己感兴趣的消息,增加一个标识key 最后发布消息时候,发布者遍历缓存列表,依次触发里面存放的订阅者的回

JavaScript设计模式与开发实践 – 观察者模式 http://web.jobbole.com/87809/

概述 观察者模式又叫发布 – 订阅模式(Publish/Subscribe),它定义了一种一对多的关系,让多个观察者对象同时监听某一个目标对象(为了方便理解,以下将观察者对象叫做订阅者,将目标对象叫做发布者).发布者的状态发生变化时就会通知所有的订阅者,使得它们能够自动更新自己. 观察者模式的使用场合就是:当一个对象的改变需要同时改变其它对象,并且它不知道具体有多少对象需要改变的时候,就应该考虑使用观察者模式. 观察者模式的中心思想就是促进松散耦合,一为时间上的解耦,二为对象之间的解耦.让耦合的

JavaScript设计模式与开发实践 – 观察者模式

概述 观察者模式又叫发布 – 订阅模式(Publish/Subscribe),它定义了一种一对多的关系,让多个观察者对象同时监听某一个目标对象(为了方便理解,以下将观察者对象叫做订阅者,将目标对象叫做发布者).发布者的状态发生变化时就会通知所有的订阅者,使得它们能够自动更新自己. 观察者模式的使用场合就是:当一个对象的改变需要同时改变其它对象,并且它不知道具体有多少对象需要改变的时候,就应该考虑使用观察者模式. 观察者模式的中心思想就是促进松散耦合,一为时间上的解耦,二为对象之间的解耦.让耦合的

观察者模式在android 上的最佳实践

在上一篇文章中介绍了介绍了观察者模式的定义和一些基本概念,观察者模式在 android开发中应用还是非常广泛的,例如android按钮事件的监听.广播等等,在任何类似于新闻-订阅的模式下面都可以使用.从某种意义上面来说android有点像JAVA EE的WEB页面,在都需要提供View层用于进行操作,在多个页面之间传递数据发送通知都是一件很麻烦的事情. 在android中从A页面跳转到B页面,然后B页面进行某些操作后需要通知A页面去刷新数据,我们可以通过startActivityForResul

Java中使用Observer接口和Observable类实践Observer观察者模式

在Java中通过Observable类和Observer接口实现了观察者模式.实现Observer接口的对象是观察者,继承Observable的对象是被观察者. 1. 实现观察者模式 实现观察者模式非常简单, [1]创建被观察者类,它继承自java.util.Observable类: [2]创建观察者类,它实现java.util.Observer接口: [3]对于被观察者类, 添加它的观察者: void addObserver(Observer o) addObserver()方法把观察者对象添

IOS设计模式之三(适配器模式,观察者模式)

本文原文请见:http://www.raywenderlich.com/46988/ios-design-patterns. 由 @krq_tiger(http://weibo.com/xmuzyq)翻译,如果你发现有什么错误,请与我联系谢谢. 适配器(Adapter)模式 适配器可以让一些接口不兼容的类一起工作.它包装一个对象然后暴漏一个标准的交互接口. 如果你熟悉适配器设计模式,苹果通过一个稍微不同的方式来实现它-苹果使用了协议的方式来实现.你可能已经熟悉UITableViewDelegat