1. 程式人生 > >二十三、 橋接設計模式

二十三、 橋接設計模式

1. 橋接設計模式介紹

在軟體系統中,某些型別由於自身的邏輯,它具有兩個或多個維度的變化,可以採用橋接模式來應對這種“多維度變化”。

定義

將抽象部分與實現部分分離,使它們可以獨立地進行變化。

2. 橋接設計模式使用場景

  • 如果一個系統需要在構建的抽象化角色和具體角色之間增加更多的靈活性,避免在兩個層次之間建立靜態的聯絡。
  • 一個類存在兩個獨立變化的維度,並且這兩個維度都需進行擴充套件。

3. 橋接設計模式UML類圖

橋接設計模式UML類圖

角色介紹

  • Abstraction:抽象部分。該類保持了一個對實現部分的引用,抽象部分中的方法需要呼叫實現部分的物件來實現,該類一般為抽象類

  • RefinedAbstraction:優化的抽象部分。 抽象部分的具體實現,該類一般是對抽象部分的方法進行完善和擴充套件。

  • Implementor:實現部分。 可以介面或抽象,該方法不一定要與抽象部分中的一致,一般情況下是由實現部分提供基本操作,而抽象部分定義的則是基於實現部分這些基本操作的業務方法。

  • ConcreteImplementorA/ConcreteImplementorB: 實現部分的具體實現。完善實現部分中方法定義的具體邏輯。

4. 橋接設計模式簡單實現

模式程式碼如下:

  • (1)、實現部分的抽象介面
public interface Implementor {
    /**
     * 實現抽象部分的具體方法
     */
    public void operationImpl
(); }
  • (2)、實現部分具體實現

ConcreteImplementtorA:

public class ConcreteImplementorA implements Implementor {
    @Override
    public void operationImpl() {
        //具體實現
    }
}

ConcreteImplementtorB:

public class ConcreteImplementorB implements Implementor {
    @Override
    public void operationImpl
() { //具體實現 } }
  • (3)、抽象部分的實現
public abstract class Abstraction {
    private Implementor mImplementor;

    public Abstraction(Implementor implementor) {
        this.mImplementor = implementor;
    }

    public void operation(){
        mImplementor.operationImpl();
    }
}   
  • (4)、抽象部分的子類
public class RefinedAbstraction extends Abstraction {

    public RefinedAbstraction(Implementor implementor) {
        super(implementor);
    }

    public void refinedOperation() {
        //對Abstraction中的方法進行擴充套件
    }
}
  • (5)、客戶端
public class Client {

    public static void main(String[] args) {
        //客戶呼叫邏輯
    }
}

以上只是模式程式碼,只是對UML類圖的實現。

下面考慮一中情形:

有兩種汽車:一般汽車和SUV汽車;每種汽車都可以安裝不同的引擎,有兩種引擎:大馬力和小馬力兩種。

  • (1)、首先定義引擎介面:
public abstract class Engine {

    //速度
    public abstract String speed();
}

引擎接口裡面有一個抽象方法,要來表示不同的引擎不同的速度。

  • (2)、具體的引擎實現類:

SmallEngine:

public class SmallEngine extends Engine {
    @Override
    public String speed() {
        return "小馬力引擎速度慢";
    }
}

LargeEngine:

public class LargeEngine extends Engine {
    @Override
    public String speed() {
        return "大馬力引擎速度快";
    }
}
  • (3)、汽車抽象類:
public abstract class Car {

    protected Engine engine;

    public Car(Engine engine) {
        this.engine = engine;
    }

    public abstract void makeCar();
}

汽車抽象類裡面有一個引擎引用,通過構造方法傳遞進來。

  • (4)、具體汽車類:

一般汽車:

public class NormalCar extends Car {
   public NormalCar(Engine engine) {
       super(engine);
   }

   @Override
   public void makeCar() {
       System.out.println("一般汽車:" + engine.speed());
   }
}

SUV汽車:

public class SuvCar extends Car {
    public SuvCar(Engine engine) {
        super(engine);
    }

    @Override
    public void makeCar() {
        System.out.println("SUV汽車:" + engine.speed());
    }
}

在具體的汽車類裡面,makeCar()方法中,呼叫不同的引擎。

  • (5)、測試類:
public class Client {
    public static void main(String[] args) {
        //兩種引擎
        SmallEngine smallEngine = new SmallEngine();
        LargeEngine largeEngine = new LargeEngine();

        //一般汽車小引擎
        NormalCar normalCarSmallEngine = new NormalCar(smallEngine);
        normalCarSmallEngine.makeCar();

        //一般汽車大引擎
        NormalCar normalCarLargeEngine = new NormalCar(largeEngine);
        normalCarLargeEngine.makeCar();

        //SUV汽車小引擎
        SuvCar suvCarSmallEngine = new SuvCar(smallEngine);
        suvCarSmallEngine.makeCar();

        //SUV汽車大引擎
        SuvCar suvCarLargeEngine = new SuvCar(largeEngine);
        suvCarLargeEngine.makeCar();

    }
}

結果如下:

        一般汽車:小馬力引擎速度慢
        一般汽車:大馬力引擎速度快
        SUV汽車:小馬力引擎速度慢
        SUV汽車:大馬力引擎速度快

5. 總結

橋接模式在應用開發中不多,一個重要的原因是對於抽象與實現的分離和把。

  • 優點:

    • 分離抽象與實現、靈活的擴充套件以及對客戶端來說透明的實現等。
  • 缺點:

    • 不容易把握實現,需要一定的經驗。