本帖最后由 严明 于 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!
|