摘要:但是發(fā)出者并不清楚到底最終那個(gè)對(duì)象會(huì)處理該請(qǐng)求,所以,責(zé)任鏈模式可以實(shí)現(xiàn),在隱瞞客戶(hù)端的情況下,對(duì)系統(tǒng)進(jìn)行動(dòng)態(tài)的調(diào)整。因?yàn)樵L問(wèn)者模式使得算法操作增加變得容易。訪問(wèn)者模式將有關(guān)行為集中到一個(gè)訪問(wèn)者對(duì)象中,其改變不影響系統(tǒng)數(shù)據(jù)結(jié)構(gòu)。
總體分為3大類(lèi):
創(chuàng)建型模式 (5種):工廠方法、抽象工廠、單例、建造者、原型
結(jié)構(gòu)型模式(7種):適配器、裝飾器、代理、外觀、橋接、組合、享元
行為型模式(11種):策略、模板方法、觀察者、迭代子、責(zé)任鏈、命令、備忘錄、狀態(tài)、訪問(wèn)者、中介者、解釋器
其它(2種):并發(fā)型、線程池
先來(lái)看看這11種模式的關(guān)系:
第一類(lèi):通過(guò)父類(lèi)與子類(lèi)的關(guān)系進(jìn)行實(shí)現(xiàn)。
第二類(lèi):兩個(gè)類(lèi)之間。
第三類(lèi):類(lèi)的狀態(tài)。
第四類(lèi):通過(guò)中間類(lèi)
定義一系列可以相互替換的算法,并將每個(gè)算法封裝起來(lái)。設(shè)計(jì)一個(gè)接口為實(shí)現(xiàn)類(lèi)提供統(tǒng)一的方法,設(shè)計(jì)一個(gè)抽象類(lèi)(可有可無(wú),屬于輔助類(lèi))提供輔助函數(shù):
public interface ICalculator { int calculate(String exp); }
輔助類(lèi):
public abstract class AbstractCalculator { public int[] split(String exp, String opt){ String array[] = exp.split(opt); int arrayInt[] = new int[2]; arrayInt[0] = Integer.parseInt(array[0]); arrayInt[1] = Integer.parseInt(array[1]); return arrayInt; } }
三個(gè)實(shí)現(xiàn)類(lèi):
public class Plus extends AbstractCalculator implements ICalculator { @Override public int calculate(String exp) { int arrayInt[] = split(exp,"+"); return arrayInt[0]+arrayInt[1]; } }
public class Minus extends AbstractCalculator implements ICalculator { @Override public int calculate(String exp) { int arrayInt[] = split(exp,"-"); return arrayInt[0]-arrayInt[1]; } }
public class Multiply extends AbstractCalculator implements ICalculator { @Override public int calculate(String exp) { int arrayInt[] = split(exp,"*"); return arrayInt[0]*arrayInt[1]; } }
簡(jiǎn)單的測(cè)試類(lèi):
public class StrategyTest { public static void main(String[] args) { String exp = "2+8"; ICalculator cal = new Plus(); int result = cal.calculate(exp); System.out.println(result); } }
策略模式多用在算法決策系統(tǒng)中,用戶(hù)只需要決定用哪個(gè)算法即可。
模板方法(Template Method)抽象類(lèi)中有一個(gè)主方法,再定義n個(gè)方法(可以是抽象的,也可以是實(shí)際的方法),定義一個(gè)類(lèi)繼承該抽象類(lèi),重寫(xiě)抽象方法,通過(guò)調(diào)用抽象類(lèi),實(shí)現(xiàn)對(duì)子類(lèi)的調(diào)用:
就是在 AbstractCalculator 類(lèi)中定義一個(gè)主方法 calculate,calculate()調(diào)用 spilt()等,Plus 和Minus 分別繼承 AbstractCalculator 類(lèi),通過(guò)對(duì) AbstractCalculator 的調(diào)用實(shí)現(xiàn)對(duì)子類(lèi)的調(diào)用:
public abstract class AbstractCalculator { /*主方法,實(shí)現(xiàn)對(duì)本類(lèi)其它方法的調(diào)用*/ public final int calculate(String exp, String opt){ int array[] = split(exp,opt); return calculate(array[0],array[1]); } /*被子類(lèi)重寫(xiě)的方法*/ protected abstract int calculate(int num1, int num2); private int[] split(String exp, String opt) { String[] array = exp.split(opt); int[] arrayInt = new int[2]; arrayInt[0] = Integer.parseInt(array[0]); arrayInt[1] = Integer.parseInt(array[1]); return arrayInt; } }
public class Plus extends AbstractCalculator { @Override protected int calculate(int num1, int num2) { return num1 + num2; } }
測(cè)試類(lèi):
public class StrategyTest { public static void main(String[] args) { String exp = "8+8"; AbstractCalculator cal = new Plus(); int result = cal.calculate(exp,"+"); System.out.println(result); } }
輸出:16
二、類(lèi)之間關(guān)系 觀察者(Observer)包括這個(gè)模式在內(nèi)的接下來(lái)的四個(gè)模式,都是類(lèi)和類(lèi)之間的關(guān)系,不涉及到繼承,學(xué)的時(shí)候應(yīng)該 記得歸納,記得本文最開(kāi)始的那個(gè)圖。觀察者模式很好理解,類(lèi)似于郵件訂閱和 RSS 訂閱,當(dāng)我們?yōu)g覽一些博客或 wiki 時(shí),經(jīng)常會(huì)看到 RSS 圖標(biāo),就這的意思是,當(dāng)你訂閱了該文章,如果后續(xù)有更新,會(huì)及時(shí)通知你。其實(shí),簡(jiǎn)單來(lái)講就一句話:當(dāng)一個(gè)對(duì)象變化時(shí),其它依賴(lài)該對(duì)象的對(duì)象都會(huì)收到通知,并且隨著變化!對(duì)象之間是一種一對(duì)多的關(guān)系。先來(lái)看看關(guān)系圖:
我解釋下這些類(lèi)的作用:MySubject 類(lèi)就是我們的主對(duì)象,Observer1 和 Observer2 是依賴(lài)于MySubject 的對(duì)象,當(dāng) MySubject 變化時(shí),Observer1 和 Observer2 必然變化。AbstractSubject類(lèi)中定義著需要監(jiān)控的對(duì)象列表,可以對(duì)其進(jìn)行修改:增加或刪除被監(jiān)控對(duì)象,且當(dāng) MySubject變化時(shí),負(fù)責(zé)通知在列表內(nèi)存在的對(duì)象。我們看實(shí)現(xiàn)代碼:
一個(gè) Observer 接口:
public interface Observer { void update(); }
兩個(gè)實(shí)現(xiàn)類(lèi):
public class Observer1 implements Observer { @Override public void update() { System.out.println("observer1 has received!"); } }
public class Observer2 implements Observer{ @Override public void update() { System.out.println("observer2 has received!"); } }
Subject 接口及實(shí)現(xiàn)類(lèi):
public interface Subject { /*增加觀察者*/ void add(Observer observer); /*刪除觀察者*/ void del(Observer observer); /*通知所有的觀察者*/ void notifyObservers(); /*自身的操作*/ void operation(); }
public abstract class AbstractSubject implements Subject { private Vectorvector = new Vector (); @Override public void add(Observer observer) { vector.add(observer); } @Override public void del(Observer observer) { vector.remove(observer); } @Override public void notifyObservers() { Enumeration enumo = vector.elements(); while(enumo.hasMoreElements()){ enumo.nextElement().update(); } } }
public class MySubject extends AbstractSubject { @Override public void operation() { System.out.println("update self!"); notifyObservers(); } }
測(cè)試類(lèi):
public class ObserverTest { public static void main(String[] args) { MySubject sub = new MySubject(); sub.add(new Observer1()); sub.add(new Observer2()); sub.operation(); } }
輸出:
update self!
observer1 has received!
observer2 has received!
順序訪問(wèn)集合中的對(duì)象,一般來(lái)說(shuō),集合中非常常見(jiàn),如果對(duì)集合類(lèi)比較熟悉的話,理解本模式會(huì)十分輕松。這句話包含兩層意思:一是需要遍歷的對(duì)象,即聚集對(duì)象,二是迭代器對(duì)象,用于對(duì)聚集對(duì)象進(jìn)行遍歷訪問(wèn)。我們看下關(guān)系圖
這個(gè)思路和我們常用的一模一樣,MyCollection 中定義了集合的一些操作,MyIterator 中定義了一系列迭代操作,且持有 Collection 實(shí)例,我們來(lái)看看實(shí)現(xiàn)代碼:
兩個(gè)接口 :
public interface Collection { Iterator iterator(); /*取得集合元素*/ Object get(int i); /*取得集合大小*/ int size(); }
public interface Iterator { //前移 Object previous(); //后移 Object next(); boolean hasNext(); //取得第一個(gè)元素 Object first(); }
兩個(gè)實(shí)現(xiàn):
public class MyCollection implements Collection { public String string[] = {"A","B","C","D","E"}; @Override public Iterator iterator() { return new MyIterator( this ); } @Override public Object get(int i) { return string[i]; } @Override public int size() { return string.length; } }
public class MyIterator implements Iterator { private Collection collection; private int pos = -1; public MyIterator(Collection collection) { this.collection = collection; } @Override public Object previous() { if (pos > 0) { pos--; } return collection.get(pos); } @Override public Object next() { if (pos < collection.size() - 1) { pos++; } return collection.get(pos); } @Override public boolean hasNext() { if (pos < collection.size() - 1) { return true; }else { return false; } } @Override public Object first() { pos = 0; return collection.get(pos); } }
測(cè)試類(lèi):
public class Test { public static void main(String[] args) { MyCollection collection = new MyCollection(); Iterator it = collection.iterator(); while (it.hasNext()) { System.out.println(it.next()); } } }
輸出:A B C D E
此處我們貌似模擬了一個(gè)集合類(lèi)的過(guò)程,感覺(jué)是不是很爽?其實(shí) JDK 中各個(gè)類(lèi)也都是這些基本的東西,加一些設(shè)計(jì)模式,再加一些優(yōu)化放到一起的,只要我們把這些東西學(xué)會(huì)了,掌握好了,我們也可以寫(xiě)出自己的集合類(lèi),甚至框架!
接下來(lái)我們將要談?wù)勜?zé)任鏈模式,有多個(gè)對(duì)象,每個(gè)對(duì)象持有對(duì)下一個(gè)對(duì)象的引用,這樣就會(huì)形成一條鏈,請(qǐng)求在這條鏈上傳遞,直到某一對(duì)象決定處理該請(qǐng)求。但是發(fā)出者并不清楚到底最終那個(gè)對(duì)象會(huì)處理該請(qǐng)求,所以,責(zé)任鏈模式可以實(shí)現(xiàn),在隱瞞客戶(hù)端的情況下,對(duì)系統(tǒng)進(jìn)行動(dòng)態(tài)的調(diào)整。先看看關(guān)系圖:
Abstracthandler 類(lèi)提供了 get 和 set 方法,方便 MyHandle 類(lèi)設(shè)置和修改引用對(duì)象,MyHandle類(lèi)是核心,實(shí)例化后生成一系列相互持有的對(duì)象,構(gòu)成一條鏈 。
public interface Handler { void operator(); }
public abstract class AbstractHandler { private Handler handler; public Handler getHandler() { return handler; } public void setHandler(Handler handler) { this.handler = handler; } }
public class MyHandler extends AbstractHandler implements Handler { private String name; public MyHandler(String name) { this.name = name; } @Override public void operator() { System.out.println(name + "deal!"); if (null != getHandler()) { getHandler().operator(); } } }
public class Test { public static void main(String[] args) { MyHandler h1 = new MyHandler("h1"); MyHandler h2 = new MyHandler("h2"); MyHandler h3 = new MyHandler("h3"); h1.setHandler(h2); h2.setHandler(h3); h1.operator(); } }
輸出:
h1deal!
h2deal!
h3deal!
此處強(qiáng)調(diào)一點(diǎn)就是,鏈接上的請(qǐng)求可以是一條鏈,可以是一個(gè)樹(shù),還可以是一個(gè)環(huán),模式本身不約束這個(gè),需要我們自己去實(shí)現(xiàn),同時(shí),在一個(gè)時(shí)刻,命令只允許由一個(gè)對(duì)象傳給另一個(gè)對(duì)象,而不允許傳給多個(gè)對(duì)象 。
命令模式很好理解,舉個(gè)例子,司令員下令讓士兵去干件事情,從整個(gè)事情的角度來(lái)考慮,司令員的作用是,發(fā)出口令,口令經(jīng)過(guò)傳遞,傳到了士兵耳朵里,士兵去執(zhí)行。這個(gè)過(guò)程好在,三者相互解耦,任何一方都不用去依賴(lài)其他,只需要做好自己的事兒就行,司令員要的是結(jié)果,不會(huì)去關(guān)注到底士兵是怎么實(shí)現(xiàn)的。我們看看關(guān)系圖:
public interface Command { void exe(); }
public class MyCommand implements Command { private Receiver receiver; public MyCommand(Receiver receiver) { this.receiver = receiver; } @Override public void exe() { receiver.action(); } }
public class Receiver { public void action() { System.out.println("command received!"); } }
public class Invoker { private Command command; public Invoker(Command command) { this.command = command; } public void action() { command.exe(); } }
public class Test { public static void main(String[] args) { Receiver receiver = new Receiver(); MyCommand cmd = new MyCommand(receiver); Invoker invoker = new Invoker(cmd); invoker.action(); } }
輸出:command received!
命令模式的目的就是達(dá)到命令的發(fā)出者和執(zhí)行者之間解耦,實(shí)現(xiàn)請(qǐng)求和執(zhí)行分開(kāi),熟悉 Struts 的同學(xué)應(yīng)該知道,Struts 其實(shí)就是一種將請(qǐng)求和呈現(xiàn)分離的技術(shù),其中必然涉及命令模式的思想!
其實(shí)每個(gè)設(shè)計(jì)模式都是很重要的一種思想,看上去很熟,其實(shí)是因?yàn)槲覀冊(cè)趯W(xué)到的東西中都有涉及,盡管有時(shí)我們并不知道,其實(shí)在 Java 本身的設(shè)計(jì)之中處處都有體現(xiàn),像 AWT、JDBC、集合類(lèi)、IO 管道或者是 Web 框架,里面設(shè)計(jì)模式無(wú)處不在。因?yàn)槲覀兤邢?,很難講每一個(gè)設(shè)計(jì)模式都講的很詳細(xì),不過(guò)我會(huì)盡我所能,盡量在有限的空間和篇幅內(nèi),把意思寫(xiě)清楚了,更好讓大家明白。
主要目的是保存一個(gè)對(duì)象的某個(gè)狀態(tài),以便在適當(dāng)?shù)臅r(shí)候恢復(fù)對(duì)象,個(gè)人覺(jué)得叫備份模式更形象些,通俗的講下:假設(shè)有原始類(lèi) A,A 中有各種屬性,A 可以決定需要備份的屬性,備忘錄類(lèi) B 是用來(lái)存儲(chǔ) A 的一些內(nèi)部狀態(tài),類(lèi) C 呢,就是一個(gè)用來(lái)存儲(chǔ)備忘錄的,且只能存儲(chǔ),不能修改等操作。做個(gè)圖來(lái)分析一下:
Original 類(lèi)是原始類(lèi),里面有需要保存的屬性 value 及創(chuàng)建一個(gè)備忘錄類(lèi),用來(lái)保存 value 值。Memento 類(lèi)是備忘錄類(lèi),Storage 類(lèi)是存儲(chǔ)備忘錄的類(lèi),持有 Memento 類(lèi)的實(shí)例,該模式很好理解。直接看源碼:
public class Original { private String value; public Original(String value) { this.value = value; } public Memento createMemento() { return new Memento(value); } public void restoreMemento(Memento memento) { this.value = memento.getValue(); } public String getValue() { return value; } public void setValue(String value) { this.value = value; } }
public class Memento { private String value; public Memento(String value) { this.value = value; } public String getValue() { return value; } public void setValue(String value) { this.value = value; } }
public class Storage { private Memento memento; public Storage(Memento memento) { this.memento = memento; } public Memento getMemento() { return memento; } public void setMemento(Memento memento) { this.memento = memento; } }
測(cè)試類(lèi):
public class Test { public static void main(String[] args) { // 創(chuàng)建原始類(lèi) Original origi = new Original("egg"); // 創(chuàng)建備忘錄 Storage storage = new Storage(origi.createMemento()); // 修改原始類(lèi)的狀態(tài) System.out.println("初始化狀態(tài)為:" + origi.getValue()); origi.setValue("niu"); System.out.println("修改后的狀態(tài)為:" + origi.getValue()); // 回復(fù)原始類(lèi)的狀態(tài) origi.restoreMemento(storage.getMemento()); System.out.println("恢復(fù)后的狀態(tài)為:" + origi.getValue()); } }
輸出:
初始化狀態(tài)為:egg
修改后的狀態(tài)為:niu
恢復(fù)后的狀態(tài)為:egg
簡(jiǎn)單描述下:新建原始類(lèi)時(shí),value 被初始化為 egg,后經(jīng)過(guò)修改,將 value 的值置為 niu,最后倒數(shù)第二行進(jìn)行恢復(fù)狀態(tài),結(jié)果成功恢復(fù)了。其實(shí)我覺(jué)得這個(gè)模式叫“備份-恢復(fù)”模式最形象。
核心思想就是:當(dāng)對(duì)象的狀態(tài)改變時(shí),同時(shí)改變其行為,很好理解!就拿 QQ 來(lái)說(shuō),有幾種狀態(tài),在線、隱身、忙碌等,每個(gè)狀態(tài)對(duì)應(yīng)不同的操作,而且你的好友也能看到你的狀態(tài),所以,狀態(tài)模式就兩點(diǎn):1、可以通過(guò)改變狀態(tài)來(lái)獲得不同的行為。2、你的好友能同時(shí)看到你的變化。看圖:
public class State { private String value; public void method1() { System.out.println("execute the first opt!"); } public void method2() { System.out.println("execute the second opt!"); } public String getValue() { return value; } public void setValue(String value) { this.value = value; } }
public class Context { private State state; public void method() { if (state.getValue().equals("state1")) { state.method1(); } else if (state.getValue().equals("state2")) { state.method2(); } } public Context(State state) { this.state = state; } public State getState() { return state; } public void setState(State state) { this.state = state; } }
測(cè)試類(lèi):
public class Test { public static void main(String[] args) { State state = new State(); Context context = new Context(state); //設(shè)置第一種狀態(tài) state.setValue("state1"); context.method(); //設(shè)置第二種狀態(tài) state.setValue("state2"); context.method(); } }
輸出:
execute the first opt!
execute the second opt!
根據(jù)這個(gè)特性,狀態(tài)模式在日常開(kāi)發(fā)中用的挺多的,尤其是做網(wǎng)站的時(shí)候,我們有時(shí)希望根據(jù)對(duì)象的某一屬性,區(qū)別開(kāi)他們的一些功能,比如說(shuō)簡(jiǎn)單的權(quán)限控制等 。
訪問(wèn)者模式把數(shù)據(jù)結(jié)構(gòu)和作用于結(jié)構(gòu)上的操作解耦合,使得操作集合可相對(duì)自由地演化。訪問(wèn)者模式適用于數(shù)據(jù)結(jié)構(gòu)相對(duì)穩(wěn)定算法又易變化的系統(tǒng)。因?yàn)樵L問(wèn)者模式使得算法操作增加變得容易。若系統(tǒng)數(shù)據(jù)結(jié)構(gòu)對(duì)象易于變化,經(jīng)常有新的數(shù)據(jù)對(duì)象增加進(jìn)來(lái),則不適合使用訪問(wèn)者模式。訪問(wèn)者模式的優(yōu)點(diǎn)是增加操作很容易,因?yàn)樵黾硬僮饕馕吨黾有碌脑L問(wèn)者。訪問(wèn)者模式將有關(guān)行為集中到一個(gè)訪問(wèn)者對(duì)象中,其改變不影響系統(tǒng)數(shù)據(jù)結(jié)構(gòu)。其缺點(diǎn)就是增加新的數(shù)據(jù)結(jié)構(gòu)很困難?!?From 百科
簡(jiǎn)單來(lái)說(shuō),訪問(wèn)者模式就是一種分離對(duì)象數(shù)據(jù)結(jié)構(gòu)與行為的方法,通過(guò)這種分離,可達(dá)到為一個(gè)被訪問(wèn)者動(dòng)態(tài)添加新的操作而無(wú)需做其它的修改的效果。簡(jiǎn)單關(guān)系圖:
public interface Visitor { void visit(Subject sub); }
public class MyVisitor implements Visitor { @Override public void visit(Subject sub) { System.out.println("visit the subjcet:" + sub.getSubject()); } }
Subject 類(lèi),accept 方法,接受將要訪問(wèn)它的對(duì)象,getSubject()獲取將要被訪問(wèn)的屬性,
public interface Subject { void accept(Visitor visitor); String getSubject(); }
public class MySubject implements Subject { @Override public void accept(Visitor visitor) { visitor.visit(this); } @Override public String getSubject() { return "love"; } }
測(cè)試類(lèi):
public class Test { public static void main(String[] args) { Visitor visitor = new MyVisitor(); Subject sub = new MySubject(); sub.accept(visitor); } }
輸出:visit the subject:love
該模式適用場(chǎng)景:如果我們想為一個(gè)現(xiàn)有的類(lèi)增加新功能,不得不考慮幾個(gè)事情:1、新功能會(huì)不會(huì)與現(xiàn)有功能出現(xiàn)兼容性問(wèn)題?2、以后會(huì)不會(huì)再需要添加?3、如果類(lèi)不允許修改代碼怎么辦?面對(duì)這些問(wèn)題,最好的解決方法就是使用訪問(wèn)者模式,訪問(wèn)者模式適用于數(shù)據(jù)結(jié)構(gòu)相對(duì)穩(wěn)定的系統(tǒng),把數(shù)據(jù)結(jié)構(gòu)和算法解耦,
中介者模式也是用來(lái)降低類(lèi)類(lèi)之間的耦合的,因?yàn)槿绻?lèi)類(lèi)之間有依賴(lài)關(guān)系的話,不利于功能的拓展和維護(hù),因?yàn)橹灰薷囊粋€(gè)對(duì)象,其它關(guān)聯(lián)的對(duì)象都得進(jìn)行修改。如果使用中介者模式,只需關(guān)心和 Mediator 類(lèi)的關(guān)系,具體類(lèi)類(lèi)之間的關(guān)系及調(diào)度交給 Mediator 就行,這有點(diǎn)像spring 容器的作用。先看看圖:
User 類(lèi)統(tǒng)一接口,User1 和 User2 分別是不同的對(duì)象,二者之間有關(guān)聯(lián),如果不采用中介者模式,則需要二者相互持有引用,這樣二者的耦合度很高,為了解耦,引入了 Mediator 類(lèi),提供統(tǒng)一接口,MyMediator 為其實(shí)現(xiàn)類(lèi),里面持有 User1 和 User2 的實(shí)例,用來(lái)實(shí)現(xiàn)對(duì) User1和 User2 的控制。這樣 User1 和 User2 兩個(gè)對(duì)象相互獨(dú)立,他們只需要保持好和 Mediator 之間的關(guān)系就行,剩下的全由 MyMediator 類(lèi)來(lái)維護(hù)!基本實(shí)現(xiàn):
public interface Mediator { void createMediator(); void workAll(); }
public class MyMediator implements Mediator { private User user1; private User user2; public User getUser1() { return user1; } public User getUser2() { return user2; } @Override public void createMediator() { user1 = new User1(this); user2 = new User2(this); } @Override public void workAll() { user1.work(); user2.work(); } }
public abstract class User { private Mediator mediator; public abstract void work(); public Mediator getMediator() { return mediator; } public User(Mediator mediator) { this.mediator = mediator; } }
public class User1 extends User { public User1(Mediator mediator) { super(mediator); } @Override public void work() { System.out.println("user1 exe!"); } }
public class User2 extends User { public User2(Mediator mediator) { super(mediator); } @Override public void work() { System.out.println("user2 exe!"); } }
測(cè)試類(lèi):
public class Test { public static void main(String[] args) { MyMediator mediator = new MyMediator(); mediator.createMediator(); mediator.workAll(); } }
輸出:
user1 exe!
user2 exe!
解釋器模式是我們暫時(shí)的最后一講,一般主要應(yīng)用在 OOP 開(kāi)發(fā)中的編譯器的開(kāi)發(fā)中,所以適用面比較窄。
Context 類(lèi)是一個(gè)上下文環(huán)境類(lèi),Plus 和 Minus 分別是用來(lái)計(jì)算的實(shí)現(xiàn),代碼如下:
public interface Expression { int interpret(Context context); }
public class Plus implements Expression { @Override public int interpret(Context context) { return context.getNum1() + context.getNum2(); } }
public class Minus implements Expression { @Override public int interpret(Context context) { return context.getNum1() - context.getNum2(); } }
public class Context { private int num1; private int num2; public Context(int num1, int num2) { this.num1 = num1; this.num2 = num2; } public int getNum1() { return num1; } public void setNum1(int num1) { this.num1 = num1; } public int getNum2() { return num2; } public void setNum2(int num2) { this.num2 = num2; } }
測(cè)試類(lèi):
public class Test { public static void main(String[] args) { // 計(jì)算 9+2-8 的值 int result = new Minus().interpret((new Context(new Plus().interpret(new Context(9, 2)), 8))); System.out.println(result); } }
最后輸出正確的結(jié)果:3。
基本就這樣,解釋器模式用來(lái)做各種各樣的解釋器,如正則表達(dá)式等的解釋器等等!
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/71045.html
摘要:當(dāng)然,除了讓我們顯得更加專(zhuān)業(yè)之外,在自己所學(xué)習(xí)或者工作的項(xiàng)目中,適當(dāng)合理的使用設(shè)計(jì)模式,能夠給項(xiàng)目帶來(lái)很大的好處。 簡(jiǎn)單說(shuō)兩句 本文首發(fā)公眾號(hào)【一名打字員】 對(duì)不住各位老鐵了,年前說(shuō)好要更幾波JAVA的東西,又偷懶了,沒(méi)辦法,在這里用小錘錘偷偷錘了自己幾下。由于工作原因,更新時(shí)間不定,各位老鐵有問(wèn)題可以私聊我哈。 對(duì)于初學(xué)者或者是正在向中高級(jí)的Java程序猿(打字員)來(lái)說(shuō),時(shí)刻梳理自己...
摘要:分別為適配器模式,裝飾器模式,代理模式,外觀模式,橋接模式,組合模式,享元模式。設(shè)計(jì)模式五適配器模式適配器模式將某個(gè)對(duì)象的接生成器和協(xié)程的實(shí)現(xiàn)在這篇文章中,作者針對(duì)那些比較難以理解的概念,以一個(gè)更為通俗的方式去講明白。。 PHP 源碼注解 PHP 的詳細(xì)源碼注解 PHP 字符串操作整理 一些有關(guān)字符串的常用操作。 Redis 常見(jiàn)七種使用場(chǎng)景 (PHP 實(shí)戰(zhàn)) 這篇文章主要介紹利用 R...
摘要:推文用設(shè)計(jì)模式解構(gòu)三國(guó)是一種什么體驗(yàn)行為型設(shè)計(jì)模式一策略模式工廠模式優(yōu)化結(jié)構(gòu)狀態(tài)模式隨著狀態(tài)改變而改變行為。推文狀態(tài)機(jī)與狀態(tài)模式責(zé)任鏈模式多個(gè)對(duì)象依次處理請(qǐng)求前者指定后者。代理模式代理針對(duì)一個(gè)對(duì)象,為了增加控制等中介雙方都是多個(gè),為了解耦。 策略模式 選擇使用封裝好的一系列算法,可相互替換。 類(lèi)比:商店[Context]買(mǎi)完衣服買(mǎi)單[Stratege](現(xiàn)金[Concrete Stra...
摘要:類(lèi)共享,因此需要實(shí)現(xiàn)中的所有抽象方法,如果有的具體策略類(lèi)比較簡(jiǎn)單,但還是必須要去實(shí)現(xiàn)它的抽象方法,因此會(huì)增加不必要的開(kāi)銷(xiāo)參考設(shè)計(jì)模式十八策略模式對(duì)象行為型深入面向?qū)ο竽J脚c實(shí)踐第版 因?yàn)樽罱趯W(xué)策略模式,所以想先跳過(guò)創(chuàng)建型設(shè)計(jì)模式中得適配器模式 定義 策略模式,顧名思義,就是提供多個(gè)策略的模式,用戶(hù)在不同的情況下可以選擇不同的策略,比如商場(chǎng)的打折策略(不同節(jié)假日不同的折扣方式),旅游出...
摘要:設(shè)計(jì)模式分創(chuàng)建型模式,結(jié)構(gòu)型模式和行為型模式。責(zé)任鏈模式使多個(gè)對(duì)象都有機(jī)會(huì)處理請(qǐng)求,從而避免了請(qǐng)求的發(fā)送者和接受者之間的耦合關(guān)系。狀態(tài)模式的核心是封裝,通過(guò)狀態(tài)的變更引起行為的變更。 前言 最近加班是真的很多,無(wú)法騰出大塊時(shí)間來(lái)學(xué)習(xí)。設(shè)計(jì)模式又不想只更到一半半途而廢,想了又想,決定精簡(jiǎn),保證大家一看就懂(看完就忘...)。設(shè)計(jì)模式分創(chuàng)建型模式,結(jié)構(gòu)型模式和行為型模式。到目前為止,創(chuàng)建型...
摘要:設(shè)計(jì)模式的類(lèi)別設(shè)計(jì)模式一共分為種類(lèi)型,共種。屬于結(jié)構(gòu)型的設(shè)計(jì)模式適配器模式橋接模式裝飾模式組合模式外觀模式享元模式代理模式。問(wèn)題描述了應(yīng)該在何時(shí)使用設(shè)計(jì)模式。解決方案描述了設(shè)計(jì)的組成成分,它們之間的相互關(guān)系及各自的職責(zé)和協(xié)作方式。 設(shè)計(jì)模式概述 1. 設(shè)計(jì)模式是什么 我們?cè)谄綍r(shí)編寫(xiě)代碼的過(guò)程中,會(huì)遇到各種各樣的問(wèn)題,細(xì)想一下很多問(wèn)題的解決思路大致一樣的,這時(shí)候你就可以把解決問(wèn)題的思路整...
閱讀 2872·2021-11-19 11:30
閱讀 3133·2021-11-15 11:39
閱讀 1905·2021-08-03 14:03
閱讀 2079·2019-08-30 14:18
閱讀 2134·2019-08-30 11:16
閱讀 2288·2019-08-29 17:23
閱讀 2679·2019-08-28 18:06
閱讀 2619·2019-08-26 12:22