1. 程式人生 > >一個故事貫穿設計模式(十九)訪問者模式

一個故事貫穿設計模式(十九)訪問者模式

   這裡記錄的是訪問者模式 。  訪問者模式據說是設計模式中最難的一種,看一看它的例子把。

包結構:

類結構:

測試入口:

package com.automannn.design_mode.visitor.test;

import com.automannn.design_mode.visitor.OOP_class.*;
import com.automannn.design_mode.visitor.OOP_interface.*;
import com.automannn.design_mode.visitor.entity_alive.*;
import com.automannn.design_mode.visitor.entity_logicalOperation.*;
import com.automannn.design_mode.visitor.entity_nonliving.*;
import com.automannn.design_mode.visitor.exception.SingletonException;

/**
 * @author 
[email protected]
* @time 2018/9/13 15:06 */ public class Test { static LongGe longGe= new LongGe(); public static void main(String[] args) { //龍哥的適配管理器 AdapterManager am = new AdapterManager(); new Thread(am).start(); YuGe yuGe = new YuGe(); //龍哥通過迭代器的方式拿武器,於哥不知道它的車身到底有什麼武器 WeaponIterator wp = longGe.weaponItertor(); //因為武器在車上,所以龍哥可以拿來攻擊 while (wp.haseNext()){ Weapon weapon = (Weapon) wp.next(); System.out.print(longGe.getName()+": "); weapon.attack(); } //於哥有些慌張,想要去龍哥的車子搶奪刀,後者斧子,或者槍 System.out.println(yuGe.getName()+"憤然反抗,去車裡搶奪 刀,或者 槍, 或者 斧子"); //這時候,於哥不知道總共有什麼武器和多少武器,於是隨便去拿 try { //做好了拿刀的手勢,卻發現是斧子... Knife knife = (Knife) longGe.getBmw_car().getWeapon(0); }catch (ClassCastException e){ System.out.print(yuGe.getName()+": "); System.out.println("迭代器模式真是厲害,我甘拜下風。"); } //突然龍哥的刀掉了,情急之下,忘記了自己的寶馬車上有哪些武器 WeaponDescriptor descriptor= new WeaponDescriptor(60.0f,300.0f); longGe.setAdapter(new WeaponAdapter(descriptor)); longGe.setAssosation(am); longGe.AssosationDo(); //龍哥使用介面卡模式,拿到了一把槍,可是他不知道怎麼用,於是按照槍使用的模板使用 System.out.println(longGe.getName()+"通過模板模式,使用槍支:"); Weapon wpp = am.getWeapon(); try { Gun gg = (Gun) wpp; new SimpleGunTemplate().run(); }catch (ClassCastException e){ System.out.println("介面卡出錯!"); } //於哥發現龍哥欺人太甚了,想用點什麼來防禦一下,但是自己製作太費時間,於是使用工廠模式生產防彈衣 ArmorFactory armorFactory = new ArmorFactory(); armorFactory.produceWithCahce(); yuGe.setArmor((Armor) armorFactory.getProduct()); System.out.print(yuGe.getName()+" 通過 工廠模式 生產的 "); yuGe.getArmor().run(); //在打鬥中,於哥發現旁邊旁邊有個臺階,於是站上去以便更好的防禦 try { HighStep highStep = HighStep.getInstance(yuGe); } catch (SingletonException e) { System.out.println(e.getMessage()); } //龍哥本來就比於哥矮,於是肯定不甘心,於是追著站上去 try { HighStep highStep = HighStep.getInstance(longGe); } catch (SingletonException e) { System.out.println(e.getMessage()); } System.out.println("龍哥不甘心,開始想象要是自己先站上去就好了"); System.out.println("龍哥開始想象:~~~~"); //於哥發現站不上去了,腦海中想著要是有個分身先站上去就好了 //以下是他的想象: new Thread(()->{ try { HighStepThreadSafe highStepThreadSafe = HighStepThreadSafe.getInstance(longGe); } catch (Exception e) { System.out.println("~~~~"+e.getMessage()); } }).start(); try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } try { HighStepThreadSafe highStepThreadSafe = HighStepThreadSafe.getInstance(yuGe); } catch (Exception e) { System.out.println("~~~~"+e.getMessage()); } System.out.println("-------------------------"); //於哥發現掉血有點嚴重,再通過工廠模式生產防彈衣代價太大,於是通過原型模式複製一個防彈衣就ok了 ArmorPrototypeManager armorPrototypeManager= new ArmorPrototypeManager(); armorPrototypeManager.register("newArmor",yuGe.getArmor()); Armor newArmor= (Armor) armorPrototypeManager.create("newArmor"); System.out.println(yuGe.getName()+" 通過原型模式,複製了一個防彈衣"); newArmor.run(); //於哥決定防彈衣不行,還得弄個盾牌 Shield shield = new Shield(); shield.run(); System.out.println("這個盾牌太low了,需要一個更強大的"); //於哥用通過了一個盾牌構造器構造一個盾牌 System.out.println("使用盾牌構造器"); ShieldBuilder shieldBuilder = new ShieldBuilder(); Shield shield1= shieldBuilder.addParam("金剛石組成").addParam("具有條紋").addParam("可以防子彈").build(); shield1.run(); //他們都有點累了,心想回車裡坐一下吧,於是通過抽象工廠,龍哥召喚出小汽車,於哥召喚出摩托車 VehicleAbstractFactory carFactory= VehicleAbstractFactory.getFactory("com.automannn.design_mode.visitor." + "entity_logicalOperation.CarFactory"); carFactory.createShell(); carFactory.createWheel(); System.out.println(longGe.getName()+" 坐騎:"); carFactory.run(); VehicleAbstractFactory carFactory1= VehicleAbstractFactory.getFactory("com.automannn.design_mode.visitor." + "entity_logicalOperation.MotorFactory"); carFactory1.createShell(); carFactory1.createWheel(); System.out.println(yuGe.getName() +" 坐騎:"); carFactory1.run(); //龍哥覺得工廠造出來的車子不舒服,還是自己的寶馬車安逸 //並且使用了裝飾器模式,洋洋灑灑的一通操作 System.out.println("龍哥選擇了他的寶馬車,並用裝飾器模式一頓操作猛如虎"); new CarDecorator(longGe.getBmw_car()).run(); //於哥覺得比較明智的就是報警,可由於自己放不開手,於是只能委託一個路人報警 new HelperPersonProxy(yuGe).help(); //突然前面遇到了一個紅綠燈,龍哥害怕呀, 因為他不知道交通規則 於是使用門面模式,才得以安全過去 System.out.println("龍哥,通過門面模式,通過一個紅綠燈路口轉彎"); new CrossRoadFacade().cross(); //這個時候,路邊有個賣冰淇凌的。 龍哥和於哥都想買 Bridge bridge = new SpoonBridge(); System.out.println("於哥想要吃粘稠一點的冰激凌,通過橋接模式:"); bridge.setSpoon(new SpoonLiquid()); bridge.run(); System.out.println("龍哥想要吃幹一點的冰激凌,通過橋接模式:"); bridge.setSpoon(new SpoonSolid()); bridge.run(); //龍哥掏出了他的手機, 準備叫小弟 System.out.println(longGe.getName()+"掏出了手機:"); Phone aifeng= new Phone("愛瘋叉"); aifeng.addCorePart(new Phone.Part("A8處理器")); aifeng.addCorePart(new Phone.Part("定製主機板")); aifeng.addOtherParts(new Phone.Part("定製電池")); aifeng.setShell(new Phone.Part("金屬外殼")); aifeng.run(); //在這種情況,如果下雨, System.out.println("下雨了。。。"); yuGe.setStation("雨天"); yuGe.stationDo(); System.out.println("天晴了。。。"); longGe.setStation("晴天"); longGe.stationDo(); //這時候龍哥的電話被小弟接到了 AnswerPhone answerPhone = new Xiaodi(""); answerPhone.answer(); answerPhone = new Xiaodi("心情好"); answerPhone.answer(); //這時候警局的電話正被警元小張,和 小李觀察,監聽著電話 FixedTelephone fixedTelephone = new FixedTelephone(); fixedTelephone.addObserver( new Xiaoli()); fixedTelephone.addObserver( new Xiaozhang()); fixedTelephone.operate(); //相關部門已經知道了事情的嚴重性,於是下令必需妥善處理這件事 BaseHandler high= new OfficialHandler("上級部門"); BaseHandler medium = new OfficialHandler("中級部門"); BaseHandler low = new OfficialHandler("下級部門"); high.setHandler(medium); medium.setHandler(low); high.operate(); //這個事情已經驚動了特種部隊 SpecialTroops specialTroops = new SpecialTroops(); Command command = new SimpleCommand( specialTroops); Commander commander = new Commander(); commander.setCommand(command); commander.action(); //於哥知道等下警察就要來了,於是趕緊拍照保留證據,證明自己的清白 Scene scene = new Scene(); scene.setDesc("龍哥香車美女,目無他人,欺負老實人...."); //備份 Memento memento =new Memento(scene); //持久化 Storage storage = new Storage(memento); System.out.println("證據已經留下,當時的情況是這樣的:"); System.out.println(storage.getMemento().getScene().getDesc()); //特種部隊到來,果斷對龍哥使用訪問者模式搜了一遍 SimpleVisitor visitor = new SimpleVisitor(); Access access = longGe; visitor.visit(access); } public static class Trigger{ MessageQueue queue= new MessageQueue(); public void trigger(){ queue.cacheMessage(); } } private static class AdapterManager extends Trigger implements Runnable{ private Weapon weapon; @Override public void run() { while (true){ if (queue.hasMessage()&& longGe.getAdapter()!=null){ weapon = (Weapon) longGe.getAdapter().getTarget(); System.out.print(longGe.getName()+" 通過介面卡取得了武器。又開始了攻擊"); weapon.attack(); } } } public Weapon getWeapon() { return weapon; } } private static class MessageQueue{ //接收五個訊號用作緩衝,,這裡沒有用到,但是它邏輯上是存在的 boolean[] bb = new boolean[5]; //以0 記錄佇列頭 int top =0; //遊標,控制佇列的位置 int corsor=0; private void cacheMessage(){ //bb[corsor]=true; move(); } public boolean hasMessage(){ if (top == corsor) return false; Tmove(); return true; } //定義浮標移動的方式 private void move(){ //若當前的遊標已經到達線性尾部,則回到頭部 if ((corsor+1)%5==0){ corsor=0; return; } corsor++; } private void Tmove(){ //若當前的遊標已經到達線性尾部,則回到頭部 if ((top+1)%5==0){ top=0; return; } top++; } } }

測試結果: