而被打招呼的对象称为观望者,而被文告的对象称为观望者

形式动机
澳门威尼斯人网址 1 澳门威尼斯人网址 2
树立一种对象与指标之间的依赖关系,3个对象发生改变时将活动文告任何对象,别的对象将相应做出反应。在此,产生变动的靶子称为观看对象,而被文告的对象称为观察者,叁个考察对象能够对应四个阅览者,而且这么些观看者之间一向不互动关系,能够依照供给增删阅览者,使得系统更便于扩展,那正是观看者情势的情势动机。

格局动机
澳门威尼斯人网址 3 澳门威尼斯人网址 4
建立一种对象与目的之间的依靠关系,贰个对象爆发变动时将电动公告其余对象,其余对象将相应做出反应。在此,产生改变的靶子称为观看对象,而被布告的对象称为观看者,二个观望对象能够对应四个观望者,而且那个观察者之间平素不互动调换,能够依照供给增加和删除观看者,使得系统更便于扩展,那正是阅览者情势的情势动机。

前些天咱们来上学一种行为型形式,阅览者情势(Observer Pattern)。

格局定义
观望者格局(Observer
帕特tern):定义对象间的一种一对多注重关系,使得每当叁个目的情状产生转移时,其相关依赖对象皆得到布告并被自动更新。观望者格局又称为发布-订阅(Publish/Subscribe)方式、模型-视图(Model/View)形式、源-监听器(Source/Listener)方式或从属者(Dependents)方式。观望者格局是一种对象行为型形式。
Observer Pattern: Define a one-to-many dependency between objects so
that when one object changes state, all its dependents are notified and
updated automatically.
Frequency of use: high
UML图
澳门威尼斯人网址 5

情势定义
观望者格局(Observer
Pattern):定义对象间的一种一对多依赖关系,使得每当1个对象意况产生变动时,其毛将安附毛将安附正视对象皆获得关照并被自动更新。观望者方式又叫做公布-订阅(Publish/Subscribe)方式、模型-视图(Model/View)情势、源-监听器(Source/Listener)形式或从属者(Dependents)形式。观察者形式是一种对象行为型情势。
Observer Pattern: Define a one-to-many dependency between objects so
that when one object changes state, all its dependents are notified and
updated automatically.
Frequency of use: high
UML图
澳门威尼斯人网址 6

形式定义

概念对象间的一种一对多重视关系,使得每当3个对象意况发生变更时,其有关信赖对象皆获得文告并被自动更新。观望者格局又称作发表-订阅(Publish-Subscribe)方式、模型-视图(Model-View)方式、源-监听器(Source-Listener)方式或从属者(Dependents)形式。

形式社团
观看者形式涵盖如下剧中人物:
Subject: 目标
ConcreteSubject: 具体目的
Observer: 观察者
ConcreteObserver: 具体观望者

方式结构
观察者格局涵盖如下剧中人物:
Subject: 目标
ConcreteSubject: 具体对象
Observer: 观察者
ConcreteObserver: 具体阅览者

格局组织

观望者情势涵盖如下脚色:

**Subject: ** 目标
**ConcreteSubject: ** 具体目的
**Observer: ** 观察者
**ConcreteObserver: ** 具体阅览者

形式分析
观望者格局描述了怎么着建立目的与对象时期的信赖关系,如何组织满意那种供给的系统。
这一方式中的关键指标是考察对象和观看者,一个对象可以有私自数指标与之相信赖的观望者,一旦指标的景观爆发变动,全体的观看者都将收获关照。
作为对这些布告的响应,每种观察者都将即时更新本人的状态,以与对象状态同步,那种互相也称之为宣布-订阅(publish-subscribe)。指标是通报的公布者,它发出布告时并不要求知道哪个人是它的观望者,能够有专断数指标观望者订阅它并吸收布告。

情势分析
观察者格局描述了怎么建立目的与对象时期的信赖关系,怎样组织满足那种必要的系统。
这一情势中的关键目的是洞察对象和观望者,3个对象能够有专断数指标与之相正视的观看者,一旦指标的动静发生改变,全部的观看者都将得到关照。
作为对这些公告的响应,每一种观看者都将即时更新自个儿的事态,以与对象状态同步,那种相互也称为公布-订阅(publish-subscribe)。指标是通报的发表者,它发生文告时并不须求知道何人是它的观望者,能够有私行数指标观望者订阅它并接收文告。

UML图

澳门威尼斯人网址 7

方式实例与分析
COO娘回来?小编不驾驭!—观看者方式示例代码
系统布局
澳门威尼斯人网址 8
Subject: 目标 ISubject.cs

方式实例与分析
业主回来?笔者不清楚!—观望者方式示例代码
系统布局
澳门威尼斯人网址 9
Subject: 目标 ISubject.cs

代码实现

namespace ObserverPattern
{
    interface ISubject
    {
        void Attach(Observer observer);
        void Detach(Observer observer);
        void Notify();
        string SubjectState
        {
            get;
            set;
        }
    }
}
namespace ObserverPattern
{
    interface ISubject
    {
        void Attach(Observer observer);
        void Detach(Observer observer);
        void Notify();
        string SubjectState
        {
            get;
            set;
        }
    }
}

Subject.java

/**
 * 抽象目标者
 */
public abstract class Subject {

    // 保存注册的观察者对象
    private List<Observer> mObservers = new ArrayList<>();

    //注册观察者对象
    public void attach(Observer observer) {
        mObservers.add(observer);
        System.out.println("Attached an observer");
    }

    //注销观察者对象
    public void detach(Observer observer) {
        mObservers.remove(observer);
    }

    // 通知所有注册的观察者对象
    public void nodifyObservers(String newState) {
        for (Observer observer : mObservers) {
            observer.update(newState);
        }
    }
}

ConcreteSubject: 具体对象 Secretary.cs

ConcreteSubject: 具体对象 Secretary.cs

ConcreteSubject.java

/**
 * 具体目标者
 */
public class ConcreteSubject extends Subject {

    private String state;

    public String getState() {
        return state;
    }

    public void change(String newState) {
        state = newState;
        System.out.println("ConcreteSubject State:" + state);

        //状态发生改变,通知观察者
        nodifyObservers(state);
    }
}
using System.Collections.Generic;

namespace ObserverPattern
{
    //前台秘书类
    class Secretary : ISubject
    {
        //同事列表
        private IList<Observer> observers = new List<Observer>();
        private string action;
        //增加
        public void Attach(Observer observer)
        {
            observers.Add(observer);
        }
        //减少
        public void Detach(Observer observer)
        {
            observers.Remove(observer);
        }
        //通知
        public void Notify()
        {
            foreach (Observer o in observers)
            {
                o.Update();
            }
        }
        //前台状态
        public string SubjectState
        {
            get { return action; }
            set { action = value; }
        }
    }
}
using System.Collections.Generic;

namespace ObserverPattern
{
    //前台秘书类
    class Secretary : ISubject
    {
        //同事列表
        private IList<Observer> observers = new List<Observer>();
        private string action;
        //增加
        public void Attach(Observer observer)
        {
            observers.Add(observer);
        }
        //减少
        public void Detach(Observer observer)
        {
            observers.Remove(observer);
        }
        //通知
        public void Notify()
        {
            foreach (Observer o in observers)
            {
                o.Update();
            }
        }
        //前台状态
        public string SubjectState
        {
            get { return action; }
            set { action = value; }
        }
    }
}

Observer.java

/**
 * 观察者
 */
public interface Observer {

    void update(String state);
}

Boss.cs

Boss.cs

ConcreteObserver.java

/**
 *具体观察者
 */
public class ConcreteObserver implements Observer {

    // 观察者状态
    private String observerState;

    @Override
    public void update(String state) {
        // 更新观察者状态,让它与目标状态一致
        observerState = state;
        System.out.println("ConcreteObserver State :" + observerState);
    }
}
using System.Collections.Generic;

namespace ObserverPattern
{
    class Boss : ISubject
    {
        //同事列表
        private IList<Observer> observers = new List<Observer>();
        private string action;
        //增加
        public void Attach(Observer observer)
        {
            observers.Add(observer);
        }
        //减少
        public void Detach(Observer observer)
        {
            observers.Remove(observer);
        }
        //通知
        public void Notify()
        {
            foreach (Observer o in observers)
            {
                o.Update();
            }
        }
        //前台状态
        public string SubjectState
        {
            get { return action; }
            set { action = value; }
        }
    }
}
using System.Collections.Generic;

namespace ObserverPattern
{
    class Boss : ISubject
    {
        //同事列表
        private IList<Observer> observers = new List<Observer>();
        private string action;
        //增加
        public void Attach(Observer observer)
        {
            observers.Add(observer);
        }
        //减少
        public void Detach(Observer observer)
        {
            observers.Remove(observer);
        }
        //通知
        public void Notify()
        {
            foreach (Observer o in observers)
            {
                o.Update();
            }
        }
        //前台状态
        public string SubjectState
        {
            get { return action; }
            set { action = value; }
        }
    }
}

测试类

public class MyClass {

    public static void main(String[] args) {
        // 创建目标对象
        ConcreteSubject concreteSubject = new ConcreteSubject();
        // 创建观察者对象
        Observer observer = new ConcreteObserver();
        // 将观察者对象注册到目标对象上
        concreteSubject.attach(observer);
        // 改变目标对象的状态
        concreteSubject.change("I change");
    }
}

Observer: 观察者 Observer.cs

Observer: 观察者 Observer.cs

运作结果

澳门威尼斯人网址 10

namespace ObserverPattern
{
    abstract class Observer
    {
        protected string name;
        protected ISubject sub;
        public Observer(string name, ISubject sub)
        {
            this.name = name;
            this.sub = sub;
        }
        public abstract void Update();
    }
}
namespace ObserverPattern
{
    abstract class Observer
    {
        protected string name;
        protected ISubject sub;
        public Observer(string name, ISubject sub)
        {
            this.name = name;
            this.sub = sub;
        }
        public abstract void Update();
    }
}

情势分析

  • 观看者情势描述了什么建立指标与对象时期的依赖关系,如何协会满足那种要求的系统。

  • 这一方式中的关键指标是考察对象和阅览者,2个对象能够有私自数目标与之相注重的观望者,一旦指标的景色产生改变,全数的观看者都将赢得关照。

  • 用作对这几个布告的响应,每一种观看者都将即时更新本人的境况,以与对象状态同步,那种互相也叫做公布-订阅(publish-subscribe)。指标是打招呼的发表者,它爆发通知时并不须要知道何人是它的观看者,能够有专擅数指标观望者订阅它并接收通

ConcreteObserver: 具体观看者 StockObserver.cs

ConcreteObserver: 具体旁观者 StockObserver.cs

考察形式的独到之处

  • 观看者情势能够兑现表示层和数量逻辑层的离别,并定义了安宁的消息更新传递机制,抽象了履新接口,使得能够有丰裕多采分歧的表示层作为具体观望者剧中人物。

  • 旁观者方式在观望对象和观察者之间建立二个华而不实的耦合。

  • 观看者格局支持广播通讯。

  • 观察者格局符合“开闭原则”的渴求。

using System;

namespace ObserverPattern
{
    //看股票的同事
    class StockObserver : Observer
    {
        public StockObserver(string name, ISubject sub)
            : base(name, sub)
        {
        }
        public override void Update()
        {
            Console.WriteLine("{0} {1} 关闭股票行情,继续工作!", sub.SubjectState, name);
        }
    }
}
using System;

namespace ObserverPattern
{
    //看股票的同事
    class StockObserver : Observer
    {
        public StockObserver(string name, ISubject sub)
            : base(name, sub)
        {
        }
        public override void Update()
        {
            Console.WriteLine("{0} {1} 关闭股票行情,继续工作!", sub.SubjectState, name);
        }
    }
}

着眼情势的后天不足

  • 假若一个考察对象对象有许多一向和直接的观看者的话,将拥有的观看者都通报加入花费很多时间。

  • 一经在观望者和着眼对象以内有轮重放重的话,观望对象会触发它们中间实行巡回调用,恐怕导致系统崩溃。

  • 观看者情势尚未对应的编写制定让观望者知道所观看标靶子对象是怎么发生变化的,而仅仅只是知道观看对象发出了变动。

本博客同步揭橥在
http://hjxandhmr.github.io/2016/06/08/DesignPattern-Observer/

参考
http://design-patterns.readthedocs.io/zh\_CN/latest/behavioral\_patterns/observer.html

NBAObserver.cs

NBAObserver.cs

using System;

namespace ObserverPattern
{
    class NBAObserver : Observer
    {
        public NBAObserver(string name, ISubject sub)
            : base(name, sub)
        {
        }
        public override void Update()
        {
            Console.WriteLine("{0} {1} 关闭NBA直播,继续工作!", sub.SubjectState, name);
        }
    }
}
using System;

namespace ObserverPattern
{
    class NBAObserver : Observer
    {
        public NBAObserver(string name, ISubject sub)
            : base(name, sub)
        {
        }
        public override void Update()
        {
            Console.WriteLine("{0} {1} 关闭NBA直播,继续工作!", sub.SubjectState, name);
        }
    }
}

Client:客户类

Client:客户类

using System;

namespace ObserverPattern
{
    class Program
    {
        static void Main(string[] args)
        {
            Secretary secretary = new Secretary();
            StockObserver stockObserver1 = new StockObserver("张三", secretary);
            NBAObserver stockObserver2 = new NBAObserver("李四", secretary);
            //前台记下了两位同事
            secretary.Attach(stockObserver1);
            secretary.Attach(stockObserver2);
            //发现老板回来
            secretary.SubjectState = "老板回来了";
            //通知两个同事
            secretary.Notify();
            Console.Read();
        }
    }
}
using System;

namespace ObserverPattern
{
    class Program
    {
        static void Main(string[] args)
        {
            Secretary secretary = new Secretary();
            StockObserver stockObserver1 = new StockObserver("张三", secretary);
            NBAObserver stockObserver2 = new NBAObserver("李四", secretary);
            //前台记下了两位同事
            secretary.Attach(stockObserver1);
            secretary.Attach(stockObserver2);
            //发现老板回来
            secretary.SubjectState = "老板回来了";
            //通知两个同事
            secretary.Notify();
            Console.Read();
        }
    }
}

格局优缺点
阅览者形式的亮点

观察者格局能够达成表示层和数目逻辑层的分手,并定义了稳定的消息更新传递机制,抽象了更新接口,使得能够有各类各种分裂的表示层作为具体观察者剧中人物。
 观望者方式在考察对象和观察者之间确立贰个虚幻的耦合。
 观看者方式援助广播通信。
 观看者格局符合“开闭原则”的渴求。

方式优缺点
观望者格局的独到之处

观望者情势能够兑现表示层和数量逻辑层的诀别,并定义了安居的新闻更新传递机制,抽象了履新接口,使得能够有丰富多彩差异的表示层作为具体观察者剧中人物。
 旁观者格局在考察对象和观望者之间建立2个架空的耦合。
 阅览者情势帮忙广播通讯。
 观望者情势符合“开闭原则”的渴求。

观望者情势的毛病

若是1个观测对象对象有诸多直接和直接的观察者的话,将具备的观看者都通报加入开销很多年华。

假如在观看者和考察对象以内有轮回放重的话,观察对象会触发它们之间展开巡回调用,可能导致系统崩溃。
澳门威尼斯人网址,
旁观者情势尚未对应的编写制定让观看者知道所阅览的靶子对象是怎么发生变化的,而仅仅只是知佛殿望对象发出了转移。

阅览者格局的老毛病

假如3个考察对象对象有广大学一年级直和直接的观看者的话,将享有的阅览者都通报参与开销很多小时。

借使在观察者和着眼对象之间有轮回注重的话,观察对象会触发它们中间展开巡回调用,恐怕导致系统崩溃。

观看者格局尚未相应的编写制定让观察者知道所观看的目的对象是怎么爆发变化的,而仅仅只是知古寺望对象发出了扭转。

方式适用条件
在偏下意况下得以应用旁观者格局:

贰个抽象模型有多个地点,当中3个地点注重于另1个方面。将那个方面封装在独立的指标中使它们得以独家独立地改成和复用。

二个对象的改动将招致别的1个或八个指标也产生变动,而不知情具体有个别许对象将产生转移,能够降低对象时期的耦合度。
 1个目的必须通报任何对象,而并不知道那个指标是何人。

必要在系统中创立多个触发链,A对象的行为将震慑B对象,B对象的作为将影响C对象……,能够利用观看者情势开创一种链式触发机制。

情势适用条件
在偏下情形下得以采用阅览者情势:

1个虚无模型有四个地点,在那之中1个方面信赖于另2个方面。将这么些地点封装在独立的指标中使它们能够分级独立地改成和复用。

三个对象的更动将造成其余二个或多少个目的也发生改变,而不知晓具体有微微对象将爆发变更,能够下降对象时期的耦合度。
 一个目的必须通报别的对象,而并不知道那个目的是何人。

须求在系统中开创3个触发链,A对象的作为将震慑B对象,B对象的行事将影响C对象……,能够使用阅览者格局创制一种链式触发机制。

【申明与感激】
本文,站在诸多大汉的双肩上,借鉴和引用了比比皆是客人拥有版权的文章或撰文,在此,对前人们的进献致谢。并还要宣布引用的始末、原著者或缘于(一些来源于网络的剧情自身不大概追述本源,深表遗憾)。

【申明与谢谢】
正文,站在重重高个子的肩头上,借鉴和引用了诸多外人拥有版权的创作或撰文,在此,对前人们的贡献致谢。并同时表露引用的始末、原来的著小编或出自(一些出自网络的内容本身不可能追述本源,深表遗憾)。

【参考文献】
《设计方式—可复用面向对象软件的基础》小编: [美] 埃里克h Gamma / RichardHelm / 拉尔夫 Johnson / 约翰 Vlissides 译者: 李英军 / 马晓星 / 蔡敏 /
刘建中 等 机械工业出版社
《重构—改正既有代码的安排》小编: Martin Fowler译者:候捷
中国电力出版社
《敏捷软件开发—原则、情势与执行》笔者: 罗Bert C. 马丁 北大大学出版社
《程序员修炼之道—从小工到大家》小编: Andrew Hunt / 戴维 托马斯电子工业出版社
《Head First 设计格局》笔者: Freeman 译者: O’Reilly Taiwan公司中华夏族民共和国电力出版社
《设计形式之禅》 小编: 秦小波 机械工业出版社
MSDN WebCast 《C#面向对象设计格局纵横谈》 教授:李建忠
刘伟同志. 设计情势. 东方之珠:浙大东军大学出版社, 二〇一二.
刘伟同志. 设计情势实验和培养和练习教程. 香江:哈工业余大学学东军事和政院学出版社, 二〇一一.
《大话设计形式》 作者: 程杰 北大东军事和政院学出版社
《C#图解教程》小编: 索Liss 译者: 苏林 / 朱晔 人民邮政和邮电通讯出版社
《你必须理解的.NET》作者: 王涛
《项目中的.NET》小编: 李天平 电子工业出版社
《Microsoft .NET公司级应用架构划设想计》小编: (美)埃斯波西托等创作 译者:
陈黎夫
http://www.dofactory.com/Patterns/Patterns.aspx .NET Design Patterns
http://www.cnblogs.com/zhenyulu 博客作者:吕震宇
http://www.cnblogs.com/terrylee 博客笔者:李会军
http://www.cnblogs.com/anlyren/ 博客作者:anlyren
http://www.cnblogs.com/idior 博客作者:idior
http://www.cnblogs.com/allenlooplee 博客作者:Allen lee
http://blog.csdn.net/ai92 博客笔者:ai92
http://www.cnblogs.com/umlonline/ 博客笔者:张传波
http://www.cnblogs.com/lovecherry/ 博客小编:Love切莉

【参考文献】
《设计方式—可复用面向对象软件的功底》小编: [美] 埃里克h Gamma / 理查德Helm / 拉尔夫 Johnson / John Vlissides 译者: 李英军 / 马晓星 / 蔡敏 /
刘建中 等 机械工业出版社
《重构—革新既有代码的统筹》小编: Martin Fowler译者:候捷
中中原人民共和国电力出版社
《敏捷软件开发—原则、格局与实践》小编: 罗Bert C. Martin 南开东军大学出版社
《程序员修炼之道—从小工到学者》作者: Andrew Hunt / 大卫 Thomas电子工业出版社
《Head First 设计情势》作者: Freeman 译者: O’Reilly Taiwan公司中中原人民共和国电力出版社
《设计格局之禅》 作者: 秦小波 机械工业出版社
MSDN WebCast 《C#面向对象设计格局纵横谈》 教师:李建忠
刘伟(Liu-Wei). 设计格局. 时尚之都:武大东军事和政院学出版社, 贰零壹壹.
刘伟先生. 设计格局实验和培养和训练教程. 东京:清华大学出版社, 二〇一二.
《大话设计格局》 作者: 程杰 哈工业余大学学大学出版社
《C#图解教程》小编: 索Liss 译者: 苏林 / 朱晔 人民邮政和邮电通讯出版社
《你必须掌握的.NET》作者: 王涛
《项目中的.NET》小编: 李天平 电子工业出版社
《Microsoft .NET集团级应用框架结构划设想计》笔者: (美)埃斯波西托等小说 译者:
陈黎夫
http://www.dofactory.com/Patterns/Patterns.aspx .NET Design Patterns
http://www.cnblogs.com/zhenyulu 博客作者:吕震宇
http://www.cnblogs.com/terrylee 博客笔者:李会军
http://www.cnblogs.com/anlyren/ 博客我:anlyren
http://www.cnblogs.com/idior 博客小编:idior
http://www.cnblogs.com/allenlooplee 博客我:Allen lee
http://blog.csdn.net/ai92 博客小编:ai92
http://www.cnblogs.com/umlonline/ 博客我:张传波
http://www.cnblogs.com/lovecherry/ 博客笔者:LoveCherry

相关文章