橋樑模式簡介

GeekWay發表於2013-04-08
橋樑模式

定義:將抽象與實現解耦,是他們可以獨立的變化。橋模式是繼承關係的一種替代方式。


名詞解釋:
抽象實現
    這是設計模式中最難以理解的一種模式了,其實這是中文翻譯的原因造成的,中文裡 把派生類叫做抽象類的實現,而橋樑模式所講的“實現”恰恰不是這個意思,橋樑模式中的“抽象”指的是抽象類及派生類,“實現”指的是這些抽象類及派生類實現自己的方式



解耦:
    所謂耦合,就是兩個實體的行為的某種強關聯。而將它們的強關聯去掉,就是耦合的解脫,或稱解耦。在這裡,解耦是指將抽象化和實現化之間的耦合解脫開,或者說是將它們之間的強關聯改換成弱關聯。
  所謂強關聯,就是在編譯時期已經確定的,無法在執行時期動態改變的關聯;所謂弱關聯,就是可以動態地確定並且可以在執行時期動態地改變的關聯。顯然,在Java語言中,繼承關係是強關聯,而聚合關係是弱關聯。
  將兩個角色之間的繼承關係改為聚合關係,就是將它們之間的強關聯改換成為弱關聯。因此,橋樑模式中的所謂解耦,就是指在一個軟體系統的抽象化和實現化之間使用聚合關係而不是繼承關係,從而使兩者可以相對獨立地變化。這就是橋樑模式的用意。

我們拿一個具體的例項解釋這一點:
    為汽車管理所 建立一個汽車管理的模型,要求對各個汽車製造廠生產的各種汽車進行管理。
假設我們這樣設計,首先設計一個抽象的汽車類Car.java,然後不同的汽車如貨車、公共汽車繼承這個抽象的汽車類。

Car.java:
public interface Car{
	void produce(){
	}
} 

Truck.java
public class Truck extends Car {
    public void produce() {
    }
}

Bus.java
public class Bus extends Car {
    public void produce() {
    }
}

汽車可以被多個汽車製造商製造,比如一汽、二汽等,我們這樣設計:
一汽生產的貨車類FawTruck.java

public class FawTruck extends Truck{
	 public void produce() {
    }
}

一汽生產的公共汽車類FawBus.java
public class FawBus extends Truck{
	 public void produce() {
    }
}

二汽生產的貨車類DfmcTruck.java
public class DfmcTruck extends Truck{
	 public void produce() {
    }
}

二汽生產的公共汽車類FawBus.java
public class DfmcBus extends Truck{
	 public void produce() {
    }
}
    這樣問題出現了,假設我們有15中車型,6家汽車製造商,那麼我們不得不實現15×6 = 90 種子類車型,這樣設計勢必造成類的數量翻倍的上升,工作量巨大。
    造成這種現象的原因在於我們把汽車的抽象和它的實現耦合在一起了,如果能將車型和製造商的分離開,問題就可以解決。


我們利用橋樑模式實現:
Car.java
public abstract class Car {
    public Car(Manufacturer lnkManufacturer) {
        this.lnkManufacturer = lnkManufacturer;
    }

Car.java
public abstract class Car {
    public Car(Manufacturer lnkManufacturer) {
        this.lnkManufacturer = lnkManufacturer;
    }

   public void produce() {
		lnkManufacturer.produce();
   }

    /**
     * @directed 
     */
    Manufacturer lnkManufacturer;
}

製造商類Manufacturer.java
public interface Manufacturer {
    void produce();
}

Truck.java
public class Truck extends Car {
    public Truck(Manufacturer lnkManufacturer) {
        super(lnkManufacturer);
    }


    public void produce() {
        lnkManufacturer.produce();
        System.out.println("的貨車");
    }
}

Bus.java
public class Bus extends Car {
     public Bus(Manufacturer lnkManufacturer) {
        super(lnkManufacturer);
    }
    public void produce() {
		lnkManufacturer.produce();
        System.out.println("的公共汽車");
    }
}

一汽Faw.java
public class Faw implements Manufacturer {
    public void produce() {
        System.out.println("一汽製造");
    }
}

二汽Dfmc.java

public class Dfmc implements Manufacturer {
    public void produce() {
        System.out.println("二汽製造");
    }
}

    這樣如果新的車型進來,就繼承Car.java,如果有新的製造商進來,就實現Manufacturer.java,除此之外不需要新增任何程式碼。如果客戶要求,採用一汽 生產的 貨車,則在客戶端呼叫的程式碼如下:
public class Client {
    public static void main(String[] argv) {
        Car car = new Truck(new Faw());
        car.produce();
    }
}

    同理,如果車型和製造商有變時,則只需要更改客戶端相應的Car的子類和Manufacturer的子類即可。

    橋樑模式由4部分組成:抽象類、抽象類的繼承類、實現類、實現類的繼承類。橋樑模式的原理圖如下:

程式碼如下:

抽象化角色類,它宣告瞭一個方法operation(),並給出了它的實現。這個實現是通過向實現化物件的委派(呼叫operationImpl()方法)實現的。

public abstract class Abstraction {
    protected Implementor impl;
    public Abstraction(Implementor impl){
        this.impl = impl;
    }
    //示例方法
    public void operation(){      
        impl.operationImpl();
    }
}

抽象類的實現類:
public class RefinedAbstraction extends Abstraction {
    public RefinedAbstraction(Implementor impl) {
        super(impl);
    }
    //其他的操作方法
    public void otherOperation(){
 
    }
}
實現類:
public abstract class Implementor {
    /**
     * 示例方法,實現抽象部分需要的某些具體功能
     */
    public abstract void operationImpl();
}

實現類的繼承類:
public class ConcreteImplementorA extends Implementor {
    @Override
    public void operationImpl() {
        //具體操作
    }
}
public class ConcreteImplementorB extends Implementor {
    @Override
    public void operationImpl() {
        //具體操作
    }
} 

    橋樑模式的使用時機:當系統需要在他的抽象和實現之間增加更多的靈活性,或者一個物件有多於一個抽象和是實現時,就需要使用橋樑模式。












相關文章