橋接模式:將抽象部分與它的實現部分分離,使它們都可以獨立地變化。
適用性:
1、不希望在抽象和它的實現部分之間有一個固定的綁定關系。例如這種情況可能是因為,在程序運行時刻實現部分應可以被選擇或者切換。
2、類的抽象以及它的實現都應該可以通過生成子類的方法加以擴充。這是橋接模式使你可以對不同的抽象接口和實現部分進行組合,并分別對它們進行擴充。
3、對一個抽象的實現部分的修改應對客戶不產生影響,即客戶的代碼不必重新編譯。
4、(C++)你想對客戶完全隱藏抽象的實現部分。在C++中,類的表示在類接口中是可見的。
5、有許多類要生成。這樣一種類層次結構說明你必須將一個對象分解成兩個部分。Rumbaugh稱這種類層次結構為“嵌套的普化”(nested generalizations)。
6、現在對個對象間共享實現(可能使用引用計數),但同時要求客戶并不知道這一點。一個簡單的例子便是Coplien的String類,在這個類中多個對象可以共享同一個字符串表示(StringRep)。
角色解析:
1、抽象化角色:抽象化給出的定義,并保存一個對實現化對象的引用。
2、修正抽象化角色:擴展抽象化角色,改變和修正父類對抽象化的定義。
3、實現化角色:這個角色給出實現化角色的接口,但不給出具體的實現。必須指出的是,這個接口不一定和抽象化角色的接口定義相同,實際上,這兩個接口可以非常不一樣。
4、具體實現化角色:這個角色給出實現化角色接口具體實現。
優點:
1、抽象和實現的分離。
2、優秀的擴展能力。
3、實現細節對客戶透明。
缺點:
橋接模式的引入會增加系統給的理解與設計難度,由于聚合關聯關系建立在抽象層,要求開發者針對抽象進行設計與編程。
使用場景:
1、如果一個系統需要在構建的抽象化角色和具體化角色之間增加更多的靈活性,避免在兩個層次之間建立靜態的聯系。
2、設計要求實現化角色的任何改變不應當影響客戶端,或者說實現化角色的改變對客戶端是完全透明的。
3、一個構件有多于一個的抽象化角色和實現化角色,系統需要它們之間進行動態耦合。
4、雖然在系統中使用繼承是沒有問題的,但是由于抽象化角色和具體化角色需要獨立變化,設計要求需要獨立管理這兩者。
例:
//員工分組
abstract class Staff
{
??? abstract public function staffData();
}
class CommonStaff extends Staff
{
??? public function staffData()
??? {
??????? return '愛因斯坦';
??? }
}
class VipStaff extends Staff
{
??? public function staffData()
??? {
??????? return '愛迪生';
??? }
}
//發送方式
abstract class SendType
{
??? abstract public function send($to,$content);
}
class QQSend extends SendType
{
??? public function __construct()
??? {
??????? //與QQ接口連接方式
??? }
??? public function send()
??? {
??????? return $content.' to '.$to.' From QQSend<br>';
??? }
}
//發送信息
class SendInfo
{
??? protected $_level;//員工分組
??? protected $_method;//發送方式
??? public function __construct($level,$method)
??? {
??????? //這里可以使用單例控制資源的消耗
??????? $this->_level = $level;
??????? $this->_method = $method;
??? }
??? public function sending($content)
??? {
??????? //當前員工分組的成員數組
??????? $staffArr = $this->_level->staffData();
??????? //通過傳入的發送方式,向成員發送內容
??????? $result = $this->_method->send($staffArr,$content);
??????? echo $result;
??? }
}
//調用
$info = new SendInfo(new VipStaff(),new QQSend());
$info->sending('666');
$info = new SendInfo(new commonStaff(),new QQSend());
$info->sending('777');