一、定义
定义对象之间的一种一对多依赖关系,使得当每一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新。观察者模式是一种行为型模式,又称为发布-订阅(Publish-Subscribe)模式、模型-视图(Model-View)模式、源-监听器(Source-Listener)模式或从属者(Dependents)模式。
二、描述
观察者模式是一种使用频率最高的设计模式之一,用于建立一种对象与对象之间的依赖关系,一个对象发生改变时将自动通知其他对象,其他对象将相应作出反应。包含以下四个角色:1、Subject(抽象目标):又称为主题,是被观察的对象。
2、ConcreteSubject(具体目标):抽象目标的子类,通常包含有经常发生改变的数据,当它的状态发生改变时,向其各个观察者发出通知。
3、Observer(抽象观察者):观察者将对观察目标的改变做出反应。
4、ConcreteObserver(具体观察者):具体观察者中维持一个指向具体目标对象的引用,它用于存储具体观察者的有关状态,这些状态需要和具体目标地状态保持一致。
三、例子
X公司欲开发一款多人联机对战游戏,在游戏中,多个游戏玩家可以加入同一战队组成联盟,当战队中某一成员收到敌人攻击时将给所有其他盟友发送通知,盟友收到通知后将作出响应。IObserver:抽象观察者
public interface IObserver
{
string Name { get; set; }
void Help(); // 声明支援盟友的方法
void BeAttacked(AllyControlCenter acc); // 声明遭受攻击的方法
}
Player:战队成员类,充当具体观察者
public class Player : IObserver
{
public string Name { get; set; }
public void BeAttacked(AllyControlCenter acc)
{
Console.WriteLine("{0}:我正被攻击,速来援救!", this.Name);
// 调用战队控制中心类的通知方法来通知盟友
acc.NotifyObserver(this.Name);
}
public void Help()
{
Console.WriteLine("{0} :坚持住,立马来救你!", this.Name);
}
}
AllyControlCenter:抽象战队控制中心类,充当抽象目标
public abstract class AllyControlCenter
{
public string AllyName { get; set; }
protected IList<IObserver> playerList = new List<IObserver>();
public void Join(IObserver observer)
{
playerList.Add(observer);
Console.WriteLine("通知:{0} 加入 {1} 战队", observer.Name, this.AllyName);
}
public void Quit(IObserver observer)
{
playerList.Remove(observer);
Console.WriteLine("通知:{0} 退出 {1} 战队", observer.Name, this.AllyName);
}
// 声明抽象通知方法
public abstract void NotifyObserver(string name);
}
ConcreteAllyControlCenter:具体战队控制中心类,充当具体目标
public class ConcreteAllyControlCenter : AllyControlCenter
{
public ConcreteAllyControlCenter(string allyName)
{
Console.WriteLine("系统通知:{0} 战队组建成功!", this.AllyName);
Console.WriteLine("-------------------------------------------------------");
this.AllyName = allyName;
}
// 实现通知方法
public override void NotifyObserver(string playerName)
{
Console.WriteLine("通知:盟友们,{0} 正遭受敌军攻击,速去抢救!", playerName);
foreach (var player in playerList)
{
if (!player.Name.Equals(playerName, StringComparison.OrdinalIgnoreCase))
{
player.Help();
}
}
}
}
Program:测试代码
// Step1.定义观察者对象
AllyControlCenter acc = new ConcreteAllyControlCenter("金庸群侠");
// Step2.定义4个观察者对象
IObserver playerA = new Player() { Name = "杨过" };
acc.Join(playerA);
IObserver playerB = new Player() { Name = "令狐冲" };
acc.Join(playerB);
IObserver playerC = new Player() { Name = "张无忌" };
acc.Join(playerC);
IObserver playerD = new Player() { Name = "段誉" };
acc.Join(playerD);
// Step3.当某盟友遭受攻击
playerA.BeAttacked(acc);
Console.ReadLine();
四、总结
1、优点
(1)观察者模式可以实现表示层和数据逻辑层的分离,定义了稳定的消息更新传递机制、并抽象了更新接口,使得可以有各种各样不同的表示层充当具体观察者角色。
(2)在观察目标和观察者之间建立一个抽象的耦合,观察目标只需要维持一个抽象观察者的集合,无须了解其具体观察者。由于观察目标和观察者没有紧密地耦合在一起,因此它们可以属于不同的抽象化层次。
(3)观察者模式支持广播通信,观察目标会向所有已注册的观察者对象发送通知,简化了一对多系统设计的难度。
(4)观察者模式符合开闭原则,增加新的具体观察者无须修改原有系统代码,在具体观察者与观察目标之间不存在关联关系的情况下增加新的观察目标也很方便。
2、缺点
(1)如果一个观察目标对象有很多直接和间接观察者,将所有的观察者都通知到会花费很多时间。
(2)如果在观察者和观察目标之间存在循环依赖,观察目标会触发它们进行循环调用,可能导致系统崩溃。
(3)观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而只是知道观察目标发生了变化。
1.本站内容仅供参考,不作为任何法律依据。用户在使用本站内容时,应自行判断其真实性、准确性和完整性,并承担相应风险。
2.本站部分内容来源于互联网,仅用于交流学习研究知识,若侵犯了您的合法权益,请及时邮件或站内私信与本站联系,我们将尽快予以处理。
3.本文采用知识共享 署名4.0国际许可协议 [BY-NC-SA] 进行授权
4.根据《计算机软件保护条例》第十七条规定“为了学习和研究软件内含的设计思想和原理,通过安装、显示、传输或者存储软件等方式使用软件的,可以不经软件著作权人许可,不向其支付报酬。”您需知晓本站所有内容资源均来源于网络,仅供用户交流学习与研究使用,版权归属原版权方所有,版权争议与本站无关,用户本人下载后不能用作商业或非法用途,需在24个小时之内从您的电脑中彻底删除上述内容,否则后果均由用户承担责任;如果您访问和下载此文件,表示您同意只将此文件用于参考、学习而非其他用途,否则一切后果请您自行承担,如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。
5.本站是非经营性个人站点,所有软件信息均来自网络,所有资源仅供学习参考研究目的,并不贩卖软件,不存在任何商业目的及用途
暂无评论内容