定义
定义对象间一种一对多的依赖关系,每当一个对象改变状态时,则所有依赖与它的对象都会得到通知并被自动更新。
使用目的
将一个系统分割成一系列相互协作的类有一个很不好的副作用,那就是需要维护相关对象间的一致性。我们不希望为了维持一致性而使各类紧密耦合,这样会给维护,扩展和重用都带来不便。
使用场景
关联行为场景,需要注意的是,关联行为是可拆分的,而不是组合关系。
事件多级触发场景。
跨系统的消息交换场景,如消息队列,事件总线的处理机制。
当一个对象的改变需要同时改变其他对象时。而且并不知道具有有多少对象有待改变时,应考虑观察者模式。
优点
观察者与被观察者之间是抽象耦合,容易扩展。
方便建立一套触发机制。
观察者所做的工作其实就是在解除耦合。让耦合的双方都依赖于抽象,而不是依赖于具体。从而使得各自的变化都不会影响另一边的变化。
缺点
应用观察者模式时需要考虑一下开发效率和运行效率的问题。
程序中包括一个被观察者,多个观察者,开发调试等内容会比较复杂,而且Java中消息的 通知一般是顺序执行的,一个卡顿会影响整体效率,这种一般开启异步子线程。
结构图
描述
老板来公司时,通知玩游戏,看股票,学习的同事赶紧工作!
完整实例
抽象观察者
Class PHA.YX.Design.Observer.Observer Extends %RegisteredObject [ Abstract ]
{
Property name As %String;
Property sub As Subject;
Method %OnNew(name As %String, sub As Subject) As %Status [ Private, ServerOnly = 1 ]
{
s $this.name=name
s $this.sub=sub
Quit $$$OK
}
Method Update() [ Abstract ]
{
}
}
具体观察者
Class PHA.YX.Design.Observer.StockObserver Extends Observer
{
Method %OnNew(name As %String, sub As Subject) As %Status [ Private, ServerOnly = 1 ]
{
s $this.name=name
s $this.sub=sub
Quit $$$OK
}
Method Update()
{
w ..sub.subjectState _""_ ..name _ ",关闭股票行情,继续工作!"
}
}
Class PHA.YX.Design.Observer.GameObserver Extends Observer
{
Method %OnNew(name As %String, sub As Subject) As %Status [ Private, ServerOnly = 1 ]
{
s $this.name=name
s $this.sub=sub
Quit $$$OK
}
Method Update()
{
w ..sub.subjectState _""_ ..name _ ",赶紧关闭玩游戏了,继续工作!"
}
}
Class PHA.YX.Design.Observer.StudyObserver Extends Observer
{
Method %OnNew(name As %String, sub As Subject) As %Status [ Private, ServerOnly = 1 ]
{
s $this.name=name
s $this.sub=sub
Quit $$$OK
}
Method Update()
{
w ..sub.subjectState _""_ ..name _ ",别学习了,继续工作!"
}
}
抽象被观察者
Class PHA.YX.Design.Observer.Subject Extends %RegisteredObject
{
Method Attach(observer As Observer)
{
}
Method Detach(observer As Observer)
{
}
Method Notify()
{
}
Property subjectState As %String;
Method subjectStateGet() As %String [ ServerOnly = 1 ]
{
Quit i%subjectState
}
Method subjectStateSet(Arg As %String) As %Status [ ServerOnly = 1 ]
{
s i%subjectState=Arg
Quit $$$OK
}
}
具体被观察者
Class PHA.YX.Design.Observer.Boss Extends Subject
{
Property observers As list Of Observer;
Property action As %String;
Method Attach(observer As Observer)
{
d ..observers.Insert(observer)
}
///考虑如何用键值对的值来删除对应数组数据
Method Detach(observer As Observer)
{
d ..observers.RemoveAt(observer)
}
Method Notify()
{
f i = 1 : 1 : ..observers.Count() d
.d ..observers.GetAt(i).Update()
.w !
}
}
调用
/// dclass(PHA.YX.Design.Program).Observer()
ClassMethod Observer()
{
#dim mBoss as PHA.YX.Design.Observer.Boss
s mBoss =class(PHA.YX.Design.Observer.Boss).%New()
#dim mStockObserver as PHA.YX.Design.Observer.StockObserver
s mStockObserver =class(PHA.YX.Design.Observer.StockObserver).%New("马玉强", mBoss)
#dim mGameObserver as PHA.YX.Design.Observer.GameObserver
s mGameObserver =class(PHA.YX.Design.Observer.GameObserver).%New("丁竑莹", mBoss)
#dim mStudyObserver as PHA.YX.Design.Observer.StudyObserver
s mStudyObserver =class(PHA.YX.Design.Observer.StudyObserver).%New("云海宝", mBoss)
d mBoss.Attach(mStockObserver)
d mBoss.Attach(mGameObserver)
d mBoss.Attach(mStudyObserver)
s mBoss.subjectState = "老板回来了!"
d mBoss.Notify()
w "删除其中一个",!
d mBoss.Detach(3)
d mBoss.Notify()
}
DHC-APP>dclass(PHA.YX.Design.Program).Observer()
老板回来拉!马玉强,关闭股票行情,继续工作!
老板回来拉!丁竑莹,赶紧关闭玩游戏了,继续工作!
老板回来拉!云海宝,别学习了,继续工作!
删除其中一个
老板回来拉!马玉强,关闭股票行情,继续工作!
老板回来拉!丁竑莹,赶紧关闭玩游戏了,继续工作!
思考 模拟微信,微博,QQ用户,通知张无忌结婚了。感兴趣的同学实现后可以发我一起参考下。