模式定義
橋接模式即将抽象部分與它的實作部分分離開來,使他們都可以獨立變化。
橋接模式将繼承關系轉化成關聯關系,它降低了類與類之間的耦合度,減少了系統中類的數量,也減少了代碼量。
将抽象部分與他的實作部分分離這句話不是很好了解,其實這并不是将抽象類與他的派生類分離,而是抽象類和它的派生類用來實作自己的對象。這樣還是不能了解的話。我們就先來認清什麼是抽象化,什麼是實作化,什麼是脫耦。
抽象化:其概念是将複雜物體的一個或幾個特性抽出去而隻注意其他特性的行動或過程。在面向對象就是将對象共同的性質抽取出去而形成類的過程。
實作化:針對抽象化給出的具體實作。它和抽象化是一個互逆的過程,實作化是對抽象化事物的進一步具體化。
脫耦:脫耦就是将抽象化和實作化之間的耦合解脫開,或者說是将它們之間的強關聯改換成弱關聯,将兩個角色之間的繼承關系改為關聯關系。
對于那句話:将抽象部分與他的實作部分分離套用《大話設計模式》裡面的就是實作系統可能有多個角度分類,每一種角度都可能變化,那麼把這種多角度分類給分離出來讓他們獨立變化,減少他們之間耦合。
橋接模式中的所謂脫耦,就是指在一個軟體系統的抽象化和實作化之間使用關聯關系(組合或者聚合關系)而不是繼承關系,進而使兩者可以相對獨立地變化,這就是橋接模式的用意。
模式結構
橋接模式主要包含如下幾個角色:
Abstraction:抽象類。
RefinedAbstraction:擴充抽象類。
Implementor:實作類接口。
ConcreteImplementor:具體實作類 。
UML圖如下
橋接模式UML.png
案例說明
我們通過一個簡單的案例來說明橋接模式的用法
一切的對象都是基于現實生活的抽象,那我們以不同顔色不同形狀的實體舉例。假設我們現在擁有紅,綠,藍三種顔色,擁有圓形,正方形和菱形三種物體,我們希望得到不同物體的不同顔色的列印。
方法1:
定義實體類:
顔色三種,物品三種。生成3*3個實體類=9
這種方法的缺點在于,如果我在添加一個顔色,或者添加一個物品,那個對應的實體類個數就要增加,這樣的方法一定是不适用的,太過笨。
方法2:
采用顔色和物品組合的方法實作功能
我們列印出物品的顔色,那我們首先要知道是什麼物品,物品是什麼顔色。
基于這倆個問題我們其實可以得到一個方法 物品.列印(顔色)
基于橋接模式角色定義我們可以一一比對
物品是抽象類的實作
顔色是接口
1、我們首先需要一個物品的基類,讓所有的物品實作這個基類,調用基類抽象方法列印物品。
2、定義顔色接口,定義顔色類實作接口方法,接口定義的方法就是傳回目前的顔色
3、物品調用抽象應該有一個形參(IColor),友善在列印物品的時候添加顔色說明
案例編碼
形狀
/// <summary>
/// 形狀抽象基類
/// </summary>
public abstract class Shape
{
public abstract void Draw(IColor color);
}
/// <summary>
/// 圓形類
/// </summary>
public class Cycle : Shape
{
public override void Draw(IColor color)
{
Console.WriteLine(color.GetColor() + "圓形");
}
}
/// <summary>
/// 正方形類
/// </summary>
public class Square : Shape
{
public override void Draw(IColor color)
{
Console.WriteLine(color.GetColor() + "正方形");
}
}
顔色
/// <summary>
/// 顔色接口
/// </summary>
public interface IColor
{
string GetColor();
}
public class WhiteColor : IColor
{
public string GetColor()
{
return "白色";
}
}
public class BlankColor : IColor
{
public string GetColor()
{
return "黑色";
}
}
調用
public class ShapeColor
{
public static void PrintShapeColor()
{
Shape shape = new Cycle();//執行個體化形狀類
IColor color = new WhiteColor();//執行個體化顔色類
shape.Draw(color);//形狀調用顔色
//實作耦合,使用組合模式而不是繼承模式
}
}