黑马程序员技术交流社区
标题:
23种模式_观察者模式之大白话解释
[打印本页]
作者:
严明
时间:
2012-6-26 08:24
标题:
23种模式_观察者模式之大白话解释
本帖最后由 严明 于 2012-6-26 08:58 编辑
最近在看一些有关模式的文章,在此将一些学习心得与大家共享一下,并用白话文解释一下这些看似高深莫的东西,先来上一个观察者模式.
1, 观察者(具体执行操作的对象,有多个)
2, 被观察者(顾名思义是被观察的对象,如果该对象发生某些变化则通知观察者执行对应的操)
为了便于理解,首先我举一个现实生活中的例子:
A 每天要吃饭, 娱乐.....,
而B 要监视A 的一举一动,获得A 的所有活动,话不多说,代码解释:
先定义一个接口 I_A
public interface I_A//A是被观察者,先将这类人抽象成一个接口
{
public void havaBreakfast();//A 要 吃饭
public void haveFun();//A要娱乐
}
再定义一个具体的被观察者 A 来实现 I_A
public class A implements I_A //A 是一个被观察者,每天都有两个要执行的动作:havaBreadfast,haveFun
{
private I_B b=new B();
//将B声明出来, 这就成了一种聚集方式的被观察者.
@Override
public void havaBreakfast()
{
System.out.println("A 开始吃饭了......");
//马上就通知B
this.b.update("A 现在就在吃饭了.........");
}
@Override
public void haveFun()
{
System.out.println("A 开始娱乐了......");
//马上就通知B
this.b.update("A 现在就在娱乐了.........");
}
}
观察者模式当然少不了观察者
public interface I_B // B 这种人是一个观察者,A 的所有行动 B都能准时知道
{
public void update(String context);// 接收间碟传入的参数,并采取行动
}
再定义一个具体的观察者 B 来实现 I_B
public class B implements I_B
{
public void update(String context)
{
System.out.println("观察到 A 开始有活动了:"+context);
}
}
最后模拟一个场景来测试
public class Client //设置 一个测试场景,看B 能否及时的观察到A 的行动 ,这也是一种聚集方式的场景类.
{
public static void main(String[] args){
A a = new A();//定义出A
//然后来看看A 到底在干什么?
a.havaBreakfast();//A 吃饭了
a.haveFun();//A 娱乐了
}
}
有人可能会想,应该定义3个类来模拟,一个被观察者A 一个观察者B 还有 一个传递消息
的间谍类Spy
, 创建一个后台线程一直处于运行状态,当发现A 有所行动就马上触发事件报告给B, B 再触发事件update(),
如果,你这样想了的话,那么可以准确的告诉你:你的思维还是停留在完全
面向过程的阶段, 这样写出来的程序就不是面向对象的
了,
最糟糕的是: 如果创建一个
后台线程一直处于运行状态,就必须用一个死循环while(true
){ },那么用到项目中的话,必须非常大的硬件投入,还不让别的程序运行了?
观察者将自己注册到被观察者的容器中时,被观察者不应该过问观察者的具体类型,而是应该使用观察者的接口。这样的优点是:假定程序中
还有别的观察者,那么只要这个观察者也是相同的接口实现
即可。一个被
观察者可以对应多个观察者
,当被观察者发生变化的时候,他可以将消息一一通知给所有的观察者。基
于接口,而不是具体的实现
——这一点为程序提供了更大的灵活性。
并且我上面的例子的代码是有问题的:
问题1:在class A 中的
private I_B b=new B();
只有B
一个人能观察到A的行动
,那么其他人要监视A的行动怎么办呢?
问题2:B只观察A的吃饭,娱乐吗? A还有政治倾向 感情生活 情绪变化 恋爱倾向 .........那么多一系列活动都要通知 B ,这如何是好?
在class A中定义 那么那么多的方法来实现吗? 不,这和
开闭原则
是严重相违背的
说实话,在下还没有研究透彻,若有高手看到,望指点一下,若你觉得对
你有帮助,请赞一个
,think you!
作者:
严明
时间:
2012-6-26 09:44
等了半天, 没人回复啊, 雁过不留痕者, 不厚道!{:soso_e118:}
作者:
严明
时间:
2012-6-26 09:44
等了半天, 没人回复啊, 雁过不留痕者, 不厚道!{:soso_e118:}
作者:
邓杰
时间:
2012-6-26 10:20
我来厚道一把;分享了;谢谢;
作者:
Forever。
时间:
2012-6-26 10:49
我暂时不去看你的代码,你先看看我讲的思路你是否能看懂:
1.被观察者和观察者永远是在一个线程里。
2.之所以观察者察觉到被观察者变化了,是因为被观察者主动告诉他了。
3.被观察者只有一个,观察者可以有多个。
这几点我认为是比较重要的,被观察者在内部有一个通知观察者的方法。
基于上面我们可以想到,被观察者内部一定有三个方法:添加观察者、删除观察者、还有通知观察者。
而观察者内部也一定有个方法:响应被观察者请求。
而观察者都会用一个list的形式存放在被观察者的内部。当你需要通知观察者时你只需要遍历这个集合里的所有观察者,挨个通知他就可以了。
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2