那便是观看者形式的形式动机,那正是观察者情势的形式动机

格局动机
图片 1 图片 2
创建一种对象与对象时期的注重关系,三个对象发生改变时将机关布告其余对象,其余对象将相应做出反应。在此,爆发变动的靶子称为观看对象,而被布告的对象称为观察者,3个观测对象能够对应两个旁观者,而且这一个观望者之间平素不互动关联,能够根据必要增删观望者,使得系统更便于增加,那正是观望者方式的格局动机。

形式动机
图片 3 图片 4
建立一种对象与对象之间的看重性关系,2个目的发生变动时将自动通告其余对象,其他对象将相应做出反应。在此,产生改变的靶子称为观看对象,而被打招呼的对象称为观看者,一个着眼对象可以对应八个观察者,而且这一个观察者之间从未互动调换,可以依照供给追加和删除观看者,使得系统更易于扩大,那就是观看者情势的方式动机。

明日我们来读书一种行为型格局,观察者格局(Observer Pattern)。

形式定义
观看者方式(Observer
Pattern):定义对象间的一种一对多信赖关系,使得每当3个对象景况发生变动时,其息息相关信赖对象皆获得关照并被自动更新。观看者形式又叫做发表-订阅(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):定义对象间的一种一对多信赖关系,使得每当一个对象情形发生变更时,其有关正视对象皆得到关照并被自动更新。观望者格局又称作发表-订阅(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

方式定义

概念对象间的一种一对多重视关系,使得每当一个对象情状发生变动时,其连带依赖对象皆获得关照并被自动更新。阅览者方式又叫做公布-订阅(Publish-Subscribe)方式、模型-视图(Model-View)形式、源-监听器(Source-Listener)格局或从属者(Dependents)情势。

格局组织
观望者情势涵盖如下剧中人物:
Subject: 目标
ConcreteSubject: 具体目的
Observer: 观察者
ConcreteObserver: 具体观望者

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

情势组织

观察者方式涵盖如下剧中人物:

**Subject: ** 目标
**ConcreteSubject: ** 具体指标
**Observer: ** 观察者
**ConcreteObserver: ** 具体观望者

格局分析
观望者形式描述了怎么着树立目的与指标之间的信赖性关系,如何协会满意这种须要的系统。
这一方式中的关键目的是观望对象和观望者,二个对象能够有自由数目标与之相依赖的阅览者,一旦指标的场馆发生变更,全部的观察者都将获取公告。
作为对那个公告的响应,每种观察者都将即时更新本身的事态,以与对象状态同步,那种相互也称之为宣布-订阅(publish-subscribe)。指标是通报的发表者,它发出通告时并不需求知道哪个人是它的阅览者,能够有专断数目标观望者订阅它并收受布告。

格局分析
阅览者格局描述了什么样建立目的与对象时期的依赖关系,怎样组织满意那种要求的系统。
这一方式中的关键指标是考察对象和观看者,二个指标能够有私自数指标与之相依赖的观看者,一旦目的的情景发生变更,全部的观望者都将获得关照。
用作对这几个布告的响应,每种观望者都将即时更新自身的景况,以与指标状态同步,那种相互也称为公布-订阅(publish-subscribe)。目的是通报的发表者,它发出通报时并不要求知道哪个人是它的观看者,可以有自由数指标观望者订阅它并吸纳公告。

UML图

图片 7

方式实例与分析
高管回来?笔者不掌握!—观望者情势示例代码
系统布局
图片 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

考察情势的长处

  • 观察者方式能够完结表示层和数据逻辑层的诀别,并定义了平静的新闻更新传递机制,抽象了更新接口,使得能够有丰裕多彩不一致的表示层作为具体观察者角色。

  • 观望者格局在考察对象和观看者之间建立3个浮泛的耦合。

  • 观看者情势帮忙广播通讯。

  • 阅览者情势符合“开闭原则”的供给。

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();
        }
    }
}

格局优缺点
观望者形式的帮助和益处

观看者形式能够兑现表示层和数码逻辑层的离别,并定义了稳定的音讯更新传递机制,抽象了履新接口,使得能够有各样各个差其他表示层作为具体观望者剧中人物。
 观望者形式在阅览对象和观望者之间创立三个浮泛的耦合。
 阅览者格局帮忙广播通讯。
 观望者形式符合“开闭原则”的渴求。

方式优缺点
观察者格局的优点

阅览者格局能够实现表示层和数据逻辑层的分开,并定义了平安的新闻更新传递机制,抽象了更新接口,使得能够有各式种种区其余表示层作为具体观望者角色。
 观望者方式在观望对象和观望者之间创制3个浮泛的耦合。
 观望者方式援助广播通讯。
 观看者格局符合“开闭原则”的渴求。

观望者形式的通病

假诺二个观测对象对象有过多一贯和直接的阅览者的话,将有着的观望者都通报参预费用很多光阴。

假若在观望者和考察对象之内有轮重播重的话,观看对象会触发它们之间开始展览巡回调用,大概导致系统崩溃。

观望者形式尚未对号入座的体制让观察者知道所观望的对象对象是怎么爆发变化的,而仅仅只是知古庙看对象发出了转移。

观看者形式的缺点

假如1个观看对象对象有无数直接和间接的观察者的话,将持有的观看者都通报参预开销很多年华。

若是在观看者和考察对象以内有轮回正视的话,阅览对象会触发它们之间展开巡回调用,或许导致系统崩溃。

观望者格局尚未对应的体制让阅览者知道所阅览标靶子对象是怎么产生变化的,而仅仅只是知道观望对象发出了扭转。

形式适用条件
在以下情况下能够动用观看者形式:

叁个华而不实模型有四个方面,其中1个方面注重于另多个方面。将那一个地点封装在独立的指标中使它们可以独家独立地改成和复用。

贰个目标的变更将招致其余贰个或四个对象也发出变动,而不知情具体有多少对象将发出改变,能够下跌对象时期的耦合度。
 二个目的必须通报任何对象,而并不知道那一个目的是哪个人。

必要在系统中开创二个触发链,A对象的行事将影响B对象,B对象的表现将影响C对象……,可以动用阅览者形式开创一种链式触发机制。

形式适用条件
在以下处境下得以选用阅览者格局:

贰个华而不实模型有五个地方,个中多个上边重视于另3个上面。将那几个方面封装在单身的靶子中使它们得以分别独立地改变和复用。

一个指标的转移将促成其他2个或多少个对象也时有产生转移,而不亮堂具体有多少对象将发生改变,能够降低对象之间的耦合度。
 贰个对象必须通报其他对象,而并不知道这几个指标是哪个人。

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

【申明与多谢】
正文,站在广大大汉的肩头上,借鉴和引用了众多客人拥有版权的著述或撰文,在此,对前人们的进献致谢。并还要发布引用的剧情、原小编或出自(一些来源于网络的始末本人不大概追述本源,深表遗憾)。

【注脚与谢谢】
正文,站在重重庆大学汉的肩头上,借鉴和引用了无数客人拥有版权的著述或撰文,在此,对前人们的进献致谢。并还要发表引用的剧情、原小编或出自(一些来源于网络的始末本人不可能追述本源,深表遗憾)。

【参考文献】
《设计格局—可复用面向对象软件的基础》我: [美] 埃里克h Gamma / RichardHelm / 拉尔夫 Johnson / John Vlissides 译者: 李英军 / 马晓星 / 蔡敏 /
刘建中 等 机械工业出版社
《重构—改良既有代码的布署》小编: 马丁 Fowler译者:候捷
中中原人民共和国电力出版社
《敏捷软件开发—原则、格局与履行》小编: 罗Bert C. 马丁 北大东军大学出版社
《程序员修炼之道—从小工到我们》小编: Andrew Hunt / 大卫 托马斯电子工业出版社
《Head First 设计格局》我: Freeman 译者: O’Reilly Taiwan集团中华人民共和国电力出版社
《设计形式之禅》 小编: 秦小波 机械工业出版社
MSDN WebCast 《C#面向对象设计方式纵横谈》 助教:李建忠
刘伟(Liu-Wei). 设计格局. 新加坡:浙大东军政高校学出版社, 二零一一.
刘伟(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/ 博客小编:Love切莉

【参考文献】
《设计形式—可复用面向对象软件的基本功》笔者: [美] 埃里克h Gamma / RichardHelm / Ralph Johnson / John Vlissides 译者: 李英军 / 马晓星 / 蔡敏 /
刘建中 等 机械工业出版社
《重构—改革既有代码的宏图》作者: Martin Fowler译者:候捷
中夏族民共和国电力出版社
《敏捷软件开发—原则、格局与实施》小编: Robert C. Martin 清华东军大学出版社
《程序员修炼之道—从小工到我们》作者: Andrew Hunt / 戴维 托马斯电子工业出版社
《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 博客笔者:阿伦 lee
http://blog.csdn.net/ai92 博客小编:ai92
http://www.cnblogs.com/umlonline/ 博客小编:张传波
http://www.cnblogs.com/lovecherry/ 博客我:LoveCherry

相关文章