`
webdev2014
  • 浏览: 679387 次
文章分类
社区版块
存档分类
最新评论

三国杀与设计模式之观察者模式

 
阅读更多

本人原博地址:http://blog.saymagic.cn/blog.php?id=16

设想一个五人局,孙权是主,其余四人依次为曹操,祝融,夏侯敦,郭嘉,开局了,主公孙权放了一个南蛮,想一想这时会有什么发生呢,主会说,小心啊,我要放南蛮了,曹操一看,我是内丫,南蛮,卖血我要收了它!!一会在南别人去,于是曹操掉一滴血拿了南蛮,祝融一看,我不怕呀,要不是曹操小子这南蛮就是我的了,到夏侯敦了,他一想,我是反贼呀,我要掉血让孙权弃牌,于是夏侯敦又掉了一滴血,最后是郭嘉,做为忠臣的它一看事情不妙,掉血,给主公牌,于是郭嘉掉了一滴血。想一想,一个南蛮放完了,每个人都有每个人的反应,这是什么呢?这就是观察者模式,用一句简单的话来说观察者模式就是一个具体主题(ConcreteSubject)角色在发生变化时,通知具体观察者(ConcreteObserver)角色,然后具体观察者就可以根据此消息做出反应,在这局三国杀里,孙权就是具体主题(ConcreteSubject),而其他四人则是具体观察者(ConcreteObserver),孙权负责通知各个人物我放了南蛮,其它人则都会收到消息并作出反映,理解了吗?那具体代码怎么写呢?

首先,我们根据依赖倒转原则,我们要面向抽象编程,所以,孙权作为具体主题(ConcreteSubject),他就应该集成一个抽象Subject,这样如果下次曹操什么的要发消息时只需要再来继承这个抽象Subject就好了,并且,这个抽象Subject里面要有一个List数组,用来存贮一会孙权要给谁发送消息,在发消息时只需要遍历数组元素调用数组里的人物收到通知的方法就好,它的类图如下:

所以,抽象Subject代码如下:

import java.util.*;

public class Subject {
private List<Observer> list = new ArrayList<Observer>();

public void 发通知() {
// TODO: implement
}

public List getList() {
return list;
}

public void setList(List list) {
this.list = list;
}

public void attach(Observer observer){
list.add(observer);
}

public void detach(Observer observer){

list.remove(observer);
}
/**
* 通知所有注册的观察者对象
*/
public void nodifyObservers(){

for(Observer observer : list){
observer.做出反映();
}
}

}

而作为具体主题(ConcreteSubject)的孙权,他只需要继承这个抽象Subject,覆盖抽象Subject的发通知方法,在里面再去调用抽象Subject的nodifyObservers()方法即可,代码如下:

import java.util.*;

public class 孙权 extends Subject {

public 孙权(){
}

public void 发通知() {
System.out.println("我是孙权,我要放南蛮了,各位注意!!!");
super.nodifyObservers();
}

}

Subject需要抽象出来,那么Observer也同样需要,这里我们把它定义成接口,其实大宝贝你要知道,接口和类都可以,他们的区别不是很多,当要有属性的时候一定要用抽象类了,但类不能多重继承,所以在抽象层不需要属性的的时候,接口是很好的选择,这里我们定义Observer抽象接口,里面定义方法‘做出反映’,代码很简单:

import java.util.*;

public interface Observer {
void 做出反映();

}

对于四个观察者则简单了。这需要实现Observer借口,实现里面‘做出反映’函数即可,这里随便列出曹操类的代码:

import java.util.*;

public class 曹操 implements Observer {
public void 做出反映() {
System.out.println("我是曹操我要掉血收南蛮");
}
}

最后是客户端,他只需要将曹操祝融等人物注册到孙权的List里面,这样,孙权发送方南蛮通知的时候,程序通过遍历数组就会通知每一个人由南蛮了,代码如下:
public class Client {

public static void main(String[] args) {
Subject sunquan = new 孙权();
Observer caocao = new 曹操();
Observer zhurong = new 祝融();
Observer xiahoudun = new 夏侯惇();
Observer guojia = new 郭嘉();
sunquan.attach(caocao);
sunquan.attach(zhurong);
sunquan.attach(xiahoudun);
sunquan.attach(guojia);
sunquan.发通知();

}

}

好啦,最后运行一下看结果吧:

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics