定 义:定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新
优 点:
1、观察者和被观察者之间是抽象耦合
2、建立一套出发机制
应用案例:
先来看看类图:
1.抽象主题角色:把所有对观察者对象的引用保存在一个集合中,每个抽象主题角色都可以有任意数量的观察者。抽象主题提供一个接口,可以增加和删除观察者角色。一般用一个抽象类或接口来实现
2.抽象观察者角色:为所有具体的观察者定义一个接口,在得到主题的通知时更新自己。
3.具体主题角色(Watched):把所有对观察者对象的引用保存在一个集合中,每个抽象主题角色都可以有任意数量的观察者。抽象主题提供一个接口,可以增加和删除观察者角色。一般用一个抽象类或接口来实现。
4.具体观察者角色(Watcher):为所有具体的观察者定义一个接口,在得到主题的通知时更新自己
现在自己系统中的设计还未使用到这个观察者模式,但是其实是可以利用上的,例如在系统自动更新系统资源数据的时候,现在采用的是每间隔一段时间就自动更新一下资源,这样会造成有时候不需要更新也进行更新了,而且频繁更新会对网络、机器的依赖性更高,所以应该采用观察者设计模式,如果有资源的更新,立马通知资源更新模块来更新资源以及相关的数据,这样使得系统更加合理以及简洁,实现UML图如下:
再来看一个被多人监视的UML类图结构:
.NET中的Observer模式
利用事件和委托来实现Observer 模式我认为更加的简单和优雅,也是一种更好的解决方案
效果及实现要点
1 .使用面向对象的抽象,Observer 模式使得我们可以独立地改变目标与观察者,从而使二者之间的依赖关系达到松耦合。
2 .目标发送通知时,无需指定观察者,通知(可以携带通知信息作为参数)会自动传播。观察者自己决定是否需要订阅通知。目标对象对此一无所知。
3 .在C# 中的Event 。委托充当了抽象的Observer 接口,而提供事件的对象充当了目标对象,委托是比抽象Observer 接口更为松耦合的设计。
总结
通过Observer 模式,把一对多对象之间的通知依赖关系的变得更为松散,大大地提高了程序的可维护性和可扩展性,也很好的符合了开放- 封闭原则。
- Public Interface IObservable
- '''
- ''' <param name="anObserver"></param>
- Sub Register(ByVal key As String, ByVal anObserver As IObserver)
- '''
- ''' <param name="key"></param>
- Sub UnRegister(ByVal key As String)
- End Interface ' IObservable
- Public Interface IObserver
- '''
- ''' <param name="anObject"></param>
- Sub Notify(ByVal anObject As Object)
- End Interface ' IObserver
- Public Interface IHanfeizi
- Sub haveBreackfast()
- Sub haveFun()
- End Interface ' IHanfeizi
- Public Class Hanfeizi
- Implements IHanfeizi, IObservable
- Private observerContainer As Hashtable = new Hashtable()
- Public Sub haveBreackfast() Implements IHanfeizi.haveBreackfast
- Console.WriteLine("韩非子吃饭")
- End Sub
- '''
- ''' <param name="anObserver"></param>
- Public Sub Register(ByVal key As String, ByVal anObserver As IObserver) Implements IObservable.Register
- observerContainer.Add(key, anObserver)
- End Sub
- Public Sub haveFun() Implements IHanfeizi.haveFun
- Console.WriteLine("韩非子弄笑话了")
- End Sub
- '''
- ''' <param name="key"></param>
- Public Sub UnRegister(ByVal key As String) Implements IObservable.UnRegister
- observerContainer.Remove(key)
- End Sub
- '''
- ''' <param name="message"></param>
- Public Sub NotifyObservers(ByVal message As String)
- Dim _observer As IObserver
- For Each _observer In observerContainer.Values
- _observer.Notify(message)
- Next
- End Sub
- End Class ' Hanfeizi
- Public Class Lisi
- Implements IObserver
- '''
- ''' <param name="anObject"></param>
- Public Sub Notify(ByVal anObject As Object) Implements IObserver .Notify
- Console.WriteLine("李斯观察到韩非子正在:" & anObject.ToString)
- Console.WriteLine("李斯向老板汇报情况")
- End Sub
- End Class ' Lisi
- Public Class LiuSi
- Implements IObserver
- '''
- ''' <param name="anObject"></param>
- Public Sub Notify(ByVal anObject As Object) Implements IObserver .Notify
- Console.WriteLine("刘斯观察到韩非子正在:" & anObject.ToString)
- Console.WriteLine("刘斯高兴不得了")
- End Sub
- End Class ' LiuSi
- Public Class WangSi
- Implements IObserver
- '''
- ''' <param name="anObject"></param>
- Public Sub Notify(ByVal anObject As Object) Implements IObserver .Notify
- Console.WriteLine("王斯观察到韩非子正在:" & anObject.ToString)
- Console.WriteLine("王斯气急败坏")
- End Sub
- End Class ' WangSi
- Module Client
- Sub Main()
- Dim _hanfeizi As Hanfeizi = New Hanfeizi()
- Dim _lisi As IObserver = New Lisi
- Dim _liusi As IObserver = New LiuSi
- Dim _wangsi As IObserver = New WangSi
- _hanfeizi.Register("lisi", _lisi)
- _hanfeizi.Register("liusi", _liusi)
- _hanfeizi.Register("wangsi", _wangsi)
- _hanfeizi.haveBreackfast()
- _hanfeizi.NotifyObservers("韩非子吃饭了")
- _hanfeizi.haveFun()
- _hanfeizi.NotifyObservers("韩非子弄笑话了")
- Console.Read()
- End Sub
- End Module