目錄
- 目錄
- 六大原則
- 建立型模式
- 工廠模式
- 适用場景
- 模式缺點
- 樣例
- 工廠方法模式
- 适用場景
- 模式缺點
- 樣例
- 抽象工廠方法模式
- 适用場景
- 模式缺點
- 樣例
- 單例模式
- 适用場景
- 模式缺點
- 樣例
- 建造者模式
- 适用場景
- 模式缺點
- 樣例
- 原型模式
- 适用場景
- 模式缺點
- 樣例
- 工廠模式
- 結構型模式
- 擴充卡模式
- 适用場景
- 模式缺點
- 樣例
- 橋接模式(稱為嫁接更直覺)
- 适用場景
- 模式缺點
- 樣例
- 過濾器模式
- 适用場景
- 模式缺點
- 樣例
- 組合模式(樹型模式更貼切)
- 适用場景
- 模式缺點
- 樣例
- 裝飾器模式
- 适用場景
- 模式缺點
- 樣例
- 外觀模式
- 适用場景
- 模式缺點
- 樣例
- 享元模式
- 适用場景
- 模式缺點
- 樣例
- 代理模式
- 适用場景
- 模式缺點
- 樣例
- 擴充卡模式
- 行為型模式
- 責任鍊模式
- 适用場景
- 模式缺點
- 樣例
- 指令模式
- 适用場景
- 模式缺點
- 樣例
- 解釋器模式
- 适用場景
- 模式缺點
- 樣例
- 疊代器模式
- 适用場景
- 模式缺點
- 樣例
- 中介者模式
- 适用場景
- 模式缺點
- 樣例
- 備忘錄模式
- 适用場景
- 模式缺點
- 樣例
- 觀察者模式(或者叫釋出-訂閱模式)
- 适用場景
- 模式缺點
- 樣例
- 狀态模式(或者叫釋出-訂閱模式)
- 适用場景
- 模式缺點
- 樣例
- 空對象模式
- 适用場景
- 模式缺點
- 樣例
- 政策模式
- 适用場景
- 模式缺點
- 樣例
- 模闆模式
- 适用場景
- 模式缺點
- 樣例
- 通路者模式
- 适用場景
- 模式缺點
- 樣例
- 責任鍊模式
六大原則
- 開閉原則(Open Close Principle)
開閉原則的意思是:對擴充開放,對修改關閉。在程式需要進行拓展的時候,不能去修改原有的代碼,實作一個熱插拔的效果。簡言之,是為了使程式的擴充性好,易于維護和更新。想要達到這樣的效果,我們需要使用接口和抽象類,後面的具體設計中我們會提到這點。
- 裡氏代換原則(Liskov Substitution Principle)
裡氏代換原則是面向對象設計的基本原則之一。 裡氏代換原則中說,任何基類可以出現的地方,子類一定可以出現。LSP 是繼承複用的基石,隻有當派生類可以替換掉基類,且軟體機關的功能不受到影響時,基類才能真正被複用,而派生類也能夠在基類的基礎上增加新的行為。裡氏代換原則是對開閉原則的補充。實作開閉原則的關鍵步驟就是抽象化,而基類與子類的繼承關系就是抽象化的具體實作,是以裡氏代換原則是對實作抽象化的具體步驟的規範。
- 依賴倒轉原則(Dependence Inversion Principle)
這個原則是開閉原則的基礎,具體内容:針對接口程式設計,依賴于抽象而不依賴于具體。
- 接口隔離原則(Interface Segregation Principle)
這個原則的意思是:使用多個隔離的接口,比使用單個接口要好。它還有另外一個意思是:降低類之間的耦合度。由此可見,其實設計模式就是從大型軟體架構出發、便于更新和維護的軟體設計思想,它強調降低依賴,降低耦合。
- 迪米特法則,又稱最少知道原則(Demeter Principle)
最少知道原則是指:一個實體應當盡量少地與其他實體之間發生互相作用,使得系統功能子產品相對獨立。
- 合成複用原則(Composite Reuse Principle)
合成複用原則是指:盡量使用合成/聚合的方式,而不是使用繼承。
建立型模式
這些設計模式提供了一種在建立對象的同時隐藏建立邏輯的方式,而不是使用 new 運算符直接執行個體化對象。這使得程式在判斷針對某個給定執行個體需要建立哪些對象時更加靈活。
工廠模式
工廠模式(Factory Pattern)是 Java 中最常用的設計模式之一。這種類型的設計模式屬于建立型模式,它提供了一種建立對象的最佳方式。
在工廠模式中,我們在建立對象時不會對用戶端暴露建立邏輯,并且是通過使用一個共同的接口來指向新建立的對象。
适用場景
- 很多地方都需要建立某種對象時。
- 建立對象操作比較複雜,同時接口又需要統一時,同時又想要對外屏蔽時。
- 想要能夠友善地擴充類型實作時。
模式缺點
- 工廠對于具體實作類型會産生依賴。
- 類型非常多時工廠類會變得非常複雜。
樣例
public interface Shape {}
public class Circle implements Shape {}
public class Square implements Shape {}
public class ShapeFactory {
public Shape getShape1() { return new Circle(); }
public Shape getShape2() { return new Square(); }
public Shape getShape(String shape) {
switch (shape) {
case "circle": return new Circle();
case "square": return new Square();
}
return null;
}
}
工廠方法模式
工廠方法(Factory Method)模式的意義是定義一個建立産品對象的工廠接口,将實際建立工作推遲到子類當中。核心工廠類不再負責産品的建立,這樣核心類成為一個抽象工廠角色,僅負責具體工廠子類必須實作的接口,這樣進一步抽象化的好處是使得工廠方法模式可以使系統在不修改具體工廠角色的情況下引進新的産品。
工廠方法模式是簡單工廠模式的衍生,解決了許多簡單工廠模式的問題。首先完全實作‘開-閉 原則’,實作了可擴充。其次更複雜的層次結構,可以應用于産品結果複雜的場合。
适用場景
- 同“工廠方法模式”
- 不希望每次增加一個類型時都需要修改工廠基類時。
模式缺點
- 代碼結構變得更複雜了。
- 工廠也變得更多了。
樣例
public interface Shape {}
public class Circle implements Shape {}
public class Square implements Shape {}
public interface ShapeAbstractFactory {
Shape getShape();
}
public class CircleFactory implements ShapeAbstractFactory {
public Shape getShape() { return new Circle(); }
}
public class SquareFactory implements ShapeAbstractFactory {
public Shape getShape() { return new Square(); }
}
抽象工廠方法模式
抽象工廠模式(Abstract Factory Pattern)隸屬于設計模式中的建立型模式,用于産品族的建構。抽象工廠是所有形态的工廠模式中最為抽象和最具一般性的一種形态。抽象工廠是指當有多個抽象角色時使用的一種工廠模式。抽象工廠模式可以向用戶端提供一個接口,使用戶端在不必指定産品的具體情況下,建立多個産品族中的産品對象。
工廠模式中的每一個形态都是針對一定問題的解決方案,工廠方法針對的是一類産品;而抽象工廠模式針對的是多類産品,一類産品内又有多種實作類型的情況。
适用場景
- 通常情況下産品需要成套使用。
- 每套解決方案内部又存在多種組合解決方案。
模式缺點
- 代碼結構變得更複雜了。
樣例
public interface Shape {}
public class Circle implements Shape {}
public class Square implements Shape {}
public interface color {}
public class Red implements Color {}
public class Blue implements Color {}
public interface AbstractFactory {
Shape getShape();
Red getColor();
}
public class Factory1 implements AbstractFactory { ... }
public class Factory2 implements AbstractFactory { ... }
單例模式
單例模式(Singleton Pattern)是 Java 中最簡單的設計模式之一。這種類型的設計模式屬于建立型模式,它提供了一種建立對象的最佳方式。
這種模式涉及到一個單一的類,該類負責建立自己的對象,同時確定隻有單個對象被建立。這個類提供了一種通路其唯一的對象的方式,可以直接通路,不需要執行個體化該類的對象。
注意:單例類隻能有一個執行個體。
适用場景
- 邏輯相對簡單的情況。
- 想要避免執行個體過多占用系統資源的情況。
模式缺點
- 修改單例對象的屬性時,需要考慮多線程和高并發場景。
樣例
public class Singleton {
private volatile static Singleton singleton;
private Singleton (){} // 不允許通過new來執行個體化對象
public static Singleton getSingleton() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}
建造者模式
建造者模式(Builder Pattern)使用多個簡單的對象一步一步建構成一個複雜的對象。這種類型的設計模式屬于建立型模式,它提供了一種建立對象的最佳方式。
一個 Builder 類會一步一步構造最終的對象。該 Builder 類是獨立于其他對象的。
适用場景
- 對象内部較為複雜,同時需要分離對象的建立與建構行為時。
- 一些内部基本部件相對穩定不變,而隻是其組合經常變化的時候。
- 初始化一個對象時,參數過多,或者很多參數具有預設值時。
模式缺點
- 不适合建立差異性很大的産品類。
- 如内部變化複雜,會有很多的建造類。
樣例
public interface Porudct { }
public interface Builder {
Product buildPart(Product p);
}
public interface Director {
Product getProduct();
}
原型模式
原型模式(Prototype Pattern)是用于建立重複的對象,同時又能保證性能。這種類型的設計模式屬于建立型模式,它提供了一種建立對象的最佳方式。
這種模式是實作了一個原型接口,該接口用于建立目前對象的克隆。當直接建立對象的代價比較大時,則采用這種模式。例如,一個對象需要在一個高代價的資料庫操作之後被建立。我們可以緩存該對象,在下一個請求時傳回它的克隆,在需要的時候更新資料庫,以此來減少資料庫調用。
适用場景
- 當一個系統應該獨立于它的産品建立,構成和表示時。
- 當要執行個體化的類是在運作時指定時,例如,通過動态裝載。
- 為了避免一個與産品類層次平行的工廠類層次時。
- 當一個類的執行個體隻能有幾個不同狀态組合中的一種時。建立相應數目的原型并克隆它們可能比每次用何時的狀态手工執行個體化該類更友善一些。
模式缺點
- 配備克隆方法需要對類的功能進行通盤考慮,這對于全新的類不是很難,但對于已有的類不一定容易,特别當一個類引用不支援串行化的間接對象,或者引用含有循環結構的時候。
- 必須實作Cloneable接口。
樣例
public interface Cloneable {
Object clone();
}
結構型模式
擴充卡模式
擴充卡模式(Adapter Pattern)是作為兩個不相容的接口之間的橋梁。這種類型的設計模式屬于結構型模式,它結合了兩個獨立接口的功能。這種模式涉及到一個單一的類,該類負責加入獨立的或不相容的接口功能。
适用場景
- 可以讓任何兩個沒有關聯的類一起運作。
- 提高了類的複用。
- 增加了類的透明度。
- 靈活性好。
模式缺點
- 過多地使用擴充卡,會讓系統非常零亂,不易整體進行把握。
- 由于 JAVA 至多繼承一個類,是以至多隻能适配一個适配者類,而且目标類必須是抽象類。
樣例
略,簡單來說就是随意調用,類似于行為型地中介者模式。
橋接模式(稱為嫁接更直覺)
橋接(Bridge)是用于把抽象化與實作化解耦,使得二者可以獨立變化。這種類型的設計模式屬于結構型模式,它通過提供抽象化和實作化之間的橋接結構,來實作二者的解耦。
這種模式涉及到一個作為橋接的接口,使得實體類的功能獨立于接口實作類。這兩種類型的類可被結構化改變而互不影響。
我們通過下面的執行個體來示範橋接模式(Bridge Pattern)的用法。其中,可以使用相同的抽象類方法但是不同的橋接實作類,來畫出不同顔色的圓。
适用場景
- 想要避免在抽象與實作之間存在永久綁定。
- 如果一個系統需要在構件的抽象化角色和具體化角色之間增加更多的靈活性,避免在兩個層次之間建立靜态的繼承聯系,通過橋接模式可以使它們在抽象層建立一個關聯關系。
- 對于那些不希望使用繼承或因為多層次繼承導緻系統類的個數急劇增加的系統,橋接模式尤為适用。
- 一個類存在兩個獨立變化的次元,且這兩個次元都需要進行擴充。
模式缺點
- 橋接模式的引入會增加系統的了解與設計難度,由于聚合關聯關系建立在抽象層,要求開發者針對抽象進行設計與程式設計。
樣例
略,簡單來說就是将多種次元的屬性從繼承關系轉化為組合關系。
過濾器模式
過濾器模式(Filter Pattern)或标準模式(Criteria Pattern)是一種設計模式,這種模式允許開發人員使用不同的标準來過濾一組對象,通過邏輯運算以解耦的方式把它們連接配接起來。這種類型的設計模式屬于結構型模式,它結合多個标準來獲得單一标準。
适用場景
- 設計人員将整個系統的輸入輸出行為了解為單個過濾器行為的疊加與組合。這樣可以将問題分解,化繁為簡。
- 任何兩個過濾器,隻要它們之間傳送的資料遵守共同的規約就可以相連接配接。每個過濾器都有自己獨立的輸入輸出接口,如果過濾器間傳輸的資料遵守其規約,隻要用管道将它們連接配接就可以正常工作。
- 整個系統易于維護和更新:舊的過濾器可以被替代,新的過濾器可以添加到已有的系統上。軟體的易于維護和更新是衡量軟體系統品質的重要名額之一。在管道-過濾器模型中,隻要遵守輸入輸出資料規約,任何一個過濾器都可以被另一個新的過濾器代替,同時為增強程式功能,可以添加新的過濾器。這樣,系統的可維護性和可更新性得到了保證。
- 支援并發執行,每個過濾器作為一個單獨的執行任務,可以與其它過濾器并發執行。過濾器的執行是獨立的。不依賴于其它過濾器的。
模式缺點
- 效率較低。
- 過濾器如果組合情況複雜,那麼會導緻過濾器之間的結構變得複雜并且難以維護。
樣例
public interface Filter {
List<Object> filter(List<Object> list);
}
組合模式(樹型模式更貼切)
組合模式(Composite Pattern),又叫部分整體模式,是用于把一組相似的對象當作一個單一的對象。組合模式依據樹形結構來組合對象,用來表示部分以及整體層次。這種類型的設計模式屬于結構型模式,它建立了對象組的樹形結構。
這種模式建立了一個包含自己對象組的類。該類提供了修改相同對象組的方式。
适用場景
- 想表示對象的部分-整體層次結構(樹形結構)。
- 希望使用者忽略組合對象與單個對象的不同,使用者将統一地使用組合結構中的所有對象。
模式缺點
- 暫無。
樣例
public interface Node {
List<Node> getSubNodeList();
}
裝飾器模式
裝飾器模式(Decorator Pattern)允許向一個現有的對象添加新的功能,同時又不改變其結構。這種類型的設計模式屬于結構型模式,它是作為現有的類的一個包裝。
這種模式建立了一個裝飾類,用來包裝原有的類,并在保持類方法簽名完整性的前提下,提供了額外的功能。
适用場景
- 動态地給一個對象添加一些額外的職責,但又不想增加很多子類的情況。
- 裝飾類和被裝飾類可以獨立發展,不會互相耦合,裝飾模式是繼承的一個替代模式,裝飾模式可以動态擴充一個實作類的功能。
模式缺點
- 多層裝飾比較複雜。
樣例
public interface Shape { }
public interface ShapeDecorator {
void setShape(Shape shape);
void doSomething();
}
外觀模式
外觀模式(Facade Pattern)隐藏系統的複雜性,并向用戶端提供了一個用戶端可以通路系統的接口。這種類型的設計模式屬于結構型模式,它向現有的系統添加一個接口,來隐藏系統的複雜性。
這種模式涉及到一個單一的類,該類提供了用戶端請求的簡化方法和對現有系統類方法的委托調用。
适用場景
- 為子系統中的一組接口提供一個一緻的界面,外觀模式定義了一個高層接口,這個接口使得這一子系統更加容易使用。
模式缺點
- 不符合開閉原則,如果要改東西很麻煩,繼承重寫都不合适。
樣例
public interface Shape { }
public interface ShapeMaker {
void doSomethingComplex();
}
享元模式
享元模式(Flyweight Pattern)主要用于減少建立對象的數量,以減少記憶體占用和提高性能。這種類型的設計模式屬于結構型模式,它提供了減少對象數量進而改善應用所需的對象結構的方式。
享元模式嘗試重用現有的同類對象,如果未找到比對的對象,則建立新對象。
适用場景
- 系統中有大量對象。
- 這些對象消耗大量記憶體。
- 這些對象的狀态大部分可以外部化。
- 這些對象可以按照内蘊狀态分為很多組,當把外蘊對象從對象中剔除出來時,每一組對象都可以用一個對象來代替。
- 系統不依賴于這些對象身份,這些對象是不可分辨的。
模式缺點
- 提高了系統的複雜度,需要分離出外部狀态和内部狀态,而且外部狀态具有固有化的性質,不應該随着内部狀态的變化而變化,否則會造成系統的混亂。
樣例
略,簡而言之就是單例的複雜情況。
代理模式
在代理模式(Proxy Pattern)中,一個類代表另一個類的功能。這種類型的設計模式屬于結構型模式。
适用場景
- 想在通路一個類時做一些控制。
模式缺點
- 由于在用戶端和真實主題之間增加了代理對象,是以有些類型的代理模式可能會造成請求的處理速度變慢。
- 實作代理模式需要額外的工作,有些代理模式的實作非常複雜。
樣例
略,簡單來說就是替換類型并做一些外在包裝。
行為型模式
責任鍊模式
顧名思義,責任鍊模式(Chain of Responsibility Pattern)為請求建立了一個接收者對象的鍊。這種模式給予請求的類型,對請求的發送者和接收者進行解耦。這種類型的設計模式屬于行為型模式。
在這種模式中,通常每個接收者都包含對另一個接收者的引用。如果一個對象不能處理該請求,那麼它會把相同的請求傳給下一個接收者,依此類推。
适用場景
- 降低耦合度。它将請求的發送者和接收者解耦。
- 簡化了對象。使得對象不需要知道鍊的結構。
- 增強給對象指派職責的靈活性。通過改變鍊内的成員或者調動它們的次序,允許動态地新增或者删除責任。
- 增加新的請求處理類很友善。
模式缺點
- 不能保證請求一定被接收。
- 系統性能将受到一定影響,而且在進行代碼調試時不太友善,可能會造成循環調用。
- 可能不容易觀察運作時的特征,有礙于除錯。
樣例
public interface Chain {
Chain nextChain();
void doSomething();
}
指令模式
指令模式(Command Pattern)是一種資料驅動的設計模式,它屬于行為型模式。請求以指令的形式包裹在對象中,并傳給調用對象。調用對象尋找可以處理該指令的合适的對象,并把該指令傳給相應的對象,該對象執行指令。
适用場景
- 行為請求者與行為實作者需要互相分離。
- 需要容易地添加新指令。
- 系統需要支援指令的撤銷(Undo)操作和恢複(Redo)操作時,也可以考慮使用指令模式。
模式缺點
- 使用指令模式可能會導緻某些系統有過多的具體指令類。
樣例
public interface Receiver { void doAction(); }
public interface Command { void execute(); }
public interface Invoker { void execute(); }
解釋器模式
解釋器模式(Interpreter Pattern)提供了評估語言的文法或表達式的方式,它屬于行為型模式。這種模式實作了一個表達式接口,該接口解釋一個特定的上下文。這種模式被用在 SQL 解析、符号處理引擎等。
适用場景
- 可以将一個需要解釋執行的語言中的句子表示為一個抽象文法樹。
- 一些重複出現的問題可以用一種簡單的語言來進行表達。
- 一個簡單文法需要解釋的場景。
模式缺點
- 可利用場景比較少。
- 對于複雜的文法比較難維護。
- 解釋器模式會引起類膨脹。
- 解釋器模式采用遞歸調用方法。
樣例
public interface Expression { boolean interpret(String context); }
public class TerminalExpression implements Expression { …… }
public class AndExpression implements Expression { …… }
疊代器模式
疊代器模式(Iterator Pattern)是 Java 和 .Net 程式設計環境中非常常用的設計模式。這種模式用于順序通路集合對象的元素,不需要知道集合對象的底層表示。
适用場景
- 通路一個聚合對象的内容而無須暴露它的内部表示。
- 需要為聚合對象提供多種周遊方式。
- 為周遊不同的聚合結構提供一個統一的接口。
模式缺點
- 由于疊代器模式将存儲資料和周遊資料的職責分離,增加新的聚合類需要對應增加新的疊代器類,類的個數成對增加,這在一定程度上增加了系統的複雜性。
樣例
public interface Iterator {
Obejct first();
boolean hasNext();
Object next();
}
public interface Aggregate { Iterator createIterator(); }
中介者模式
中介者模式(Mediator Pattern)是用來降低多個對象和類之間的通信複雜性。這種模式提供了一個中介類,該類通常處理不同類之間的通信,并支援松耦合,使代碼易于維護。中介者模式屬于行為型模式。
适用場景
- 降低了類的複雜度,将一對多轉化成了一對一。
- 各個類之間的解耦。
- 符合迪米特原則。
模式缺點
- 中介者會龐大,變得複雜難以維護。
樣例
public interface Mediator { void doAllThings(); }
備忘錄模式
備忘錄模式(Memento Pattern)儲存一個對象的某個狀态,以便在适當的時候恢複對象。備忘錄模式屬于行為型模式。
适用場景
- 給使用者提供了一種可以恢複狀态的機制,可以使使用者能夠比較友善地回到某個曆史的狀态。
- 實作了資訊的封裝,使得使用者不需要關心狀态的儲存細節。
模式缺點
- 消耗資源。如果類的成員變量過多,勢必會占用比較大的資源,而且每一次儲存都會消耗一定的記憶體。
樣例
public interface Memento {
void setState(int state);
int getState();
}
public interface Originator {
void restore(Memento memento);
Memento createMemento();
}
public interface Caretaker {
Memento getMemento(int i);
void addMemento(Memento memento);
}
觀察者模式(或者叫釋出-訂閱模式)
當對象間存在一對多關系時,則使用觀察者模式(Observer Pattern)。比如,當一個對象被修改時,則會自動通知它的依賴對象。觀察者模式屬于行為型模式。
适用場景
- 當一個抽象模型有兩個方面,其中一個方面依賴于另一方面。将這二者封裝在獨立的對象中以使它們可以各自獨立地改變和複用。
- 當對一個對象的改變需要同時(通知)改變其他對象,而不知道具體有多少對象需要被改變。
- 當一個對象必須通知其他對象,而它又不能假定其他對象是誰。換言之,不希望這些對象是緊密耦合的。
模式缺點
- 如果一個被觀察者對象有很多的直接和間接的觀察者的話,将所有的觀察者都通知到會花費很多時間。
- 如果在觀察者和觀察目标之間有循環依賴的話,觀察目标會觸發它們之間進行循環調用,可能導緻系統崩潰。
- 觀察者模式沒有相應的機制讓觀察者知道所觀察的目标對象是怎麼發生變化的,而僅僅隻是知道觀察目标發生了變化。
樣例
public interface Observer {
void update();
}
public interface Subject {
void attach(Observer o)
void detach(Observer o);
void notify();
}
狀态模式(或者叫釋出-訂閱模式)
在狀态模式(State Pattern)中,類的行為是基于它的狀态改變的。這種類型的設計模式屬于行為型模式。在狀态模式中,我們建立表示各種狀态的對象和一個行為随着狀态對象改變而改變的 context 對象。
适用場景
- 行為随狀态改變而改變的場景。
- 條件、分支語句的代替者。
模式缺點
- 狀态模式的使用必然會增加系統類和對象的個數。
- 狀态模式的結構與實作都較為複雜,如果使用不當将導緻程式結構和代碼的混亂。
- 狀态模式對"開閉原則"的支援并不太好,對于可以切換狀态的狀态模式,增加新的狀态類需要修改那些負責狀态轉換的源代碼,否則無法切換到新增狀态,而且修改某個狀态類的行為也需修改對應類的源代碼。
樣例
public interface State {
void handle();
}
public interface Context {
void setState(State s);
State getState();
}
空對象模式
有兩種含義:
- 在空對象模式(Null Object Pattern)中,一個空對象取代 NULL 對象執行個體的檢查。
- Null 對象不是檢查空值,而是反應一個不做任何動作的關系,這樣的 Null 對象也可以在資料不可用的時候提供預設的行為。
在空對象模式中,我們建立一個指定各種要執行的操作的抽象類和擴充該類的實體類,還建立一個未對該類做任何實作的空對象類,該空對象類将無縫地使用在需要檢查空值的地方。
适用場景
- 想要避免使用空指針(或null對象)的情況。
- 想要預設情況下具有“不做任何操作”的行為的情況。
模式缺點
- 必須手動實作isNil方法(或isNull方法)。
樣例
// 含義1:取代null的檢查
public interface Nullable {
boolean isNull();
}
// 含義2:不做任何動作的關系
public interface Command {
void handle();
}
public class NullCommand implements Command {
public void handle() {
return;
}
}
政策模式
在政策模式(Strategy Pattern)中,一個類的行為或其算法可以在運作時更改。這種類型的設計模式屬于行為型模式。
在政策模式中,我們建立表示各種政策的對象和一個行為随着政策對象改變而改變的 context 對象。政策對象改變 context 對象的執行算法。
适用場景
- 如果在一個系統裡面有許多類,它們之間的差別僅在于它們的行為,那麼使用政策模式可以動态地讓一個對象在許多行為中選擇一種行為。
- 一個系統需要動态地在幾種算法中選擇一種。
- 如果一個對象有很多的行為,如果不用恰當的模式,這些行為就隻好使用多重的條件選擇語句來實作。
模式缺點
- 政策類會增多。
- 所有政策類都需要對外暴露。
樣例
public interface Strategy {
void strategy();
}
模闆模式
在模闆模式(Template Pattern)中,一個抽象類公開定義了執行它的方法的方式/模闆。它的子類可以按需要重寫方法實作,但調用将以抽象類中定義的方式進行。這種類型的設計模式屬于行為型模式。
适用場景
- 有多個子類共有的方法,且邏輯相同。
- 重要的、複雜的方法,可以考慮作為模闆方法。
模式缺點
- 每一個不同的實作都需要一個子類來實作,導緻類的個數增加,使得系統更加龐大。
樣例
略,其實繼承情況下,就是對某些方法提供預設實作,對某些方法允許重寫覆寫。
通路者模式
在通路者模式(Visitor Pattern)中,我們使用了一個通路者類,它改變了元素類的執行算法。通過這種方式,元素的執行算法可以随着通路者改變而改變。這種類型的設計模式屬于行為型模式。根據模式,元素對象已接受通路者對象,這樣通路者對象就可以處理元素對象上的操作。
适用場景
- 對象結構中對象對應的類很少改變,但經常需要在此對象結構上定義新的操作。
- 需要對一個對象結構中的對象進行很多不同的并且不相關的操作,而需要避免讓這些操作"污染"這些對象的類,也不希望在增加新操作時修改這些類。
模式缺點
- 具體元素對通路者公布細節,違反了迪米特原則。
- 具體元素變更比較困難。
- 違反了依賴倒置原則,依賴了具體類,沒有依賴抽象。
樣例
public interface Visitor {
void visit(Element e);
}
public interface Element {
void accept(Visitor v);
}
// 通常在accept中,調用v.visit(this)來進行通路操作。