设计模式のObserver Pattern(观察者模式)----行为模式
观察者模式(Observer Pattern)是一种软件设计模式,属于行为型模式。它定义了一种一对多的依赖关系,当一个对象的状态发生变化时,所有依赖于它的对象都会得到通知并自动更新。
在观察者模式中,有两个核心角色:观察者(Observer)和被观察者(Subject)。观察者是依赖于被观察者的对象,当被观察者的状态发生变化时,观察者会得到通知并执行相应的操作。
观察者模式的主要目的是实现对象之间的松耦合,让被观察者和观察者之间的关系不是静态的继承关系,而是动态的关联关系。这样可以在不改变被观察者和观察者的情况下,增加新的观察者,从而实现更灵活的系统设计。
观察者模式的实现通常包括以下几个角色:
-
Subject(被观察者):被观察的对象,它维护一组观察者,并提供添加、删除和通知观察者的方法。当被观察者的状态发生变化时,会通知所有注册的观察者。
-
Observer(观察者):观察被观察者的对象,定义了在被观察者状态变化时所需执行的操作。观察者需要注册到被观察者中,以便接收状态变化的通知。
观察者模式的优点包括:
- 松耦合:被观察者和观察者之间的关系是松耦合的,它们之间相互独立,可以方便地进行扩展和维护。
- 可扩展性:可以方便地增加新的观察者,而不需要修改现有的代码。
- 随时通知:被观察者状态变化时会立即通知观察者,观察者可以及时采取相应的行动。
观察者模式在实际应用中广泛使用,例如在图形界面开发中,窗口的关闭事件可以通过观察者模式来实现,当窗口关闭时,所有注册的观察者可以执行相应的清理操作。此外,观察者模式也常用于事件驱动系统、消息队列等场景中。
一、问题产生背景
又被称为订阅发布模式。
最初流传最广的一个面试题:有一只猫咪,猫咪叫了一声,老鼠跑了,老人惊醒了,男主人骂,小偷吓得不敢动了....这就产生一个问题的模型,当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知它的依赖对象。观察者模式属于行为型模式。
二、观察者模式的通常做法
1、 抽象主题(Subject):它把所有观察者对象的引用保存到一个聚集里,每个主题都可以有任何数量的观察者。抽象主题提供一个接口,可以增加和删除观察者对象。
2、 具体主题(ConcreteSubject):将有关状态存入具体观察者对象;在具体主题内部状态改变时,给所有登记过的观察者发出通知。
3、抽象观察者(Observer):为所有的具体观察者定义一个接口,在得到主题通知时更新自己。
4、具体观察者(ConcreteObserver):实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题状态协调。
结构图:
三、具体实例
观察者模式的实现方式有几种,下面我们用接口方式实现。
1、首先我们建立观察者的抽象
namespace ObserverPattern { public interface IObserver { void update(string message); } }
2、建立被观察者的抽象
namespace ObserverPattern { public interface ISubject { void Attach(IObserver observer ); void Detach(IObserver observer); void Notify(string message); } }
3、观察者实例化
namespace ObserverPattern { public class User:IObserver { private string _name; public User(string name) { _name = name; } public void update(string message) { Console.WriteLine("hi"+_name+","+message); } } }
4、被观察者实例化(注意其中的观察者列表)
namespace ObserverPattern { public class SubscriptionSubject:ISubject { private List<IObserver> userList = new List<IObserver>(); public void Attach(IObserver observer) { userList.Add(observer); } public void Detach(IObserver observer) { userList.Remove(observer); } public void Notify(String message) { foreach (IObserver observer in userList) { observer.update(message); } } } }
5、我们整盒调用
namespace ObserverPattern { class Program { static void Main(string[] args) { SubscriptionSubject mSubscriptionSubject = new SubscriptionSubject(); //创建用户 User user1 = new User("林熙蕾"); User user2 = new User("潘春春"); User user3 = new User("罗云绮"); //订阅微博 mSubscriptionSubject.Attach(user1); mSubscriptionSubject.Attach(user2); mSubscriptionSubject.Attach(user3); //博主发通知 mSubscriptionSubject.Notify("刘德华发微博了"); Console.ReadKey(); } } }
四、设计模式分析
优点:
支持广播通信。
聚耦合,所有的观察者被抽象为一个接口。
缺点:
时间较长。
内联不足,具体表现在,观察者不能明确知道被观察者如何变化
可能出现循环调用