全面瞭解23種設計模式,細說那些被人所知的設計思想。(一週徹底擼完被23種設計模式瘋狂折磨)

全面瞭解23種設計模式,細說那些被人所知的設計思想。(一週徹底擼完被23種設計模式瘋狂折磨)

一,設計模式介紹

1,簡介:

設計模式(英語 design pattern),是對面向對象設計中反覆出現的問題的解決方案。這個術語是在1990年代由Erich Gamma等人從建築設計領域引入到計算機科學中來的。這個術語的含義還存有爭議。算法不是設計模式,因爲算法致力於解決問題而非設計問題。設計模式通常描述了一組相互緊密作用的類與對象。設計模式提供一種討論軟件設計的公共語言,使得熟練設計者的設計經驗可以被初學者和其他設計者掌握。設計模式還爲軟件重構提供了目標。
隨着軟件開發社羣對設計模式的興趣日益增長,已經出版了一些相關的專著,定期召開相應的研討會,而且Ward Cunningham爲此發明了WikiWiki用來交流設計模式的經驗

2,產生背景:

設計模式這個術語最初並不是出現在軟件設計中,而是被用於建築領域的設計中。
1977 年,美國著名建築大師、加利福尼亞大學伯克利分校環境結構中心主任克里斯托夫·亞歷山大(Christopher Alexander)在他的著作《建築模式語言:城鎮、建築、構造(A Pattern Language: Towns Building Construction)中描述了一些常見的建築設計問題,並提出了 253 種關於對城鎮、鄰里、住宅、花園和房間等進行設計的基本模式。
1979 年他的另一部經典著作《建築的永恆之道》(The Timeless Way of Building)進一步強化了設計模式的思想,爲後來的建築設計指明瞭方向。
1987 年,肯特·貝克(Kent Beck)和沃德·坎寧安(Ward Cunningham)首先將克里斯托夫·亞歷山大的模式思想應用在 Smalltalk 中的圖形用戶接口的生成中,但沒有引起軟件界的關注。
直到 1990 年,軟件工程界纔開始研討設計模式的話題,後來召開了多次關於設計模式的研討會。
1995 年艾瑞克·伽馬(ErichGamma)理査德·海爾姆(Richard Helm)拉爾夫·約翰森(Ralph Johnson)約翰·威利斯迪斯(John Vlissides)等 4 位作者合作出版了《設計模式:可複用面向對象軟件的基礎》(Design Patterns: Elements of Reusable Object-Oriented Software)一書,在本教程中收錄了 23 個設計模式,這是設計模式領域裏程碑的事件,導致了軟件設計模式的突破。這 4 位作者在軟件開發領域裏也以他們的“四人組”(Gang of Four,GoF)匿名著稱。

3,概念:

設計模式,是一套被反覆使用、多數人知曉的、經過分類編目的、代碼設計經驗的總結。使用設計模式是爲了可重用代碼、讓代碼更容易被他人理解、保證代碼可靠性、程序的重用性。

4,學習設計模式的意義 :

設計模式的本質是面向對象設計原則的實際運用,是對類的封裝性繼承性多態性以及類的關聯關係組合關係的充分理解。正確使用設計模式具有以下優點。

  • 可以提高程序員的思維能力、編程能力和設計能力。
  • 使程序設計更加標準化、代碼編制更加工程化,使軟件開發效率大大提高,從而縮短軟件的開發週期。
  • 使設計的代碼可重用性高、可讀性強、可靠性高、靈活性好、可維護性強。

二,設計模式的四大基本要素

1,模式名稱(PatternName)

每一個模式都有自己的名字,通常用一兩個詞來描述,可以根據模式的問題、特點、解決方案、功能和效果來命名。模式名稱有助於我們理解和記憶該模式,也方便我們來討論自己的設計。

2,問題(Problem)

描述了該模式的應用環境,即何時使用該模式。它解釋了設計問題和問題存在的前因後果,以及必須滿足的一系列先決條件。

3,解決方案(Solution)

包括設計的組成成分、它們之間的相互關係及各自的職責和協作方式。因爲模式就像一個模板,可應用於多種不同場合,所以解決方案並不描述一個特定而具體的設計或實現,而是提供設計問題的抽象描述和怎樣用一個具有一般意義的元素組合(類或對象的 組合)來解決這個問題。

4,效果(Consequence)

描述了模式的應用效果以及使用該模式應該權衡的問題,即模式的優缺點。主要是對時間和空間的衡量,以及該模式對系統的靈活性、擴充性、可移植性的影響,也考慮其實現問題。顯式地列出這些效果對理解和評價這些模式有很大的幫助

三,設計模式的七大設計原則

1,開閉原則

簡介:開閉原則(Open Closed Principle,OCP)由勃蘭特·梅耶(Bertrand Meyer)提出,他在 1988 年的著作《面向對象軟件構造》(Object Oriented Software Construction)中提出:軟件實體應當對擴展開放,對修改關閉(Software entities should be open for extension,but closed for modification),這就是開閉原則的經典定義。

作用:

  • 可以提高代碼的可複用性
  • 可以提高軟件的可維護性
  • 對軟件測試的影響

實現方法

可以通過抽象約束封裝變化來實現開閉原則,即通過接口或者抽象類爲軟件實體定義一個相對穩定的抽象層,而將相同的可變因素封裝在相同的具體實現類中。

因爲抽象靈活性好,適應性廣,只要抽象的合理,可以基本保持軟件架構的穩定。而軟件中易變的細節可以從抽象派生來的實現類來進行擴展,當軟件需要發生變化時,只需要根據需求重新派生一個實現類來擴展就可以了。

示例:類圖如下:

開閉原則
定義一個接口 Persion (人) , 我需要 女人或者男人(具體的實現)不需要去修改 原來的代碼 ,只需要在創建一個子類。這樣就非常符合 開閉原則:對擴展開放,對修改關閉。

2,里氏替換原則

簡介:里氏替換原則(Liskov Substitution Principle,LSP)由麻省理工學院計算機科學實驗室的里斯科夫(Liskov)女士在 1987 年的“面向對象技術的高峯會議”(OOPSLA)上發表的一篇文章《數據抽象和層次》(Data Abstraction and Hierarchy)裏提出來的,她提出:繼承必須確保超類所擁有的性質在子類中仍然成立(Inheritance should ensure that any property proved about supertype objects also holds for subtype objects)。

里氏替換原則主要闡述了有關繼承的一些原則,也就是什麼時候應該使用繼承,什麼時候不應該使用繼承,以及其中蘊含的原理。里氏替換原是繼承複用的基礎,它反映了基類與子類之間的關係,是對開閉原則的補充,是對實現抽象化的具體步驟的規範。

里氏替換原則通俗來講就是:子類可以擴展父類的功能,但不能改變父類原有的功能。也就是說:子類繼承父類時,除添加新的方法完成新增功能外,儘量不要重寫父類的方法。

那麼如何透明地使用呢?子類可以改變父類的原有功能嗎?

public class A {
    public void fun(int a,int b){
        System.out.println(a+b);
    }
}
 
public class B extends A{
    @Override
    public void fun(int a,int b){
        System.out.println(a-b);
    }
}

這裏本來是加法卻修改成了減法,這顯然是不符合認知的
它違背了里氏替換原則,子類改變了父類原有功能後,當我們在引用父類的地方使用其子類的時候,沒辦法透明使用fun方法了。父類中凡是已經實現好的方法,實際上是在設定一系列的規範和契約,雖然它不強制要求所有的子類必須遵從這些規範,但是如果子類對這些非抽象方法任意修改,就會對整個繼承體系造成破壞
所以,透明使用的關鍵就是,子類不能改變父類原有功能

如果通過重寫父類的方法來完成新的功能,這樣寫起來雖然簡單,但是整個繼承體系的可複用性會比較差,特別是運用多態比較頻繁時,程序運行出錯的概率會非常大。`

如果程序違背了里氏替換原則,則繼承類的對象在基類出現的地方會出現運行錯誤。這時其修正方法是:取消原來的繼承關係,重新設計它們之間的關係。

作用

1,里氏替換原則是實現開閉原則的重要方式之一。
2,它克服了繼承中重寫父類造成的可複用性變差的缺點。
3,它是動作正確性的保證。即類的擴展不會給已有的系統引入新的錯誤,降低了代碼出錯的可能性。

里氏替換原則爲良好的繼承定義了一個規範

  • 子類必須實現父類的抽象方法,但不得重寫父類的非抽象(已實現的)方法。
    實現方法
 public abstract class Parent{

		    public void show(int a,int b){
		        System.out.println(a+b);
		    }

		    /**
		     * 抽象方法,子類實現擴展
		     */
   			 public abstract void features();
 }
public class Children extends Parent{

    public void show(int a,int b){
        System.out.println(a+b);
    }

    @Override
    public void features() {
        System.out.println("這是子類擴展功能");
    }
}
  • 子類中可增加自己特有的方法。(可以隨時擴展)
  • 當子類覆蓋或者實現父類的方法時,方法的前置條件(方法形參)要比父類輸入參數更加寬鬆。否則會調用到父類的方法。
public abstract class Parent{

    public void setMap(HashMap map){
        System.out.println("執行父類setMap方法");
    }

}
public class Children extends Parent{

    public void setMap(Map map){
        System.out.println("執行子類setMap方法");
    }

}
public class mainClass {
    public static void main(String[] args) {
        Children children = new Children();
        children.setMap(new HashMap());
    }
}

執行結果:
執行結果

  • 當子類的方法實現父類的抽象方法時,方法的後置條件(即方法的返回值)要比父類更嚴格。否則會調用到父類的方法。
public abstract class Parent{

  public abstract List<String> getList();
}
public class Children extends Parent{

    //這裏返回值類型不對 編譯器會報錯
    //父類返回值是List,子類返回值是List的父類Collection,
    //透明使用父類的時候則需要將Collection轉換成List。 類向上轉換是安全的,向下轉換則不一定是安全了
	//@Override
   // public Collection<String> getList() {
       // return new ArrayList<String>();
   // }

   @Override
    public List<String> getList() {
        return new ArrayList<String>();
    }
}
public class mainClass {
    public static void main(String[] args) {
        Parent parent = new Children();
        parent.setList(new ArrayList<String>());
    }
}

我們最好將父類定義爲抽象類,並定義抽象方法,讓子類重新定義這些方法,當父類是抽象類時候,父類不能實例化

3,依賴倒置原則

4,單一職責原則

5,接口隔離原則

6,迪米特法則

7,合成複用原則

四,23種設計模式分爲三大類別模式

1,創建型模式:

它的主要特點是“將對象的創建與使用分離”。這樣可以降低系統的耦合度,使用者不需要關注對象的創建細節,對象的創建由相關的工廠來完成。就像我們去商場購買商品時,不需要知道商品是怎麼生產出來一樣,因爲它們由專門的廠商生產。

2,結構型模式:

它的主要特點是 如何將類或對象按某種佈局組成更大的結構。它分爲類結構型模式和對象結構型模式,前者採用繼承機制來組織接口和類,後者釆用組合或聚合來組合對象。由於組合關係或聚合關係比繼承關係耦合度低,滿足“合成複用原則”,所以對象結構型模式比類結構型模式具有更大的靈活性。

3,行爲型模式:

用於描述程序在運行時複雜的流程控制,即描述多個類或對象之間怎樣相互協作共同完成單個對象都無法單獨完成的任務,它涉及算法與對象間職責的分配。
行爲型模式分爲類行爲模式和對象行爲模式,前者採用繼承機制來在類間分派行爲,後者採用組合或聚合在對象間分配行爲。由於組合關係或聚合關係比繼承關係耦合度低,滿足“合成複用原則”,所以對象行爲模式比類行爲模式具有更大的靈活性。

五,創建型模式包含以下 5 種模式

1,單例(Singleton)模式:

簡介:某個類只能生成一個實例,該類提供了一個全局訪問點供外部獲取該實例,其拓展是有限多例模式。

  • 餓漢模式(線程不安全) ,不管客戶端需不需要這個對象,都提供了這個對象實例給客戶端。
  • 懶漢模式(線程不安全), 當客戶端需要這個對象時,纔會去 新建一個實例提供給客戶端。
  • 雙重檢查(懶漢模式上的演變 是線程安全), 用 volatile 修飾 聲明對象。(簡單來說用它聲明的類型變量表示不可以被某些編譯器未知的因素更改,可以通過緩存一致性協議保證每個線程都能獲得最新值,即滿足數據的“可見性”。並且是程度較輕的 synchronized, 所需的編碼較少,並且運行時開銷也較少), 使用 synchronized 關鍵字修飾方法(同步代碼塊時,其他試圖訪問該方法的線程將被阻塞,直到上一個線程執行完,才執行下一個),用 雙重 判斷 對象是否爲null,檢查線程在資源競爭的狀態下,出現線程阻塞問題。
  • 靜態內部類單例模式 (線程安全)。(推薦使用,代碼簡潔,可讀性高,線程安全是因爲 java 在創建靜態對象的時候已經保證)。
  • 枚舉單例模式 (代碼簡單,可讀性較差,開發中很少使用,線程安全)

2,原型(Prototype)模式:

簡介:將一個對象作爲原型,通過對其進行復制而克隆出多個和原型類似的新實例。
通過 jdk本身自帶接口 (Cloneable) 去實現接口,目標對象是原型對象的一個克隆,不僅僅是具有相同的結構,屬性,還與原型對象具有 相同的值。但是 在實例化目標對象,和實例化原型對象後, 在jvm 虛擬機 堆內存裏是 兩個地址不相同的引用對象。根據對象克隆深度層次的不同,有淺度克隆與深度克隆。

3,工廠(Prototype)模式:

簡介:定義一個用於創建產品的接口,由子類決定生產什麼產品。

  • 工廠(Creator)角色;
  • 抽象(Product) 角色;
  • 具體產品(Concenter Product) 角色;

4,抽象工廠(AbstractFactory)模式:

簡介:提供一個創建產品族的接口,其每個子類可以生產一系列相關的產品。
抽象工廠模式是所有形態的工廠模式中最爲抽象和最其一般性的,抽象工廠模式可以向客戶端提供一個接口,使得客戶端在不必指定產品具體的情況下,能夠創建多個產品對象。

  • 抽象工廠模式的核心,任何工廠都必須實現這個接口 (CqwwCallFactroy)
  • 具體工廠是抽象工廠的一個實現,負責實例化 (WawaFactroy)
  • 具體產品,抽象模式所創建的具體事例對象 (SpecificJapan, SpencificAmerica)

5,建造者(Builder)模式:

簡介:將一個複雜對象分解成多個相對簡單的部分,然後根據不同需要分別創建它們,最後構建成該複雜對象。

  • 抽象建造者(builder):描述具體建造者的公共接口,一般用來定義建造細節的方法,並不涉及具體的對象部件的創建。
  • 具體建造者(ConcreteBuilder):描述具體建造者,並實現抽象建造者公共接口。
  • 指揮者(Director):調用具體建造者來創建複雜對象(產品)的各個部分,並按照一定順序(流程)來建造複雜對象。
  • 產品(Product):描述一個由一系列部件組成較爲複雜的對象。

六,結構型模式包含以下 7 種模式。

1,代理(Proxy)模式:

簡介:爲某對象提供一種代理以控制對該對象的訪問。即客戶端通過代理間接地訪問該對象,從而限制、增強或修改該對象的一些特性。

靜態代理:

  • subject (抽象主題角色):真實主題與代理主題的共同接口。
  • RealSubject(真實主題角色): 定義了代理角色所代表的真實對象
  • Proxy(代理主題角色):含有對真實主題角色的引用,代理角色通常在將客戶端調用傳遞給真實主題對象之前或者之後執行某些操作,而不是單純返回真實主題對象。

動態代理:

  • 實現InvocationHandler
  • invoke : (在代理實例上處理方法調用並返回結果)
  • Proxy.newProxyInstance() : 創建代理實例

2,適配器(Adapter)模式:

簡介:將一個類的接口轉換成客戶希望的另外一個接口,使得原本由於接口不兼容而不能一起工作的那些類能一起工作。

1.類適配器模式,  通過繼承實現Adapter
2.對象適配器模式,通過委讓實現Adapter
  • 目標(Target)接口:當前系統業務所期待的接口,它可以是抽象類或接口。
  • 適配者(Adaptee)類:它是被訪問和適配的現存組件庫中的組件接口。
  • 適配器(Adapter)類:它是一個轉換器,通過繼承或引用適配者的對象,把適配者接口轉換成目標接口,讓客戶按目標接口的格式訪問適配者。

3,橋接(Bridge)模式:

簡介:將抽象與實現分離,使它們可以獨立變化。它是用組合關係代替繼承關係來實現的,從而降低了抽象和實現這兩個可變維度的耦合度。

  • 抽象化(Abstraction)角色:定義抽象類,幷包含一個對實現化對象的引用。
  • 擴展抽象化(Refined Abstraction)角色:是抽象化角色的子類,實現父類中的業務方法,並通過組合關係調用實現化角色中的業務方法。
  • 實現化(Implementor)角色:定義實現化角色的接口,供擴展抽象化角色調用。
  • 具體實現化(Concrete Implementor)角色:給出實現化角色接口的具體實現。

4,裝飾(Decorator)模式:

簡介:動態地給對象增加一些職責,即增加其額外的功能。

  • 抽象組件角色: 一個抽象接口,是被裝飾類和裝飾類的父接口。
  • 具體組件角色:爲抽象組件的實現類。
  • 抽象裝飾角色: 包含一個組件的引用,並定義了與抽象組件一致的接口
  • 具體裝飾角色:爲抽象裝飾角色的實現類。負責具體的裝飾。

5,外觀(Facade)模式:

簡介:爲多個複雜的子系統提供一個一致的接口,使這些子系統更加容易被訪問。

  • Facade : 爲調用方 定義簡單的調用接口。
  • Clients : 調用者。通過Facade接口調用提供某功能的內部類羣。
  • Packages: 功能提供者。指提供功能的類羣(模塊或子系統)。

6,享元(Flyweight)模式:

簡介:運用共享技術來有效地支持大量細粒度對象的複用。

1.內部狀態,即不會隨着環境的改變而改變的可共享部分。
2.外部狀態,指隨環境改變而改變的不可以共享的部分。享元模式的實現要領就是區分應用中的這兩種狀態,並將外部狀態外部化。下面來分析其基本結構和實現方法
  • 抽象享元角色 Flyweight): 所有具體享元類的父類,規定一些需要實現的公共接口。

  • 具體享元角色 (Concrete Flyweight): 抽象享元的具體實現類,並實現了抽象享元角色規定的方法。

  • 非享元(Unsharable Flyweight)角色:是不可以共享的外部狀態,它以參數的形式注入具體享元的相關方法中
    享元工廠角色 (Flyweight Factory): 負責創建和管理享元角色。

7,組合(Composite)模式:

簡介:將對象組合成樹狀層次結構,使用戶對單個對象和組合對象具有一致的訪問性。

透明方式實現 (所有的行爲,屬性,方法都在 抽象接口中,  葉節點和枝節點都必須要實現所有方法)。
安全方式實現 (將管理子構件的方法移到樹枝構件中,抽象構件和樹葉構件沒有對子對象的管理方法)。
  • Component : (樹形結構的節點抽象) :爲所有的對象定義統一的接口,(公共屬性,行爲等的定義,提供管理子節點對象的接口方法
  • Leaf : (樹形結構的葉節點)
  • Composite: (樹形結構的枝節點)

七,行爲型模式分爲以下11種模式。

1,[模板方法(Template Method)模式:]

簡介:定義一個操作中的算法骨架,將算法的一些步驟延遲到子類中,使得子類在可以不改變該算法結構的情況下重定義該算法的某些特定步驟。

2,策略(Strategy)模式:

簡介:定義了一系列算法,並將每個算法封裝起來,使它們可以相互替換,且算法的改變不會影響使用算法的客戶。

  • Strategy : 策略(算法)抽象。
  • ConcreteStrategy :各種策略(算法) 的具體實現
  • Contenxt :策略的外部封裝類,或者說策略的容器類。根據不同策略執行不同的行爲。策略由外部環境決定。

3,[命令(Command)模式:]

簡介:將一個請求封裝爲一個對象,使發出請求的責任和執行請求的責任分割開。

4,職責鏈(Chain of Responsibility)模式:

簡介:把請求從鏈中的一個對象傳到下一個對象,直到請求被響應爲止。通過這種方式去除對象之間的耦合。

優點:
1,降低了對象之間的耦合度。該模式使得一個對象無須知道到底是哪一個對象處理其請求以及鏈的結構,發送者和接收者也無須擁有對方的明確信息。
2,增強了系統的可擴展性。可以根據需要增加新的請求處理類,滿足開閉原則。
3,增強了給對象指派職責的靈活性。當工作流程發生變化,可以動態地改變鏈內的成員或者調動它們的次序,也可動態地新增或者刪除責任。
4,責任鏈簡化了對象之間的連接。每個對象只需保持一個指向其後繼者的引用,不需保持其他所有處理者的引用,這避免了使用衆多的 if 或者 if···else 語句。,5,責任分擔。每個類只需要處理自己該處理的工作,不該處理的傳遞給下一個對象完成,明確各類的責任範圍,符合類的單一職責原則。

缺點:
1,不能保證每個請求一定被處理。由於一個請求沒有明確的接收者,所以不能保證它一定會被處理,該請求可能一直傳到鏈的末端都得不到處理。
2,對比較長的職責鏈,請求的處理可能涉及多個處理對象,系統性能將受到一定影響。
3,職責鏈建立的合理性要靠客戶端來保證,增加了客戶端的複雜性,可能會由於職責鏈的錯誤設置而導致系統出錯,如可能會造成循環調用。

結構:
職責鏈模式主要包含以下角色。
1,抽象處理者(Handler)角色:定義一個處理請求的接口,包含抽象處理方法和一個後繼連接。
2,具體處理者(Concrete Handler)角色:實現抽象處理者的處理方法,判斷能否處理本次請求,如果可以處理請求則處理,否則將該請求轉給它的後繼者。
3,客戶類(Client)角色:創建處理鏈,並向鏈頭的具體處理者對象提交請求,它不關心處理細節和請求的傳遞過程。

5,[狀態(State)模式:]

簡介:允許一個對象在其內部狀態發生改變時改變其行爲能力。

6,觀察者(Observer)模式:

簡介:多個對象間存在一對多關係,當一個對象發生改變時,把這種改變通知給其他多個對象,從而影響其他對象的行爲。

結構:
觀察者 實現 Observer 接口
被觀察者,繼承 Observble 類。

  • Subject (被觀察者) :被觀察者的對象。當需要被觀察的狀態發生變化時,需要通知隊列中所有觀察者對象。Subject 需要維持(通知,刪除,添加) 一個觀察者對象的隊列列表。
  • ConcreteSubject(被觀察者的具體實現):包含一些基本的屬性狀態及其他操作。
  • Observer (觀察者,接口或抽象類) : 當Subject 的狀態發生變化時,Observer 對象將通過一個 callback函數得到通知。
  • ConcreteObserver(觀察者的具體實現):得到通知後將完成一些具體的業務邏輯處理。

7,中介者(Mediator)模式:

簡介:定義一箇中介對象來簡化原有對象之間的交互關係,降低系統中對象間的耦合度,使原有對象之間不必相互瞭解。

其主要優點如下。
1,降低了對象之間的耦合性,使得對象易於獨立地被複用。
2,將對象間的一對多關聯轉變爲一對一的關聯,提高系統的靈活性,使得系統易於維護和擴展。

其主要缺點是:當同事類太多時,中介者的職責將很大,它會變得複雜而龐大,以至於系統難以維護

中介者模式包含以下主要角色。
1,抽象中介者(Mediator)角色:它是中介者的接口,提供了同事對象註冊與轉發同事對象信息的抽象方法。
2,具體中介者(ConcreteMediator)角色:實現中介者接口,定義一個 List 來管理同事對象,協調各個同事角色之間的交互關係,因此它依賴於同事角色。
3,抽象同事類(Colleague)角色:定義同事類的接口,保存中介者對象,提供同事對象交互的抽象方法,實現所有相互影響的同事類的公共功能。
4,具體同事類(Concrete Colleague)角色:是抽象同事類的實現者,當需要與其他同事對象交互時,由中介者對象負責後續的交互。

8,[迭代器(Iterator)模式:]

簡介:提供一種方法來順序訪問聚合對象中的一系列數據,而不暴露聚合對象的內部表示。

9,[訪問者(Visitor)模式:]

簡介:在不改變集合元素的前提下,爲一個集合中的每個元素提供多種訪問方式,即每個元素有多個訪問者對象訪問。

10,[備忘錄(Memento)模式:]

簡介:在不破壞封裝性的前提下,獲取並保存一個對象的內部狀態,以便以後恢復它。

11,解釋器(Interpreter)模式:

簡介:提供如何定義語言的文法,以及對語言句子的解釋方法,即解釋器。

解釋器模式包含以下主要角色:

  • 抽象表達式(Abstract Expression)角色:定義解釋器的接口,約定解釋器的解釋操作,主要包含解釋方法 interpret()。
  • 終結符表達式(Terminal Expression)角色:是抽象表達式的子類,用來實現文法中與終結符相關的操作,文法中的每一個終結符都有一個具體終結表達式與之相對應。
  • 非終結符表達式(Nonterminal Expression)角色:也是抽象表達式的子類,用來實現文法中與非終結符相關的操作,文法中的每條規則都對應於一個非終結符表達式。
  • 環境(Context)角色:通常包含各個解釋器需要的數據或是公共的功能,一般用來傳遞被所有解釋器共享的數據,後面的解釋器可以從這裏獲取這些值。
  • 客戶端(Client):主要任務是將需要分析的句子或表達式轉換成使用解釋器對象描述的抽象語法樹,然後調用解釋器的解釋方法,當然也可以通過環境角色間接訪問解釋器的解釋方法。
    解析器結構

簡易版結構

  • Context : 解釋器上下文環境類,用來存儲解析器的上下文環境,比如需要解釋的文法等。
  • AbstratctExpression 解釋器抽象類。
  • ConcreteExpression 解釋器具體實現類。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章