java設計模式之一 橋接模式
本文介紹設計模式中的橋接(Bridge)模式的概念,用法,以及實際應用中怎麼樣使用橋接模式進行開發。
Bridge模式的概念
Bridge 模式是構造型的設計模式之一。Bridge模式基於類的最小設計原則,透過使用封裝,聚合以及繼承等行為來讓不同的類承擔不同的責任。它的主要特點是把抽象(abstraction)與行為實現(implementation)分離開來,從而可以保持各部分的獨立性以及應對它們的功能擴充套件。
Bridge模式的應用場景
物件導向的程式設計(OOP)裡有類繼承(子類繼承父類)的概念,如果一個類或介面有多個具體實現子類,如果這些子類具有以下特性:
- 存在相對並列的子類屬性。
- 存在概念上的交叉。
- 可變性。
我們就可以用Bridge模式來對其進行抽象與具體,對相關類進行重構。
為了容易理解,我們舉例說明一下,比如汽車類(Car),假設有2個子類,卡車類(Truck)與公交車類(Bus),它們有[設定引擎]這個動作行為,透過不同引擎規格的設定,可以將它們設定為比如為1500cc(Car1500),和2000cc(Car2000)的車。
這樣,不管是1500cc的卡車還是2000cc的卡車,又或是1500cc的公交車還是2000cc的公交車,它們都可以是汽車類的子類,而且:
- 存在相對並列的子類屬性。汽車的種類,與汽車引擎規格是汽車的2個並列的屬性,沒有概念上的重複。
- 存在概念上的交叉。不管是卡車還是公交車,都有1500cc與2000cc引擎規格的車。
- 可變性。除了卡車,公交車之外,可能還有救火車;除了有1500cc與2000cc引擎規格的車之外,還可能有2500cc的車等等。
這樣一來,我們怎麼來設計汽車類呢?
方法一
透過繼承設計所有可能存在的子類。可能我們會想到下面的這種繼承關係:
汽車總類:Car
汽車子類 - 按種類分類:Bus,Truck
汽車子類 - 按引擎分類:Bus1500,Bus2000,Truck1500,Truck2000
這樣設定引擎這個動作就由各個子類加以實現。
但如果以後需要增加一種救火車(FireCar),以及增加一個引擎規格2500cc,需要實現的子類將會有:
Bus1500,Bus2000,Bus2500,Truck1500,Truck2000,Truck2500,FireCar1500,FireCar2000,FireCar2500 多達9個。
也就是說,這種設計方法,子類數目將隨幾何級數增長。
而且,Bus1500,Truck1500的引擎規格相同,它們的引擎設定動作應該是一樣的,但現在把它們分成不同的子類,難以避免執行重複的動作行為。
方法二
分別為Bus以及Truck實現設定不同引擎的方法
汽車總類:Car
汽車子類:Bus,Truck
然後在Bus類裡分別提供1500cc以及2000cc引擎的設定方法:
Bus extends Car {
public setEngine1500cc();
public setEngine2000cc();
}
在Truck類裡也分別提供1500cc以及2000cc引擎的設定方法:
Truck extends Car {
public setEngine1500cc();
public setEngine2000cc();
}
這種情況,子類的數量是被控制了。但一方面,如果每增加一種引擎規格,需要修改所有的汽車子類;另一方面,即使引擎的設定行為一樣,但是不同的汽車子類卻需要提供完全一樣的方法。
在實際的應用開發中,以上2種方法都會造成遷一發而動全身,而且會存在大量的重複程式碼。
Bridge模式可以很好的解決這類問題。
Client
Bridge模式的使用者
Abstraction
抽象類介面(介面或抽象類)
維護對行為實現(Implementor)的引用
Refined Abstraction
Abstraction子類
Implementor
行為實現類介面 (Abstraction介面定義了基於Implementor介面的更高層次的操作)
ConcreteImplementor
Implementor子類
Bridge模式的應用範例
我們來看看怎麼應用Bridge模式來設計汽車類。
抽象 - Abstraction類:汽車類及其子類:
Car:汽車總類
Truck:汽車子類 - 卡車類。
Bus:汽車子類 - 公交車類。
行為實現 - Implementor:汽車引擎設定的行為類及子類
SetCarEngine:汽車引擎的設定介面
SetCarEngine1500cc:設定1500cc引擎
SetCarEngine2000cc:設定2000cc引擎
程式碼:
package zieckey.designpatterns.study.bridge;
//測試
public class Client
{
public static void main( String[] argv )
{
Engine engine1500 = new Engine1500CC();
Engine engine2200 = new Engine2200CC();
Vehicle bus1500 = new Bus( engine1500 );
Vehicle bus2200 = new Bus( engine2200 );
bus1500.setEngine();
bus2200.setEngine();
Vehicle truck1500 = new Truck( engine1500 );
Vehicle truck2200 = new Truck( engine2200 );
truck1500.setEngine();
truck2200.setEngine();
}
}
package zieckey.designpatterns.study.bridge;
/**
*
* 汽車類(Vehicle),假設有2個子類,卡車類(Truck)與公交車類(Bus),
* 它們有[設定引擎]這個動作行為,透過不同引擎規格的設定,
* 可以將它們設定為比如為1500cc(Car1500),和2000cc(Car2000)的車。
* 這樣,不管是1500cc的卡車還是2000cc的卡車,又或是1500cc的公交車還是2000cc的公交車,它們都可以是汽車類的子類,而且:
* - 存在相對並列的子類屬性。汽車的種類,與汽車引擎規格是汽車的2個並列的屬性,沒有概念上的重複。
* - 存在概念上的交叉。不管是卡車還是公交車,都有1500cc與2000cc引擎規格的車。
* - 可變性。除了卡車,公交車之外,可能還有救火車;除了有1500cc與2000cc引擎規格的車之外,還可能有2500cc的車等等。
*
* @author
* @since 2008/06/23
*/
public abstract class Vehicle
{
private Engine engine;
Vehicle( Engine engine )
{
this.setEngine( engine );
}
public abstract void setEngine();
public void setEngine( Engine engine )
{
this.engine = engine;
}
public Engine getEngine()
{
return engine;
}
}
package zieckey.designpatterns.study.bridge;
//Abstraction子類:這裡為汽車抽象類的子類
public class Bus extends Vehicle
{
public Bus( Engine engine)
{
super( engine );
}
@Override
public void setEngine()
{
System.out.print("Set Bus Engine: ");
getEngine().setEngine();
}
}
package zieckey.designpatterns.study.bridge;
//Abstraction子類:這裡為汽車抽象類的子類
public class Truck extends Vehicle
{
public Truck( Engine engine )
{
super( engine );
}
@Override
public void setEngine()
{
System.out.print("Set Truck Engine: ");
getEngine().setEngine();
}
}
package zieckey.designpatterns.study.bridge;
//汽車類的行為介面
public interface Engine
{
public void setEngine();
}
package zieckey.designpatterns.study.bridge;
/** ConcreteImplementor */
//行為實現子類
public class Engine2200CC implements Engine
{
public void setEngine()
{
System.out.println("engine 2200CC");
}
}
package zieckey.designpatterns.study.bridge;
/** ConcreteImplementor */
//行為實現子類
public class Engine1500CC implements Engine
{
public void setEngine()
{
System.out.println("engine 1500CC");
}
}
小結:Bridge模式是一種抽象與其實現相分離的模式。它主要應用於:當事物是一組變化量,和對這些事物的操作方法(實現)也是一組變化量的情況,也就是說它們都是多變的。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/9399028/viewspace-687882/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Java設計模式-橋接模式Java設計模式橋接
- Java設計模式(7)----------橋接模式Java設計模式橋接
- Java設計模式之(六)——橋接模式Java設計模式橋接
- 設計模式-橋接模式設計模式橋接
- 設計模式:橋接模式設計模式橋接
- 小白設計模式:橋接模式設計模式橋接
- 設計模式之橋接模式設計模式橋接
- 設計模式(八)——橋接模式設計模式橋接
- 設計模式之【橋接模式】設計模式橋接
- javascript設計模式橋接模式JavaScript設計模式橋接
- 設計模式(十二):橋接模式設計模式橋接
- JAVA設計模式之 橋接模式【Bridge Pattern】Java設計模式橋接
- PHP 設計模式之橋接模式PHP設計模式橋接
- GoLang設計模式19 - 橋接模式Golang設計模式橋接
- 設計模式 | 橋接模式(bridge)設計模式橋接
- 9.設計模式-橋接模式設計模式橋接
- 極簡設計模式-橋接模式設計模式橋接
- Python設計模式-橋接模式Python設計模式橋接
- 大話設計模式—橋接模式設計模式橋接
- 設計模式之橋接設計模式橋接
- 設計模式(七)橋接設計模式橋接
- 設計模式之旅12--橋接模式設計模式橋接
- 23種設計模式(9)- 橋接模式設計模式橋接
- 設計模式系列 11-- 橋接模式設計模式橋接
- Android設計模式之橋接模式Android設計模式橋接
- 我學設計模式 之 橋接模式設計模式橋接
- 設計模式學習-裝飾模式,橋接模式設計模式橋接
- 《設計模式》 - 6. 橋接模式( Bridge )設計模式橋接
- 設計模式(十三)----結構型模式之橋接模式設計模式橋接
- 10.橋接模式設計思想橋接模式
- C#設計模式-橋接模式(Bridge Pattern)C#設計模式橋接
- C#設計模式系列:橋接模式(Bridge)C#設計模式橋接
- 設計模式--橋接模式Bridge(結構型)設計模式橋接
- 設計模式(五)橋接模式Bridge == Pointer To Implementation設計模式橋接
- 跟著GPT學設計模式之橋接模式GPT設計模式橋接
- Java進階篇設計模式之四 -----介面卡模式和橋接模式Java設計模式橋接
- 橋接模式橋接模式
- 從零開始學設計模式(七)—橋接模式設計模式橋接