设计模式------观察者模式
大量参考设计模式之禅观察者---就是间谍哈,或者叫偷窥狂也可以秦国的李斯要监视韩非子的一举一动,怎么办?方法1:派间谍呗,但是间谍得时时刻刻工作才能观察到韩非子的一举一动哈public class HanFeiZi{ //作为监视的判断标准 private boolean isHaveBreakfast = false; //别人要在外面能监视到他,那么他必须提供一个漏洞来让别人监视,这个漏洞是在getter中啦 private boolean isHaveFun = false; public void haveBreakfast(){ System.out.println("韩非子:开始吃饭了..."); this.isHaveBreakfast = true; } public void haveFun(){ System.out.println("韩非子:开始娱乐了"); this.isHaveFun = true; } //.....setter/getter}public class LiSi { public void update(String str){ //李斯做在家里听探子的报告就可以了,所以给探子一个接口 System.out.println("收到探子来信"); this.reportToQiShiHuang(str); System.out.println("报告完毕,回家打酱油"); } .....}class Spy extends Thread{ private HanFeiZi hanFeiZi; private LiSi lisi; private String type; //说明他是那种类型的间谍,是偷窥韩非子吃饭呢,还是偷窥韩非子洗澡呢 public Spy(HanFeiZi hanFeiZi,LiSi lisi,String type){ this.hanFeiZi=hanFeiZi; this.lisi=lisi; this.type=type; } public void run(){ while(true){ if(this.type.equals("breakfast")){ if(this.hanFeiZi.isHaveBreakfase){ this.lisi.update("韩非子在吃饭"); //探子观察到韩非子有动向,马上回报 //重置状态,继续监视 this.hanFeiZi.setHaveBreakfast(false); } }else{//监视韩非子娱乐的状态 this.lisi.update("韩非子在娱乐"); this.hanFeiZi.setHaveFun(false); } } } }上面的代码很清晰,但是效率不高,因为探子必须一直监视他们重点: 既然韩非子一吃饭李斯就知道,那我们为什么不把李斯这个类聚集到韩非子这个类上呢???(这让我想到了数据库中的两种表设计方式,第一种是建立第三方表来联系,在多对多时候用,第二种就是挂载哈。。。)下面是李斯病毒入侵韩非子public class HanFeiZi { private LiSi lisi = new Lisi(); public void haveBreakfast(){//连监视标志位都不需要了 System.out.println("韩非子开始吃饭了。。"); this.liSi.update("韩非子在吃饭"); //韩非子一吃饭就被李斯知道,呵呵,李斯果然是韩非子肚子里面的蛔虫 } public void haveFun(){ System.out.println("韩非子开始娱乐了。。"); this.liSi.update("韩非子在娱乐"); }}//呵呵。。。。但是如果向韩非子这样的人不只是李斯想偷窥呢。。很多人都想监视韩非子啊,怎么办。。。。给韩非子加开后门(黑客常常这么做)public interface Observable{ //给被观察者添加的后面,注意啦,接口在给类扩展功能的同时当然也为自己打开了后门,病毒可以通过此地入侵。。恩恩,这是接口的副作用,被李斯利用了 public void addObserver(Observer oberserver); public void deleteObserver(Observer observer); public void notifyObservers(String context); }public class HanFeiZi implements Observable{ private ArrayList<Observer> list = new ArrayList<Observer>(); public void addObserver(Observer o){ this.list.add(o); } public void deleteObserver(Observer o){ this.list.remove(o); } public void nofifyObservers(String context){ for(Observer o:list){ o.update(context); } } public void haveBreakfast(){ System.out.println("韩非子开始吃饭了"); this.notifyObservers("韩非子开始吃饭了"); } public void haveFun(){ System.out.println("韩非子开始娱乐了"); this.notifyObservers("韩非子开始娱乐了"); }}是不是很完美啊。。。。但是jdk提供了这些东西,但是他把Observable后面做成了抽象类而不是接口。。。这样做比较好,因为后门本来就不应该显示的出现在韩非子的类中,当然啦,韩非子自己提供后面那不是有毛病啊。。。。下面使用jdkpublic class HanFeiZi extends Observable{ public void haveBreakfast(){ System.out.println("韩非子吃饭"); super.setChanged(); //就是设置标志位 super.notifyObservers("韩非子在吃饭"); } public void haveFun(){ ......同理 }}public class LiSi implements Observer{ public void update(Observale o,Object msg){ //这里不但可以得到情报,还可以得到被观察者对象。。 。。。想怎么搞就怎么搞 }}ATM 机器上取钱,多次输错密码,卡就会被ATM吞掉,吞卡动作发生的时候,会触发哪些事件呢?第一摄像头连续快拍,第二,通知监控系统,吞卡发生;第三,初始化ATM 机屏幕,返回最初状态----全都用的是观察者哈