3.1 結(jié)構(gòu)型模式基本概念
結(jié)構(gòu)型模式描述如何將類或?qū)ο蟀茨撤N布局組成更大的結(jié)構(gòu)畸裳。它分為類結(jié)構(gòu)型模式和對象結(jié)構(gòu)型模式怖糊,前者采用繼承機制來組織接口和類蓬抄,后者釆用組合或聚合來組合對象嚷缭。
由于組合關(guān)系或聚合關(guān)系比繼承關(guān)系耦合度低路幸,滿足“合成復(fù)用原則”,所以對象結(jié)構(gòu)型模式比類結(jié)構(gòu)型模式具有更大的靈活性砰识。
結(jié)構(gòu)型模式分為以下 7 種:
代理(Proxy)模式:為某對象提供一種代理以控制對該對象的訪問。即客戶端通過代理間接地訪問該對象膨处,從而限制鹃答、增強或修改該對象的一些特性测摔。
適配器(Adapter)模式:將一個類的接口轉(zhuǎn)換成客戶希望的另外一個接口,使得原本由于接口不兼容而不能一起工作的那些類能一起工作。
橋接(Bridge)模式:將抽象與實現(xiàn)分離樊销,使它們可以獨立變化。它是用組合關(guān)系代替繼承關(guān)系來實現(xiàn)的,從而降低了抽象和實現(xiàn)這兩個可變維度的耦合度腺占。
裝飾(Decorator)模式:動態(tài)地給對象增加一些職責(zé)积蔚,即增加其額外的功能尽爆。
外觀(Facade)模式:為多個復(fù)雜的子系統(tǒng)提供一個一致的接口槐雾,使這些子系統(tǒng)更加容易被訪問彪笼。
享元(Flyweight)模式:運用共享技術(shù)來有效地支持大量細(xì)粒度對象的復(fù)用幅恋。
組合(Composite)模式:將對象組合成樹狀層次結(jié)構(gòu),使用戶對單個對象和組合對象具有一致的訪問性。
3.2 代理模式
代理模式的定義:由于某些原因需要給某對象提供一個代理以控制對該對象的訪問。這時,訪問對象不適合或者不能直接引用目標(biāo)對象,代理對象作為訪問對象和目標(biāo)對象之間的中介挨厚。
代理模式的結(jié)構(gòu)比較簡單寞钥,主要是通過定義一個繼承抽象主題的代理來包含真實主題,從而實現(xiàn)對真實主題的訪問赚爵,下面來分析其基本結(jié)構(gòu)和實現(xiàn)方法法瑟。
代理模式的主要角色如下:
抽象主題(Subject)類:通過接口或抽象類聲明真實主題和代理對象實現(xiàn)的業(yè)務(wù)方法。
真實主題(Real Subject)類:實現(xiàn)了抽象主題中的具體業(yè)務(wù)唁奢,是代理對象所代表的真實對象霎挟,是最終要引用的對象。
代理(Proxy)類:提供了與真實主題相同的接口麻掸,其內(nèi)部含有對真實主題的引用酥夭,它可以訪問、控制或擴展真實主題的功能脊奋。
一般代理會被理解為代碼增強熬北,實際上就是在原代碼邏輯前后增加一些代碼邏輯,而使調(diào)用者無感知诚隙。
根據(jù)代理的創(chuàng)建時期讶隐,代理模式分為靜態(tài)代理和動態(tài)代理。
靜態(tài):由程序員創(chuàng)建代理類或特定工具自動生成源代碼再對其編譯最楷,在程序運行前代理類的 .class 文件就已經(jīng)存在了整份。
動態(tài):在程序運行時,運用反射機制動態(tài)創(chuàng)建而成.
代碼:
package proxy;
public class ProxyTest {
public static void main(String[] args) {
Proxy proxy = new Proxy();
proxy.Request();
}
}
//抽象主題
interface Subject {
void Request();
}
//真實主題
class RealSubject implements Subject {
public void Request() {
System.out.println("訪問真實主題方法...");
}
}
//代理
class Proxy implements Subject {
private RealSubject realSubject;
public void Request() {
if (realSubject == null) {
realSubject = new RealSubject();
}
preRequest();
realSubject.Request();
postRequest();
}
public void preRequest() {
System.out.println("訪問真實主題之前的預(yù)處理籽孙。");
}
public void postRequest() {
System.out.println("訪問真實主題之后的后續(xù)處理烈评。");
}
}
3.3 適配器模式(Adapter模式)
適配器模式(Adapter)的定義如下:將一個類的接口轉(zhuǎn)換成客戶希望的另外一個接口,使得原本由于接口不兼容而不能一起工作的那些類能一起工作犯建。適配器模式分為類結(jié)構(gòu)型模式和對象結(jié)構(gòu)型模式兩種讲冠,前者類之間的耦合度比后者高,且要求程序員了解現(xiàn)有組件庫中的相關(guān)組件的內(nèi)部結(jié)構(gòu)适瓦,所以應(yīng)用相對較少些竿开。
類適配器模式可采用多重繼承方式實現(xiàn),如 C++ 可定義一個適配器類來同時繼承當(dāng)前系統(tǒng)的業(yè)務(wù)接口和現(xiàn)有組件庫中已經(jīng)存在的組件接口玻熙;[Java] 不支持多繼承否彩,但可以定義一個適配器類來實現(xiàn)當(dāng)前系統(tǒng)的業(yè)務(wù)接口,同時又繼承現(xiàn)有組件庫中已經(jīng)存在的組件嗦随。
對象適配器模式可釆用將現(xiàn)有組件庫中已經(jīng)實現(xiàn)的組件引入適配器類中列荔,該類同時實現(xiàn)當(dāng)前系統(tǒng)的業(yè)務(wù)接口。
適配器模式(Adapter)包含以下主要角色:
目標(biāo)(Target)接口:當(dāng)前系統(tǒng)業(yè)務(wù)所期待的接口枚尼,它可以是抽象類或接口贴浙。
適配者(Adaptee)類:它是被訪問和適配的現(xiàn)存組件庫中的組件接口。
適配器(Adapter)類:它是一個轉(zhuǎn)換器署恍,通過繼承或引用適配者的對象崎溃,把適配者接口轉(zhuǎn)換成目標(biāo)接口,讓客戶按目標(biāo)接口的格式訪問適配者盯质。
類適配器模式的結(jié)構(gòu)圖
對象適配器模式的結(jié)構(gòu)圖
類適配器模式的代碼:
package adapter;
//目標(biāo)接口
interface Target
{
public void request();
}
//適配者接口
class Adaptee
{
public void specificRequest()
{
System.out.println("適配者中的業(yè)務(wù)代碼被調(diào)用袁串!");
}
}
//類適配器類
class ClassAdapter extends Adaptee implements Target
{
public void request()
{
specificRequest();
}
}
//客戶端代碼
public class ClassAdapterTest
{
public static void main(String[] args)
{
System.out.println("類適配器模式測試:");
Target target = new ClassAdapter();
target.request();
}
}
對象適配器模式的代碼:
package adapter;
//對象適配器類
class ObjectAdapter implements Target
{
private Adaptee adaptee;
public ObjectAdapter(Adaptee adaptee)
{
this.adaptee=adaptee;
}
public void request()
{
adaptee.specificRequest();
}
}
//客戶端代碼
public class ObjectAdapterTest
{
public static void main(String[] args)
{
System.out.println("對象適配器模式測試:");
Adaptee adaptee = new Adaptee();
Target target = new ObjectAdapter(adaptee);
target.request();
}
}
對象適配器模式中的“目標(biāo)接口”和“適配者類”的代碼同類適配器模式一樣概而,只要修改適配器類和客戶端的代碼即可.
3.4 橋接模式(Bridge模式)
橋接(Bridge)模式的定義如下:將抽象與實現(xiàn)分離,使它們可以獨立變化囱修。它是用組合關(guān)系代替繼承關(guān)系來實現(xiàn)到腥,從而降低了抽象和實現(xiàn)這兩個可變維度的耦合度。
橋接模式遵循了里氏替換原則和依賴倒置原則蔚袍,最終實現(xiàn)了開閉原則,對修改關(guān)閉配名,對擴展開放啤咽。
橋接模式將抽象化部分與實現(xiàn)化部分分開,取消二者的繼承關(guān)系渠脉,改用組合關(guān)系宇整;
模式的結(jié)構(gòu)
橋接(Bridge)模式包含以下主要角色。
抽象化(Abstraction)角色:定義抽象類芋膘,并包含一個對實現(xiàn)化對象的引用鳞青。
擴展抽象化(Refined Abstraction)角色:是抽象化角色的子類,實現(xiàn)父類中的業(yè)務(wù)方法为朋,并通過組合關(guān)系調(diào)用實現(xiàn)化角色中的業(yè)務(wù)方法臂拓。
實現(xiàn)化(Implementor)角色:定義實現(xiàn)化角色的接口,供擴展抽象化角色調(diào)用习寸。
具體實現(xiàn)化(Concrete Implementor)角色:給出實現(xiàn)化角色接口的具體實現(xiàn)胶惰。
代碼:
package bridge;
public class BridgeTest {
public static void main(String[] args) {
Implementor imple = new ConcreteImplementorA();
Abstraction abs = new RefinedAbstraction(imple);
abs.Operation();
}
}
//實現(xiàn)化角色
interface Implementor {
public void OperationImpl();
}
//具體實現(xiàn)化角色
class ConcreteImplementorA implements Implementor {
public void OperationImpl() {
System.out.println("具體實現(xiàn)化(Concrete Implementor)角色被訪問");
}
}
//抽象化角色
abstract class Abstraction {
protected Implementor imple;
protected Abstraction(Implementor imple) {
this.imple = imple;
}
public abstract void Operation();
}
//擴展抽象化角色
class RefinedAbstraction extends Abstraction {
protected RefinedAbstraction(Implementor imple) {
super(imple);
}
public void Operation() {
System.out.println("擴展抽象化(Refined Abstraction)角色被訪問");
imple.OperationImpl();
}
}