天天看點

GOF23設計模式(二)——結構型模式

結構型模式

核心作用:從程式結構上實作松耦合,進而可以擴大整體的類結構,用來解決更大的問題

擴充卡模式(adapter)

現執行個體子:轉換器、轉接頭、變壓器等

作用:

将一個類的接口轉換成期望接口。使得原本不相容可以相容工作
角色:
目标接口(Target):期望接口
擴充卡(Adapter)轉接頭
需要适配的類(Adaptee)現有的類/接口
JDK
java.io.InputStreamReader(InputStream)
java.io.OutputStreamWriter(OutputStream)

橋接模式(Bridge)

解決:單一次元繼承帶來的不易擴充的問題

核心要求:處理多層繼承結構,處理多元度變化的場景,将各個次元設計成獨立的繼承結構,使各個次元可以獨立的擴充。在抽象層建立關聯。

可以取代多層繼承的方案。多層繼承違背了SRP,複用性差,類的個數多不易維護。進而提高了系統的擴充性,在兩個變化次元中任意擴充一個次元,都不需要修改原有的系統,符合OCP

裝飾模式(Decorator/Wrapper)

職責:
動态的為一個對象添加新的功能。是一種代替繼承的技術,無須通過繼承增加子類就能擴充對象的新功能。使用對象的關聯關系代替繼承關系,更加靈活,同時避免類型體系的快速膨脹。
Component抽象構件角色
真實對象和裝飾對象所共有接口。這樣對于用戶端就能夠實作調用替換
ConcreteComponent具體構件角色(真實對象)
例子:io流中的FileInputStream、FileOutputStream
Decorator裝飾角色
持有一個抽象構件的引用。裝飾對象接受所有用戶端的請求,并把這些請求轉發給真實的對象,這樣就能在真實調用調用前後增加新的功能。例子:FilterInputStream
ConcreteDecorator(具體裝飾角色)
負責給構件對象增加新的責任例子:BufferedInputStream、DataInputStream

應用:

Servlet API : ServletRequestWrapper、HttpServletRequestWrapper

缺點:

産出很多小對象。大量小對象占據記憶體,一定程度上影響性能;易于出錯,不易調試排查與橋接模式的差別:相同:都是為了解決過多子類對象問題誘因不同:橋接——對象自身現有機制沿着多個次元變化,是既有部分不穩定裝飾——為了增加新的功能

組合模式

場景:
把部分和整體的關系用樹形結構來表示,進而使用戶端可以使用統一的方式處理部分對象和整體對象
核心:
抽象構件(Component)角色:定義了葉子和容器構件的共同點
葉子(Leaf):構件角色:無子節點
容器(Composite)構件角色:有容器特征,可以包含子節點
JUnit底層設計中:TestCase、TestUnite、Test

外觀模式(門面模式 Facade)

為了系統提供統一的接口。封裝子系統的複雜性,便于用戶端調用

享元模式(Flyweight)

記憶體屬于稀缺資源,不要随便浪費。如果有很多個完全相同或相似的對象,可以通過享元模式,節省記憶體
以共享的方式高效地支援大量細粒度對象的重用
共享的關鍵是區分了内部狀态和外部狀态
内部狀态:可以共享,不會随環境變化而改變
外部狀态:不可以共享,會随環境變化而改變
實作:
FlyWeightFactory享元工廠類
建立并管理享元對象,享元池一般設計成鍵值對
FlyWeight抽象享元類
聲明公共方法,這些方法可以向外界提供對象的内部狀态,設定外部狀态
ConcreteFlyWeight具體享元類
為内部狀态提供成員變量進行存儲
UnsharedConCreteFlyWeight非共享享元類(外部狀态封裝類)
不能被共享的子類可以設計成非共享享元類
線程池、資料庫連接配接池、java.lang.String
優缺點:
優點:
極大減少記憶體中對象的數量
相同或相似的對象記憶體中隻存一份,極大的節約資源,提高系統性能
外部狀态相對獨立,不影響内部狀态
模式較為複雜,是程式邏輯複雜化
為了節省記憶體,共享了内部狀态,分離出外部狀态,而讀取外部狀态師運作時間變長。用時間換取空間

代理模式(Proxy)

作用:
抽象角色:定義代理角色和真實角色的公開方法
真實角色:實作抽象角色,實作真實業務邏輯
代理角色:實作抽象角色,代理真實角色,并在真實角色的業務進行中加入附加操作
分類:
靜态代理
動态代理
JDK自帶的動态代理(java.lang.reflect.Proxy,java.lang.reflect.InvocationHandler) java.beans.EventHandler
javaassist位元組碼操作庫實作
CGLIB
ASM(底層使用指令,可維護性差)

繼續閱讀