韩非子和李斯的间谍故事
李斯是秦国的上尉,需要安插间谍到各个国家,以便获取信息。韩非子做为韩国的重量级人物,韩非子身边自然
有很多间谍。李斯对韩非子的信息,了如指掌,那么相隔千里,是如何实现的呢?
答案:安插间谍。
|
package com.hym.myobserve; /** * 测试主程 * */ public class Client { public static void main(String[] args) throws InterruptedException { LiSi liSi=new LiSi(); HanFeiZi hanFeiZi=new HanFeiZi(); //观察吃早餐 Spy watchBreakfast=new Spy(hanFeiZi, liSi, "breakfast"); //观察娱乐 Spy watchFun=new Spy(hanFeiZi, liSi, "fun"); //////////////////////////此处的问题////////////////////////// //开启了两个线程,两个线程开启了两个死循环,一直在执行实现监控 //这样会比较消耗cpu的资源。 ///////////////////////////////////////////////////////////// watchBreakfast.start(); watchFun.start(); //主线程等待1s韩非子吃饭 Thread.sleep(1000); hanFeiZi.haveBreakfast(); Thread.sleep(1000); hanFeiZi.haveFun(); } }
public interface IHanFeiZi { /**吃早饭*/ public void haveBreakfast(); /**娱乐活动*/ public void haveFun(); }
package com.hym.myobserve; /** *韩非子类,继承韩非子接口,添加两个标示状态的属性 * */ public class HanFeiZi implements IHanFeiZi{ private boolean isHaveBreakfast=false; private boolean isHaveFun=false; @Override public void haveBreakfast() { System.out.println("韩非子:开始吃饭啦"); isHaveBreakfast=true; } @Override public void haveFun() { System.out.println("韩非子:开始娱乐了"); isHaveFun=true; } public boolean isHaveBreakfast() { return isHaveBreakfast; } public void setHaveBreakfast(boolean isHaveBreakfast) { this.isHaveBreakfast = isHaveBreakfast; } public boolean isHaveFun() { return isHaveFun; } public void setHaveFun(boolean isHaveFun) { this.isHaveFun = isHaveFun; } }
/** * * 抽象观察者对象李斯 * */ public interface ILisi { /**发现别人有动静,自己也要行动起来*/ public void update(String context); }
package com.hym.myobserve; /** * 观察者对象李斯 * */ public class LiSi implements ILisi{ //李斯是个观察者对象,一旦发现情况,需要要boss进行汇报 @Override public void update(String context) { System.out.println("李斯观察到韩非子有活动了,并向秦始皇汇报"); reportToQinShiHuang(context); System.out.println("李斯报告秦始皇:汇报完毕"); } private void reportToQinShiHuang(String reportContext){ System.out.println("李斯报告秦始皇:韩非子有活动了---->"+reportContext); } }
package com.hym.myobserve; /** * 间谍程序,监控程序是一个线程类 * */ public 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; } @Override public void run() { //用死循环来保证程序一直在监控状态 while(true){ //监控是否在吃早餐 if(this.type.equals("breakfast")){ if(hanFeiZi.isHaveBreakfast()){ this.liSi.update("韩非子在吃饭"); this.hanFeiZi.setHaveBreakfast(false); } }else{//监控是否在娱乐 if(hanFeiZi.isHaveFun()){ this.liSi.update("韩非子在娱乐"); this.hanFeiZi.setHaveFun(false); } } } } }
public class Client { public static void main(String[] args) throws InterruptedException { //定义韩非子 HanFeiZi hanFeiZi=new HanFeiZi(); //韩非子吃饭 hanFeiZi.haveBreakfast(); //韩非子娱乐 hanFeiZi.haveFun(); //==>主程类非常简单,但是发现李斯都没有在主程中声明。而是随着韩非子的上场而上场的。 //但是这是不符合场景的,就好比一部电视剧一样,不是所欲相关联的人物,从第一集就都要 //上场,而且建立关系。所以有第三个版本的改造。 } }
public interface IHanFeiZi { /**吃早饭*/ public void haveBreakfast(); /**娱乐活动*/ public void haveFun(); }
package com.hym.myobserve2; import java.awt.List; /** *韩非子类,继承韩非子接口,添加两个标示状态的属性 * */ public class HanFeiZi implements IHanFeiZi{ //声明李斯 private ILisi lisi=new LiSi(); @Override public void haveBreakfast() { System.out.println("韩非子:开始吃饭啦"); lisi.update("韩非子在吃饭"); } @Override public void haveFun() { System.out.println("韩非子:开始娱乐了"); lisi.update("韩非子在娱乐"); } }
/** * * 抽象观察者对象李斯 * */ public interface ILisi { /**发现别人有动静,自己也要行动起来*/ public void update(String context); }
package com.hym.myobserve2; /** * 观察者对象李斯 * */ public class LiSi implements ILisi{ //李斯是个观察者对象,一旦发现情况,需要要boss进行汇报 @Override public void update(String context) { System.out.println("李斯观察到韩非子有活动了,并向秦始皇汇报"); reportToQinShiHuang(context); System.out.println("李斯报告秦始皇:汇报完毕"); } private void reportToQinShiHuang(String reportContext){ System.out.println("李斯报告秦始皇:韩非子有活动了---->"+reportContext); } }
package com.hym.myobserve3; /** * 测试主程 * * */ public class Client { /**韩非子生活的总次数*/ private static int sum=0; public static void main(String[] args) throws InterruptedException { // 定义韩非子 HanFeiZi hanFeiZi = new HanFeiZi(); startHanFeiziLive(hanFeiZi,2); //韩非子生活了一段时间李斯出现了,并且开始监控 System.out.println("李斯开始监控韩非子"); LiSi liSi = new LiSi(); //设置监控 hanFeiZi.setILisi(liSi); //韩非子被监视(观察)过后的一段生活 startHanFeiziLive(hanFeiZi,3); //突然某一天秦王就把李斯给啥了 kill(liSi,hanFeiZi); startHanFeiziLive(hanFeiZi,2); System.out.println("韩非子一共娱乐或吃放了"+sum+"次"); } /** * * @param hanFeiZi * @param count 娱乐和吃饭的总次数 * @throws InterruptedException */ private static void startHanFeiziLive(HanFeiZi hanFeiZi,int count) throws InterruptedException { // 为模拟业务,此处用循环来模拟李斯10次吃饭和10次娱乐 for (int i = 0; i < count; i++) { sum++; // 前10次i是偶数的时候李斯吃饭 if (i < count/2) { // 后10次i是奇数的时候李斯吃饭 if (i % 2 == 0) { // 韩非子吃饭 hanFeiZi.haveBreakfast(sum); } else { hanFeiZi.haveFun(sum); } } else { // 后10次i是奇数的时候李斯吃饭 if (i % 2 == 1) { // 韩非子吃饭 hanFeiZi.haveBreakfast(sum); } else { hanFeiZi.haveFun(sum); } } Thread.sleep(1000 * 2); } } /** * 李斯被杀害 * @param lisi */ public static void kill(ILisi lisi,HanFeiZi hanFeiZi){ lisi=null; //韩非子不能再持有lisi的应用,否则java回收机制不能及时回收lisi实例 hanFeiZi.setILisi(null);//实际开发中可以提供remove方法 } }
public interface IHanFeiZi { /**吃早饭*/ public void haveBreakfast(int i); /**娱乐活动*/ public void haveFun(int i); }
/** * 韩非子类,继承韩非子接口,添加两个标示状态的属性 * */ public class HanFeiZi implements IHanFeiZi { // 为了让李斯的对象不是随着HanFeiZi对象的创建而创建,所以不能直接创建对象 // 而是在李斯对象在实际业务中被创建的时候,让韩非子对象才真正持有李斯对象 // 所以使用全部变量和set方法实现 // private ILisi lisi=new LiSi(); private ILisi mILisi; public void setILisi(ILisi lisi) { mILisi = lisi; } @Override public void haveBreakfast(int time) { System.out.println("韩非子:开始吃饭啦"+time); if (mILisi != null) mILisi.update("韩非子在吃饭"); } @Override public void haveFun(int time) { System.out.println("韩非子:开始娱乐了"+time); if (mILisi != null) mILisi.update("韩非子在娱乐"); } }
public interface ILisi { /**发现别人有动静,自己也要行动起来*/ public void update(String context); }
public class LiSi implements ILisi{ //李斯是个观察者对象,一旦发现情况,需要要boss进行汇报 @Override public void update(String context) { System.out.println("李斯观察到韩非子有活动了,并向秦始皇汇报"); reportToQinShiHuang(context); System.out.println("李斯报告秦始皇:汇报完毕"); } private void reportToQinShiHuang(String reportContext){ System.out.println("李斯报告秦始皇:韩非子有活动了---->"+reportContext); } }
韩非子其实一直就具备吃饭和娱乐的能力,只是在很长一段时间,没有被李斯监视(观察)过。
突然秦国觉得李斯这个人很重要,于是李斯这么个人要观察韩非子的行为,从而告知秦王。
|
package com.hym.myobserve4; /** * 测试主程 * * */ public class Client { /**韩非子生活的总次数*/ private static int sum=0; public static void main(String[] args) throws InterruptedException { // 定义韩非子 HanFeiZi hanFeiZi = new HanFeiZi(); startHanFeiziLive(hanFeiZi,2); //韩非子生活了一段时间李斯出现了,并且开始监控 System.out.println("李斯开始监控韩非子"); LiSi liSi = new LiSi(); //设置监控 hanFeiZi.addObsever(liSi); //韩非子被监视(观察)过后的一段生活 startHanFeiziLive(hanFeiZi,3); //突然某一天秦王就把李斯给杀了 kill(liSi,hanFeiZi); startHanFeiziLive(hanFeiZi,2); System.out.println("韩非子一共娱乐或吃放了"+sum+"次"); //场景中有了新的业务,秦国的李斯被杀过后,大王派王思观察HanFeizi的吃饭娱乐行为, //同时要观察HanFeiZi是否有把妹行为。 WangSi wangSi=new WangSi(); hanFeiZi.addObsever(wangSi); hanFeiZi.baMeizi(); //扩展新的观查者,对被观察的行为进行扩展都非常方便,而且观察者和被观察者的通用接口 //无需做任何修改,代码维护和扩展都很便捷,符合了软件设计中遵循的开闭原则 } /** * * @param hanFeiZi * @param count 娱乐和吃饭的总次数 * @throws InterruptedException */ private static void startHanFeiziLive(HanFeiZi hanFeiZi,int count) throws InterruptedException { // 为模拟业务,此处用循环来模拟李斯10次吃饭和10次娱乐 for (int i = 0; i < count; i++) { sum++; // 前10次i是偶数的时候李斯吃饭 if (i < count/2) { // 后10次i是奇数的时候李斯吃饭 if (i % 2 == 0) { // 韩非子吃饭 hanFeiZi.haveBreakfast(sum); } else { hanFeiZi.haveFun(sum); } } else { // 后10次i是奇数的时候李斯吃饭 if (i % 2 == 1) { // 韩非子吃饭 hanFeiZi.haveBreakfast(sum); } else { hanFeiZi.haveFun(sum); } } Thread.sleep(1000 * 2); } } /** * 李斯被杀害 * @param lisi */ public static void kill(IObserver lisi,HanFeiZi hanFeiZi){ System.out.println("======观察者李斯被杀害========"); //韩非子不能再持有lisi的引用,否则java回收机制不能及时回收lisi实例 //hanFeiZi.setILisi(null);//实际开发中可以提供remove方法 hanFeiZi.mIObservers.remove(lisi); lisi=null; } }
public interface IHanFeiZi { /**吃早饭*/ public void haveBreakfast(int i); /**娱乐活动*/ public void haveFun(int i); }
package com.hym.myobserve4; import java.util.ArrayList; import java.util.List; /** * 韩非子类,继承韩非子接口,添加两个标示状态的属性 **/ public class HanFeiZi implements IObservable,IHanFeiZi { // 为了让李斯的对象不是随着HanFeiZi对象的创建而创建,所以不能直接创建对象 // 而是在李斯对象在实际业务中被创建的时候,让韩非子对象才真正持有李斯对象 // 所以使用全部变量和set方法实现 // private ILisi lisi=new LiSi(); List<IObserver> mIObservers= new ArrayList<IObserver>(); @Override public void haveBreakfast(int time) { System.out.println("韩非子:开始吃饭啦"+time); notifyObsevers("吃饭"); } @Override public void haveFun(int time) { System.out.println("韩非子:开始娱乐了"+time); notifyObsevers("娱乐"); } /** * 添加了把妹的新能力,如果把妹能力通用,可以提到接口中去 */ public void baMeizi(){ System.out.println("韩非子正在把妹"); notifyObsevers("韩非子正在把妹"); } @Override public void addObsever(IObserver iObserver) { mIObservers.add(iObserver); } @Override public void deleteObsever(IObserver iObserver) { mIObservers.remove(iObserver); } @Override public void notifyObsevers(String context) { if (mIObservers != null&&mIObservers.size()>0){ for (IObserver iObserver : mIObservers) { iObserver.update("韩非子在"+context); } } } }
/** * * 抽象观察者对象李斯<br> * 将接口修改为通用的观察者接口 * * */ public interface IObserver { /**发现别人有动静,自己也要行动起来*/ public void update(String context); }
package com.hym.myobserve4; /** * 观察者对象李斯 * */ public class LiSi implements IObserver{ //李斯是个观察者对象,一旦发现情况,需要要boss进行汇报 @Override public void update(String context) { System.out.println("李斯观察到韩非子有活动了,并向秦始皇汇报"); reportToQinShiHuang(context); System.out.println("李斯报告秦始皇:汇报完毕"); } private void reportToQinShiHuang(String reportContext){ System.out.println("李斯报告秦始皇:韩非子有活动了---->"+reportContext); } }
package com.hym.myobserve4; /** * 被观察者接口,这样将实际业务和观察者模型也实现了分离。 * 此接口提供被观察者相关功能的声明 */ public interface IObservable { /** * 给被观察者添加观察者对象 * @param iObserver */ public void addObsever(IObserver iObserver); /** * 给被观察者删除观察者对象 * @param iObserver */ public void deleteObsever(IObserver iObserver); /** * 通知所有观察者,触发观察者行为 * @param context */ public void notifyObsevers(String context); }
public class WangSi implements IObserver{ @Override public void update(String context) { System.out.println(context); } }
/** * 测试主程 * * */ public class Client { public static void main(String[] args) throws InterruptedException { ObservableModle observableModle=new ObservableModle(); ObserverModle observerModle=new ObserverModle(); observableModle.addObserver(observerModle); observableModle.doSometing("做一些事情.."); } }
package com.hym.observe; import java.util.Observable; import java.util.Observer; /** * * @description: * <p> * 可被观察的模型,模式的运用场景分析 * </p> * @author: HuYuMian * * @QQ:732476506 */ public class ObservableModle extends Observable{ @Override public synchronized void addObserver(Observer o) { super.addObserver(o); } @Override public synchronized void deleteObserver(Observer o) { super.deleteObserver(o); } @Override public void notifyObservers() { super.notifyObservers(); } public void doSometing(String context){ System.out.println("被观察者"+context); /*if (!changed) return; */ //上面这部分代码在observable.java的源码中,有判断处理。默认值是false,不执行update方法。 //所以使用java本身的observable.java的api,通知观察者对象update方法调用,必须先执行setChanged //方法,并在执行notifyObservers方法后,会被重置,调用protected synchronized void clearChanged() { //changed = false; //} setChanged(); notifyObservers(context); } }
public class ObserverModle implements Observer{ //参数说明:Observable o:被观察者对象 //Object arg:数据对象 @Override public void update(Observable o, Object arg) { System.out.println("观察者"+arg.toString()); } }