1. 程式人生 > >java橋接模式

java橋接模式

參考:http://www.cnblogs.com/houleixx/archive/2008/02/23/1078877.html

學習設計模式也有一段時間了,今天就把我整理的一篇課程和大家分享,有不妥之處歡迎指出. 

生活中的例子

就拿汽車在路上行駛的來說。即有小汽車又有公共汽車,它們都不但能在市區中的公路上行駛,也能在高速公路上行駛。這你會發現,對於交通工具(汽車)有不同的型別,然而它們所行駛的環境(路)也在變化,在軟體系統中就要適應兩個方面的變化?怎樣實現才能應對這種變化呢?

概述

在軟體系統中,某些型別由於自身的邏輯,它具有兩個或多個維度的變化,那麼如何應對這種“多維度的變化”?如何利用面嚮物件的技術來使得該型別能夠輕鬆的沿著多個方向進行變化,而又不引入額外的複雜度?這就要使用Bridge模式。

意圖

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

                                                                    ——《設計模式》GOF 

結構圖


傳統類圖


      

例:


package bridge;

/**
 * Implementor 抽象汽車
 * */
public abstract class AbstractCar {

	public abstract void run();
}

package bridge;

/**
 * RefinedAbstraction 高速公路
 * */
public class SpeedWay extends AbstractRoad {

	public SpeedWay(AbstractCar car) {
		super(car);
		// TODO Auto-generated constructor stub
	}

	@Override
	public void run() {
		// TODO Auto-generated method stub
		System.out.println("高速公路上:");
		car.run();
	}

}

package bridge;

/**
 * RefinedAbstraction 市區街道
 * */
public class Street extends AbstractRoad {

	public Street(AbstractCar car) {
		super(car);
		// TODO Auto-generated constructor stub
	}

	@Override
	public void run() {
		// TODO Auto-generated method stub
		System.out.println("市區街道:");
		car.run();
	}

}
package bridge;

/**
 * Implementor 抽象汽車
 * */
public abstract class AbstractCar {

	public abstract void run();
}

package bridge;

/**
 * 
 * ConcreteImplementor 小汽車
 * */
public class Car extends AbstractCar {

	@Override
	public void run() {
		// TODO Auto-generated method stub
		System.out.println("小汽車跑");
	}

}

package bridge;

/**
 * 
 * ConcreteImplementor 公交車
 * */
public class Bus extends AbstractCar {

	@Override
	public void run() {
		// TODO Auto-generated method stub
		System.out.println("公交車跑");
	}

}

package bridge;

/**
 * client
 * */
public class Client {

	public static void main(String[] args) {

		AbstractCar car = new Bus();
		AbstractRoad road = new SpeedWay(car);
		road.run();

		AbstractCar car2 = new Car();
		road = new SpeedWay(car2);
		road.run();
	}
}

效果以及實現要點

1.Bridge模式使用“物件間的組合關係”解耦了抽象和實現之間固有的繫結關係,使得抽象和實現可以沿著各自的維度來變化。 2.所謂抽象和實現沿著各自維度的變化,即“子類化”它們,得到各個子類之後,便可以任意它們,從而獲得不同路上的不同汽車。
3.Bridge模式有時候類似於多繼承方案,但是多繼承方案往往違背了類的單一職責原則(即一個類只有一個變化的原因),複用性比較差。Bridge模式是比多繼承方案更好的解決方法。
4.Bridge模式的應用一般在“兩個非常強的變化維度”,有時候即使有兩個變化的維度,但是某個方向的變化維度並不劇烈——換言之兩個變化不會導致縱橫交錯的結果,並不一定要使用Bridge模式。

適用性:

1.如果一個系統需要在構件的抽象化角色和具體化角色之間增加更多的靈活性,避免在兩個層次之間建立靜態的聯絡。 
2.設計要求實現化角色的任何改變不應當影響客戶端,或者說實現化角色的改變對客戶端是完全透明的。
3.一個構件有多於一個的抽象化角色和實現化角色,系統需要它們之間進行動態耦合。 
4.雖然在系統中使用繼承是沒有問題的,但是由於抽象化角色和具體化角色需要獨立變化,設計要求需要獨立管理這兩者。
總結:
      Bridge模式是一個非常有用的模式,也非常複雜,它很好的符合了開放-封閉原則和優先使用物件,而不是繼承這兩個面向物件原則。

橋接模式與裝飾模式的區別

裝飾模式:
      這兩個模式在一定程度上都是為了減少子類的數目,避免出現複雜的繼承關係。但是它們解決的方法卻各有不同,裝飾模式把子類中比基類中多出來的部分放到單獨的類裡面,以適應新功能增加的需要,當我們把描述新功能的類封裝到基類的物件裡面時,就得到了所需要的子類物件,這些描述新功能的類通過組合可以實現很多的功能組合 .
橋接模式:
          橋接模式則把原來的基類的實現化細節抽象出來,在構造到一個實現化的結構中,然後再把原來的基類改造成一個抽象化的等級結構,這樣就可以實現系統在多個維度上的獨立變化 。