营销型门户网站建设,用php做电子商务网站,wordpress仪表盘访问不了,ss网站代码观察者模式——定义了对象之间的一对多依赖#xff0c;这样一来#xff0c;当一个对像改变状态时#xff0c;它的所有依赖者都会收到通知并自动更新. 从定义可以看出,OBSERVER(观察者)模式逻辑上需要两组对象来实现.首先它必需要有发布者(Publish),也可称为被观察的目标 (… 观察者模式——定义了对象之间的一对多依赖这样一来当一个对像改变状态时它的所有依赖者都会收到通知并自动更新. 从定义可以看出,OBSERVER(观察者)模式逻辑上需要两组对象来实现.首先它必需要有发布者(Publish),也可称为被观察的目标 (Subject)(习惯上都称它为目标Subject,后面我们都称它作目标Subject),另外就是订阅者(Subscribe),习惯上称为观察 者(Observer).一个目标对象对应多个观察者对象,目标对象发生变化时,所有在目标对象中注册的观察者对象会得到通知,自动更新自己. 观察者模式UML图如下: 观察者模式的相关角色: 1、抽象主体Subject角色也 就是被关注的对象是一对多关系中的那个“一”。它的相关信息的变化将会通知给订阅这个变化的观察者。主体角色把所有对观察考对象的引用保存在一个集合 (List,ArrayList.....)里每个主体可能管理若干数量的观察者。抽象主体提供一个接口可以增加和删除观察者对象主体角色又叫做抽 象被观察者Observable角色一般用一个抽象类或者一个接口实现。 2、抽象观察者Observer角色为所有的具体观察者定义一个接口在得到主体的通知时更新自己。这个接口叫做更新接口(Update)。抽象观察者角色一般用一个抽象类或者一个接口实现。在这个示意性的实现中更新接口只包含一个方法即Update()方法这个方法叫做更新方法。 3、具体主体ConcreteSubject角色将有关状态存入具体现察者对象在具体主体的内部状态改变时给所有登记过的观察者发出通知。具体主体角色又叫做具体被观察者角色Concrete Observable。具体主题角色通常用一个具体子类实现。 4、具体观察者ConcreteObserver角色存储与主体的状态自恰的状态。具体现察者角色实现抽象观察者角色所要求的更新接口以便使本身的状态与主体的状态相协调。如果需要具体现察者角色可以保存一个指向具体主体对象的引用。具体观察者角色通常用一个具体子类实现。 下面我们用代码来示例观察者模式。 程序如下图: 一、观察者模式的基本思路 1、抽象主体Subject using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Collections;namespace MyObserver { //定义Subject抽象类它是ConcreteSubject具体目标对象的基类 //要实现Observer模式时通常将数据对象作为目标Subject各个显示数据的对象作为观察者Observer //每一个观察者Observer通过调用目标Subject中的一个公有public方法在他所感兴趣的数据中注册registers自己。 //这样当数据改变时每一个目标Subject通过观察者Observer的接口发送更新通知。 abstract class Subject { #region 定义一个List来装盛所有与此数据对象相联系的观察者Observer private ListObserver _observers new ListObserver(); #endregion #region 附加或解除Observer功能(注册或注销功能) public void Attach(Observer observer) { _observers.Add(observer); //observer观察者在此数据对象中注册registers自己。 } public void Detach(Observer observer) { _observers.Remove(observer);//在此数据对象中取消注册也即让对象变更时不用再通知此observer观察者 } #endregion #region 通知在_observers列表中的所有观察者 public void Nofity() { //遍历观察者列表按列表的名录逐一通知 foreach (Observer o in _observers) { o.Update(); } } #endregion } } 2、具体主体ConcreteSubject using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace MyObserver { //定义具体数据对象类它继承自Subject抽象类 class ConcreteSubject:Subject { #region SubjectState属性 private string _subjectState; public string SubjectState { get { return _subjectState; } set { _subjectState value; } } #endregion } } 3、抽象观察者Observer using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace MyObserver { #region 定义Observer抽象类它是ConcreteObserver的基类 abstract class Observer { //定义一个用于发送更新通知的接口 //这样当数据改变时每一个目标Subject通过观察者Observer的接口发送更新通知。 public abstract void Update(); } #endregion } 4、具体观察者ConcreteObserver using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace MyObserver { class ConcreteObserver:Observer { private string _name; private string _observerState; private ConcreteSubject _subject; public ConcreteSubject Subject { get { return _subject; } set { _subject value; } } #region 构造函数 public ConcreteObserver(ConcreteSubject subject, string name) { this._subject subject; this._name name; } #endregion #region 实现目标数据更新通知接口 public override void Update() { _observerState _subject.SubjectState; Console.WriteLine(观察者 {0} 收到的数据对象的新状态值是 {1},_name,_observerState); } #endregion } } 5、客户端代码 #region 基本思路示例 Console.WriteLine(----------观察者模式基本思路示例--------); ConcreteSubject s new ConcreteSubject(); //首先创建一个数据对象 s.Attach(new ConcreteObserver(s, X)); //向这个数据对象内注册三个观察者X,Y,Z s.Attach(new ConcreteObserver(s, Y)); s.Attach(new ConcreteObserver(s, Z)); s.SubjectState ABC; //改变数据对象的状态值 s.Nofity(); //调用数据对象的通知功能来依次通知已经注册的观察者 Console.ReadKey(); #endregion 二、我的团长我的团使用观察者模式 这里我们让孟烦了在前哨望风当他发现敌情时他马上通知所有兄弟们准备战斗。这里孟烦了就是具体主体ConcreteSubject他的那些兄弟要麻迷龙豆饼....等等都是具体观察者(ConcreteObserver) 1、抽象主体Subject:Guard using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Collections;namespace MyObserver { abstract class Guard { #region 定义一个List来收集所有需要通知到的其它士兵 private ListSoldier _soldiers new ListSoldier(); #endregion #region 附加或解除Observer功能(注册或注销功能) public void Attach(Soldier observer) { _soldiers.Add(observer); //observer观察者在此数据对象中注册registers自己。 } public void Detach(Soldier observer) { _soldiers.Remove(observer);//在此数据对象中取消注册也即让对象变更时不用再通知此observer观察者 } #endregion #region 通知在_observers列表中的所有观察者 public void Nofity() { //遍历观察者列表按列表的名录逐一通知 foreach (Soldier o in _soldiers) { o.Update(); } } #endregion } } 2、具体主体ConcreteSubject:ConcreteGurad using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace MyObserver { class ConcreteGurad:Guard { private string _name; public string Name { get { return _name; } set { _name value; } } #region FightInfo属性 private string _fightInfo; public string FightInfo { get { return _fightInfo; } set { _fightInfo value; } } #endregion public ConcreteGurad(string name) { this._name name; } } } 3、抽象观察者Observer:Soldier using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace MyObserver { abstract class Soldier { public abstract void Update(); } } 4、具体观察者ConcreteObserver:ConcreteSoldier using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace MyObserver { class ConcreteSoldier:Soldier { private string _observerState; private string _name; private ConcreteGurad _subject; public ConcreteGurad Subject { get { return _subject; } set { _subject value; } } #region 构造函数 public ConcreteSoldier(ConcreteGurad subject, string name) { this._subject subject; this._name name; } #endregion #region 实现目标数据更新通知接口 public override void Update() { _observerState _subject.FightInfo ; Console.WriteLine(士兵 {0} 收到哨兵 {1} 的信号:{2},_name,_subject.Name ,_observerState); } #endregion } } 5、客户端代码 #region 我的团长我的团 Console.WriteLine(----------我的团长我的团观察者模式示例--------); ConcreteGurad cg new ConcreteGurad(孟烦了); ConcreteSoldier yaoma new ConcreteSoldier(cg, 要麻); ConcreteSoldier sepigu new ConcreteSoldier(cg, 蛇屁股); ConcreteSoldier doubing new ConcreteSoldier(cg, 豆饼); ConcreteSoldier kangya new ConcreteSoldier(cg, 康丫); ConcreteSoldier milong new ConcreteSoldier(cg, 迷龙); ConcreteSoldier bula new ConcreteSoldier(cg, 不辣); cg.Attach(yaoma); cg.Attach(sepigu); cg.Attach(doubing); cg.Attach(kangya); cg.Attach(milong); cg.Attach(bula); cg.FightInfo 鬼子从右边摸上来了,大家准备歼灭他们.; cg.Nofity(); Console.ReadKey(); #endregion 程序运行后效果如下: 总结:1、要点 1抽象主体角色公开了自身的事件可以给任意观察者订阅。 2象观察者角色定义了统一的处理行为在C#中使用事件-代理模式的话统一的处理行为并不这么重要有的时候甚至还会限制灵活性。 3)观察者往往只需要实现响应方法即可。 4)有多个主体角色、多个观察者角色交错也可以一个类型是两个角色主体也可以提供多个事件。从应用上来说观察者模式变化是非常多的。2、优缺点 观察者模式的优缺点 Observer模式的优点是实现了表示层和数据逻辑层的分离并定义了稳定的更新消息传递机制类别清晰并抽象了更新接口使得可以有各种各样不同的表示层观察者。 但是其缺点是每个外观对象必须继承这个抽像出来的接口类这样就造成了一些不方便比如有一个别人写的外观对象并没有继承该抽象类或者接口不对我们 又希望不修改该类直接使用它。虽然可以再应用Adapter模式来一定程度上解决这个问题但是会造成更加复杂烦琐的设计增加出错几率。 观察者模式的效果有以下几个优点 1观察者模式在被观察者和观察者之间建立一个抽象的耦合。被观察者角色所知道的只是一个具体现察者聚集每一个具体现察者都符合一个抽象观察者的接 口。被观察者并不认识任何一个具体观察者它只知道它们都有一个共同的接口。由于被观察者和观察者没有紧密地耦合在一起因此它们可以属于不同的抽象化层 次。 2观察者模式支持广播通信。被观察者会向所有的登记过的观察者发出通知。 观察者模式有下面的一些缺点 1如果一个被观察者对象有很多直接和间接的观察者的话将所有的观察者都通知到会花费很多时间。 2如果在被观察者之间有循环依赖的话被观察者会触发它们之间进行循环调用导致系统崩溃。在使用观察考模式时要特别注意这一点。 3如果对观察者的通知是通过另外的线程进行异步投递的话系统必须保证投递是以自恰的方式进行的。 4虽然观察者模式可以随时使观察者知道所观察的对象发生了变化但是观察者模式没有相应的机制使观察者知道所观察的对象是怎么发生变化的。 转载于:https://www.cnblogs.com/smallfa/archive/2009/11/19/1606147.html