<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                ## **橋接(Bridge)模式:** 將抽象與實現分離,使它們可以獨立變化。它是用組合關系代替繼承關系來實現的,從而降低了抽象和實現這兩個可變維度的耦合度。 特點:獨立存在,擴展性強 應用:需要不斷更換調用對象卻執行相同的調用方法,實現擴展功能 將不同的對象傳入橋接對象中通過set和get獲取相應的對象的內容 **橋接(Bridge)模式的優點:** * 由于抽象與實現分離,所以擴展能力強; * 其實現細節對客戶透明。 **缺點是:** * 由于聚合關系建立在抽象層,要求開發者針對抽象化進行設計與編程,這增加了系統的理解與設計難度。 ``` abstract class Fruit{ abstract function?getColor(); } class Apple extends Fruit{ public function?getColor(){ return'red'; } } class Banana extends Fruit{ public function?getColor(){ return'yellow'; } } class BridgeObj{ protected?$_fruit; /** * 設置對象 */ public function?setFruit($fruit){ ???? $this->_fruit?=?$fruit; } public function?getColor(){ return?$this->_fruit->getColor(); } } $obj?=newBridgeObj(); $obj->setFruit(new Apple()); printf("本次橋接對象:%sn",?$obj->getColor()); $obj->setFruit(newBanana()); printf("本次橋接對象:%sn",?$obj->getColor()); ``` **(一)為什么需要橋接模式** 1,如果一個系統需要在構件的抽象化角色和具體化角色之間增加更多的靈活性,避免在兩個層次之間建立靜態的繼承聯系,通過橋接模式可以使它們在抽象層建立一個關聯關系。 2,抽象化角色和實現化角色可以以繼承的方式獨立擴展而互不影響,在程序運行時可以動態將一個抽象化子類的對象和一個實現化子類的對象進行組合,即系統需要對抽象化角色和實現化角色進行動態耦合。 3,雖然在系統中使用繼承是沒有問題的,但是由于抽象化角色和具體化角色需要獨立變化,設計要求需要獨立管理這兩者。對于那些不希望使用繼承或因為多層次繼承導致系統類的個數急劇增加的系統,橋接模式尤為適用。 **(二)橋接模式UML圖** ![圖片描述](https://img.mukewang.com/58dbc01c0001e8e910030543.png "PHP設計模式(九)—橋接模式(BridgePattern)_") * Abstraction為抽象化角色,主要職責是定義該角色的行為,同時保存一個對實現化角色的引用。 * Implementor為實現化角色,它是一個接口或抽象類。在PHP中一般是抽象類。 有點不知所云吧。我學的時候也是。老規矩,來個實例吧。 **(三)簡單實例** 如果我現在是小米公司的雷布斯,小米公司旗下有小米mix和小米note手機,現在有一個底層的語音輸出軟件,由于小米mix的全面屏設計沒有開孔使用了骨傳導,所以和小米note有些不同。那么我們要如何來設計這個輸出功能呢? 傳統的做法就應該是,一個抽象手機品牌,mix和note手機品牌繼承抽象手機品牌。然后有一個mix品牌的輸出軟件繼承自mix品牌。如果這時候有一個redmi的牌子的輸出軟件就應繼承自redmi品牌,redmi繼承抽象手機品牌。 如果除了這個語音輸出軟件,我們還有其它的軟件呢,一個手機有很多軟件,那么這種繼承,如果畫出繼承鏈的話,那一個品牌下得有多少子類? 如果我們使用橋接模式的話,就可以把這個軟件的具體實現與抽象品牌分離出來,這樣也能是我們動態增減實現化角色時更為方便。 ~~~ <?php //抽象化角色 abstract class MiPhone{ protected $_audio; //存放音頻軟件對象 abstract function output(); public function __construct(Audio $audio){ $this->_audio = $audio; } } //具體手機 class Mix extends MiPhone{ //語音輸出功能 public function output(){ $this->_audio->output(); } } class Note extends MiPhone{ public function output(){ $this->_audio->output(); } } //實現化角色 功能實現者 abstract class Audio{ abstract function output(); } //具體音頻實現者 -骨傳導音頻輸出 class Osteophony extends Audio{ public function output(){ echo "骨傳導輸出的聲音-----哈哈".PHP_EOL; } } //普通音頻輸出---聲筒輸出 class Cylinder extends Audio{ public function output(){ echo "聲筒輸出的聲音-----呵呵".PHP_EOL; } } //讓小米mix和小米note輸出聲音 $mix = new Mix(new Osteophony); $mix->output(); $note = new Note(new Cylinder); $note->output(); ~~~ 這樣寫的好處是把抽象化角色手機和實現化角色手機的具體功能音頻輸出 分離了出來。如果現在最新的小米note系列也要用上骨傳導輸出,那么我們只需實例化時傳入的聲筒音頻類改為骨傳導音頻類。如果我們還有一個揚聲器輸出,小米mix和小米note都有這個功能。我們只需要再添加一個揚聲器輸出類繼承Audio類,然后誰使用就保存這個實例在屬性中。沒有橋接模式的話,我們可是要寫兩個,一個是小米mix的揚聲器輸出,一個是小米note。 如果揚聲器輸出對小米mix和小米note不一樣,那么我們確實需要寫兩個揚聲器輸出類。使用橋接模式,依然比原來直接繼承好,就是因為有一天揚聲器技術驅動更新了,我們要更新揚聲器不用修改手機類代碼,而只需傳入一個更新的揚聲器類。 在比如: ![](https://img.kancloud.cn/6f/59/6f59df50e8970f38ffea6065fbca7328_1041x233.png) 類圖 ![](https://img.kancloud.cn/9f/7f/9f7f0c6d5354bfdde03f5531defddefa_1313x491.png) 示例代碼: ``` //抽象類:電腦 abstract class Computer{ protected $phone; public function __construct($phone) { $this->phone = $phone; } public function &__get($property_name) { if(isset($this->$property_name)) { return($this->$property_name); } else { return(NULL); } } public function __set($property_name, $value) { $this->$property_name = $value; } public abstract function connect(); } //接口:手機 interface Phone{ public function connectImpl(); } //華碩品牌的電腦 class ASUSComputer extends Computer{ public function __construct($phone) { $this->phone=$phone; } public function connect() { echo "華碩電腦"; $this->phone->connectImpl(); } } //戴爾品牌的電腦 class DellComputer extends Computer{ public function __construct($phone) { $this->phone=$phone; } public function connect() { echo "戴爾電腦"; $this->phone->connectImpl(); } } //三星手機 class SamsungPhone implements Phone{ public function connectImpl() { echo "連接了三星手機\n"; } } //小米手機 class XiaomiPhone implements Phone{ public function connectImpl() { echo "連接了小米手機\n"; } } //抽象類:人 abstract class Person{ public $computer; public function __construct($computer) { $this->computer = $computer; } public abstract function useComputer(); } //學生 class Student extends Person{ public function useComputer() { echo "學生使用"; $this->computer->connect(); } } //老師 class Teacher extends Person{ public function useComputer() { echo "教師使用"; $this->computer->connect(); } } function main(){ //華碩電腦連接了小米手機 $asusComputer=new ASUSComputer(new XiaomiPhone()); $asusComputer->connect(); //戴爾電腦連接了三星手機 $dellComputer=new DellComputer(new SamsungPhone()); $dellComputer->connect(); //學生使用華碩電腦連接了小米手機 $student=new Student(new ASUSComputer(new XiaomiPhone())); $student->useComputer(); //教師使用戴爾電腦連接了三星手機 $teacher=new Teacher(new DellComputer(new SamsungPhone())); $teacher->useComputer(); } main(); 輸出結果: 華碩電腦連接了小米手機 戴爾電腦連接了三星手機 學生使用華碩電腦連接了小米手機 ``` 舉例:   車分為很多種(小轎車,公交車),并且每種車都會跑在不同的道路上(街道,高速路),如果使用繼承的方式我們可以實現這些場景   但是那樣做的話會使得代碼變得可擴展行很差,但是使用橋接模式就不一樣啦 ~~~ abstract class Road{ public $car; public function __construct(Car $car){ $this->car = $car; } public abstract function run(); } class SpeedWay extends Road{ public function run(){ echo $this->car->name." run on SpeedWay\n"; } } class Street extends Road{ public function run(){ echo $this->car->name." run on Street\n"; } } abstract class Car{ public $name; } class SmallCar extends Car{ public function __construct(){ $this->name = "SmallCar"; } } class Bus extends Car{ public function __construct(){ $this->name = "Bus"; } } $small_car = new SmallCar(); $SpeedWay = new SpeedWay($small_car); $SpeedWay->run(); $bus = new Bus(); $Street = new Street($bus); $Street->run(); ~~~ 例子: ![](https://img.kancloud.cn/3b/7e/3b7e0d7a04c514247c6ca5b0b82fb8ae_661x525.png) ``` <?php //實現化角色:顏色 interface Color{ function getColor(); } //具體實現化角色:黃色 class Yellow implements Color{ public function getColor(){ return "yellow"; } } //具體實現化角色:紅色 class Red implements Color{ public function getColor(){ return "red"; } } //抽象化角色:包 abstract class Bag{ protected $color; public function setColor($color){ $this->color=$color; } abstract public function getName(); } //擴展抽象化角色:挎包 class HandBag extends Bag{ public function getName(){ return $this->color->getColor()."的HandBag(挎包)"; } } //擴展抽象化角色:錢包 class Wallet extends Bag{ public function getName(){ return $this->color->getColor()."的Wallet(錢包)"; } } class BagManage{ public static function main(){ $color=new Yellow(); $bag=new HandBag(); $bag->setColor($color); echo $bag->getName(); $color=new Red(); $bag=new Wallet(); $bag->setColor($color); echo $bag->getName(); } } BagManage::main(); ``` 使用場景:   當一個類存在兩個獨立變化的維度,且這兩個維度都需要進行擴展時。   當一個系統不希望使用繼承或因為多層次繼承導致系統類的個數急劇增加時。   當一個系統需要在構件的抽象化角色和具體化角色之間增加更多的靈活性時。 ## 橋接模式模式的擴展 在軟件開發中,有時橋接(Bridge)模式可與[適配器模式](http://c.biancheng.net/view/1361.html)聯合使用。當橋接(Bridge)模式的實現化角色的接口與現有類的接口不一致時,可以在二者中間定義一個適配器將二者連接起來,其具體結構圖如圖 5 所示。 ![](https://img.kancloud.cn/a6/67/a66767a81c6c38956fe57fea4c49d44b_598x494.png)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看