ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、视频、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
# 桥接模式 ## **桥接(Bridge)模式:** 将抽象与实现分离,使它们可以独立变化。它是用组合关系代替继承关系来实现的,从而降低了抽象和实现这两个可变维度的耦合度。 特点:独立存在,扩展性强 应用:需要不断更换调用对象却执行相同的调用方法,实现扩展功能 将不同的对象传入桥接对象中通过set和get获取相应的对象的内容 **桥接(Bridge)模式的优点:** - 由于抽象与实现分离,所以扩展能力强; - 其实现细节对客户透明。 **缺点是:** - 由于聚合关系建立在抽象层,要求开发者针对抽象化进行设计与编程,这增加了系统的理解与设计难度。 ``` <pre class="calibre10">``` abstract class <span class="token4">Fruit</span><span class="token3">{</span> abstract <span class="token5">function</span> <span class="token4">getColor</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span> class <span class="token4">Apple</span> extends <span class="token4">Fruit</span><span class="token3">{</span> public <span class="token5">function</span> <span class="token4">getColor</span><span class="token3">(</span><span class="token3">)</span><span class="token3">{</span> <span class="token5">return</span><span class="token2">'red'</span><span class="token3">;</span> <span class="token3">}</span> <span class="token3">}</span> class <span class="token4">Banana</span> extends <span class="token4">Fruit</span><span class="token3">{</span> public <span class="token5">function</span> <span class="token4">getColor</span><span class="token3">(</span><span class="token3">)</span><span class="token3">{</span> <span class="token5">return</span><span class="token2">'yellow'</span><span class="token3">;</span> <span class="token3">}</span> <span class="token3">}</span> class <span class="token4">BridgeObj</span><span class="token3">{</span> protected $_fruit<span class="token3">;</span> <span class="token">/** * 设置对象 */</span> public <span class="token5">function</span> <span class="token4">setFruit</span><span class="token3">(</span>$fruit<span class="token3">)</span><span class="token3">{</span> $this<span class="token1">-</span><span class="token1">></span>_fruit <span class="token1">=</span> $fruit<span class="token3">;</span> <span class="token3">}</span> public <span class="token5">function</span> <span class="token4">getColor</span><span class="token3">(</span><span class="token3">)</span><span class="token3">{</span> <span class="token5">return</span> $this<span class="token1">-</span><span class="token1">></span>_fruit<span class="token1">-</span><span class="token1">></span><span class="token4">getColor</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span> <span class="token3">}</span> $obj <span class="token1">=</span><span class="token4">newBridgeObj</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span> $obj<span class="token1">-</span><span class="token1">></span><span class="token4">setFruit</span><span class="token3">(</span><span class="token5">new</span> <span class="token4">Apple</span><span class="token3">(</span><span class="token3">)</span><span class="token3">)</span><span class="token3">;</span> <span class="token4">printf</span><span class="token3">(</span><span class="token2">"本次桥接对象:%sn"</span><span class="token3">,</span> $obj<span class="token1">-</span><span class="token1">></span><span class="token4">getColor</span><span class="token3">(</span><span class="token3">)</span><span class="token3">)</span><span class="token3">;</span> $obj<span class="token1">-</span><span class="token1">></span><span class="token4">setFruit</span><span class="token3">(</span><span class="token4">newBanana</span><span class="token3">(</span><span class="token3">)</span><span class="token3">)</span><span class="token3">;</span> <span class="token4">printf</span><span class="token3">(</span><span class="token2">"本次桥接对象:%sn"</span><span class="token3">,</span> $obj<span class="token1">-</span><span class="token1">></span><span class="token4">getColor</span><span class="token3">(</span><span class="token3">)</span><span class="token3">)</span><span class="token3">;</span> ``` ``` **(一)为什么需要桥接模式** 1,如果一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性,避免在两个层次之间建立静态的继承联系,通过桥接模式可以使它们在抽象层建立一个关联关系。 2,抽象化角色和实现化角色可以以继承的方式独立扩展而互不影响,在程序运行时可以动态将一个抽象化子类的对象和一个实现化子类的对象进行组合,即系统需要对抽象化角色和实现化角色进行动态耦合。 3,虽然在系统中使用继承是没有问题的,但是由于抽象化角色和具体化角色需要独立变化,设计要求需要独立管理这两者。对于那些不希望使用继承或因为多层次继承导致系统类的个数急剧增加的系统,桥接模式尤为适用。 **(二)桥接模式UML图** ![](https://img.mukewang.com/58dbc01c0001e8e910030543.png) - Abstraction为抽象化角色,主要职责是定义该角色的行为,同时保存一个对实现化角色的引用。 - Implementor为实现化角色,它是一个接口或抽象类。在PHP中一般是抽象类。 有点不知所云吧。我学的时候也是。老规矩,来个实例吧。 **(三)简单实例** 如果我现在是小米公司的雷布斯,小米公司旗下有小米mix和小米note手机,现在有一个底层的语音输出软件,由于小米mix的全面屏设计没有开孔使用了骨传导,所以和小米note有些不同。那么我们要如何来设计这个输出功能呢? 传统的做法就应该是,一个抽象手机品牌,mix和note手机品牌继承抽象手机品牌。然后有一个mix品牌的输出软件继承自mix品牌。如果这时候有一个redmi的牌子的输出软件就应继承自redmi品牌,redmi继承抽象手机品牌。 如果除了这个语音输出软件,我们还有其它的软件呢,一个手机有很多软件,那么这种继承,如果画出继承链的话,那一个品牌下得有多少子类? 如果我们使用桥接模式的话,就可以把这个软件的具体实现与抽象品牌分离出来,这样也能是我们动态增减实现化角色时更为方便。 ``` <pre class="calibre10">``` <span class="token1"><</span><span class="token1">?</span>php <span class="token">//抽象化角色</span> abstract class <span class="token4">MiPhone</span><span class="token3">{</span> protected $_audio<span class="token3">;</span> <span class="token">//存放音频软件对象</span> abstract <span class="token5">function</span> <span class="token4">output</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span> public <span class="token5">function</span> <span class="token4">__construct</span><span class="token3">(</span>Audio $audio<span class="token3">)</span><span class="token3">{</span> $this<span class="token1">-</span><span class="token1">></span>_audio <span class="token1">=</span> $audio<span class="token3">;</span> <span class="token3">}</span> <span class="token3">}</span> <span class="token">//具体手机</span> class <span class="token4">Mix</span> extends <span class="token4">MiPhone</span><span class="token3">{</span> <span class="token">//语音输出功能</span> public <span class="token5">function</span> <span class="token4">output</span><span class="token3">(</span><span class="token3">)</span><span class="token3">{</span> $this<span class="token1">-</span><span class="token1">></span>_audio<span class="token1">-</span><span class="token1">></span><span class="token4">output</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span> <span class="token3">}</span> class <span class="token4">Note</span> extends <span class="token4">MiPhone</span><span class="token3">{</span> public <span class="token5">function</span> <span class="token4">output</span><span class="token3">(</span><span class="token3">)</span><span class="token3">{</span> $this<span class="token1">-</span><span class="token1">></span>_audio<span class="token1">-</span><span class="token1">></span><span class="token4">output</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span> <span class="token3">}</span> <span class="token">//实现化角色 功能实现者</span> abstract class <span class="token4">Audio</span><span class="token3">{</span> abstract <span class="token5">function</span> <span class="token4">output</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span> <span class="token">//具体音频实现者 -骨传导音频输出</span> class <span class="token4">Osteophony</span> extends <span class="token4">Audio</span><span class="token3">{</span> public <span class="token5">function</span> <span class="token4">output</span><span class="token3">(</span><span class="token3">)</span><span class="token3">{</span> echo <span class="token2">"骨传导输出的声音-----哈哈"</span><span class="token3">.</span>PHP_EOL<span class="token3">;</span> <span class="token3">}</span> <span class="token3">}</span> <span class="token">//普通音频输出---声筒输出</span> class <span class="token4">Cylinder</span> extends <span class="token4">Audio</span><span class="token3">{</span> public <span class="token5">function</span> <span class="token4">output</span><span class="token3">(</span><span class="token3">)</span><span class="token3">{</span> echo <span class="token2">"声筒输出的声音-----呵呵"</span><span class="token3">.</span>PHP_EOL<span class="token3">;</span> <span class="token3">}</span> <span class="token3">}</span> <span class="token">//让小米mix和小米note输出声音</span> $mix <span class="token1">=</span> <span class="token5">new</span> <span class="token4">Mix</span><span class="token3">(</span><span class="token5">new</span> <span class="token4">Osteophony</span><span class="token3">)</span><span class="token3">;</span> $mix<span class="token1">-</span><span class="token1">></span><span class="token4">output</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span> $note <span class="token1">=</span> <span class="token5">new</span> <span class="token4">Note</span><span class="token3">(</span><span class="token5">new</span> <span class="token4">Cylinder</span><span class="token3">)</span><span class="token3">;</span> $note<span class="token1">-</span><span class="token1">></span><span class="token4">output</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span> ``` ``` 这样写的好处是把抽象化角色手机和实现化角色手机的具体功能音频输出 分离了出来。如果现在最新的小米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) 示例代码: ``` <pre class="calibre10">``` <span class="token">//抽象类:电脑</span> abstract class <span class="token4">Computer</span><span class="token3">{</span> protected $phone<span class="token3">;</span> public <span class="token5">function</span> <span class="token4">__construct</span><span class="token3">(</span>$phone<span class="token3">)</span> <span class="token3">{</span> $this<span class="token1">-</span><span class="token1">></span>phone <span class="token1">=</span> $phone<span class="token3">;</span> <span class="token3">}</span> public <span class="token5">function</span> <span class="token1">&</span><span class="token4">__get</span><span class="token3">(</span>$property_name<span class="token3">)</span> <span class="token3">{</span> <span class="token5">if</span><span class="token3">(</span><span class="token4">isset</span><span class="token3">(</span>$this<span class="token1">-</span><span class="token1">></span>$property_name<span class="token3">)</span><span class="token3">)</span> <span class="token3">{</span> <span class="token5">return</span><span class="token3">(</span>$this<span class="token1">-</span><span class="token1">></span>$property_name<span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span> <span class="token5">else</span> <span class="token3">{</span> <span class="token5">return</span><span class="token3">(</span>NULL<span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span> <span class="token3">}</span> public <span class="token5">function</span> <span class="token4">__set</span><span class="token3">(</span>$property_name<span class="token3">,</span> $value<span class="token3">)</span> <span class="token3">{</span> $this<span class="token1">-</span><span class="token1">></span>$property_name <span class="token1">=</span> $value<span class="token3">;</span> <span class="token3">}</span> public abstract <span class="token5">function</span> <span class="token4">connect</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span> <span class="token">//接口:手机</span> interface <span class="token4">Phone</span><span class="token3">{</span> public <span class="token5">function</span> <span class="token4">connectImpl</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span> <span class="token">//华硕品牌的电脑</span> class <span class="token4">ASUSComputer</span> extends <span class="token4">Computer</span><span class="token3">{</span> public <span class="token5">function</span> <span class="token4">__construct</span><span class="token3">(</span>$phone<span class="token3">)</span> <span class="token3">{</span> $this<span class="token1">-</span><span class="token1">></span>phone<span class="token1">=</span>$phone<span class="token3">;</span> <span class="token3">}</span> public <span class="token5">function</span> <span class="token4">connect</span><span class="token3">(</span><span class="token3">)</span> <span class="token3">{</span> echo <span class="token2">"华硕电脑"</span><span class="token3">;</span> $this<span class="token1">-</span><span class="token1">></span>phone<span class="token1">-</span><span class="token1">></span><span class="token4">connectImpl</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span> <span class="token3">}</span> <span class="token">//戴尔品牌的电脑</span> class <span class="token4">DellComputer</span> extends <span class="token4">Computer</span><span class="token3">{</span> public <span class="token5">function</span> <span class="token4">__construct</span><span class="token3">(</span>$phone<span class="token3">)</span> <span class="token3">{</span> $this<span class="token1">-</span><span class="token1">></span>phone<span class="token1">=</span>$phone<span class="token3">;</span> <span class="token3">}</span> public <span class="token5">function</span> <span class="token4">connect</span><span class="token3">(</span><span class="token3">)</span> <span class="token3">{</span> echo <span class="token2">"戴尔电脑"</span><span class="token3">;</span> $this<span class="token1">-</span><span class="token1">></span>phone<span class="token1">-</span><span class="token1">></span><span class="token4">connectImpl</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span> <span class="token3">}</span> <span class="token">//三星手机</span> class <span class="token4">SamsungPhone</span> implements <span class="token4">Phone</span><span class="token3">{</span> public <span class="token5">function</span> <span class="token4">connectImpl</span><span class="token3">(</span><span class="token3">)</span> <span class="token3">{</span> echo <span class="token2">"连接了三星手机\n"</span><span class="token3">;</span> <span class="token3">}</span> <span class="token3">}</span> <span class="token">//小米手机</span> class <span class="token4">XiaomiPhone</span> implements <span class="token4">Phone</span><span class="token3">{</span> public <span class="token5">function</span> <span class="token4">connectImpl</span><span class="token3">(</span><span class="token3">)</span> <span class="token3">{</span> echo <span class="token2">"连接了小米手机\n"</span><span class="token3">;</span> <span class="token3">}</span> <span class="token3">}</span> <span class="token">//抽象类:人</span> abstract class <span class="token4">Person</span><span class="token3">{</span> public $computer<span class="token3">;</span> public <span class="token5">function</span> <span class="token4">__construct</span><span class="token3">(</span>$computer<span class="token3">)</span> <span class="token3">{</span> $this<span class="token1">-</span><span class="token1">></span>computer <span class="token1">=</span> $computer<span class="token3">;</span> <span class="token3">}</span> public abstract <span class="token5">function</span> <span class="token4">useComputer</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span> <span class="token">//学生</span> class <span class="token4">Student</span> extends <span class="token4">Person</span><span class="token3">{</span> public <span class="token5">function</span> <span class="token4">useComputer</span><span class="token3">(</span><span class="token3">)</span> <span class="token3">{</span> echo <span class="token2">"学生使用"</span><span class="token3">;</span> $this<span class="token1">-</span><span class="token1">></span>computer<span class="token1">-</span><span class="token1">></span><span class="token4">connect</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span> <span class="token3">}</span> <span class="token">//老师</span> class <span class="token4">Teacher</span> extends <span class="token4">Person</span><span class="token3">{</span> public <span class="token5">function</span> <span class="token4">useComputer</span><span class="token3">(</span><span class="token3">)</span> <span class="token3">{</span> echo <span class="token2">"教师使用"</span><span class="token3">;</span> $this<span class="token1">-</span><span class="token1">></span>computer<span class="token1">-</span><span class="token1">></span><span class="token4">connect</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span> <span class="token3">}</span> <span class="token5">function</span> <span class="token4">main</span><span class="token3">(</span><span class="token3">)</span><span class="token3">{</span> <span class="token">//华硕电脑连接了小米手机</span> $asusComputer<span class="token1">=</span><span class="token5">new</span> <span class="token4">ASUSComputer</span><span class="token3">(</span><span class="token5">new</span> <span class="token4">XiaomiPhone</span><span class="token3">(</span><span class="token3">)</span><span class="token3">)</span><span class="token3">;</span> $asusComputer<span class="token1">-</span><span class="token1">></span><span class="token4">connect</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span> <span class="token">//戴尔电脑连接了三星手机</span> $dellComputer<span class="token1">=</span><span class="token5">new</span> <span class="token4">DellComputer</span><span class="token3">(</span><span class="token5">new</span> <span class="token4">SamsungPhone</span><span class="token3">(</span><span class="token3">)</span><span class="token3">)</span><span class="token3">;</span> $dellComputer<span class="token1">-</span><span class="token1">></span><span class="token4">connect</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span> <span class="token">//学生使用华硕电脑连接了小米手机</span> $student<span class="token1">=</span><span class="token5">new</span> <span class="token4">Student</span><span class="token3">(</span><span class="token5">new</span> <span class="token4">ASUSComputer</span><span class="token3">(</span><span class="token5">new</span> <span class="token4">XiaomiPhone</span><span class="token3">(</span><span class="token3">)</span><span class="token3">)</span><span class="token3">)</span><span class="token3">;</span> $student<span class="token1">-</span><span class="token1">></span><span class="token4">useComputer</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span> <span class="token">//教师使用戴尔电脑连接了三星手机</span> $teacher<span class="token1">=</span><span class="token5">new</span> <span class="token4">Teacher</span><span class="token3">(</span><span class="token5">new</span> <span class="token4">DellComputer</span><span class="token3">(</span><span class="token5">new</span> <span class="token4">SamsungPhone</span><span class="token3">(</span><span class="token3">)</span><span class="token3">)</span><span class="token3">)</span><span class="token3">;</span> $teacher<span class="token1">-</span><span class="token1">></span><span class="token4">useComputer</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span> <span class="token4">main</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span> 输出结果: 华硕电脑连接了小米手机 戴尔电脑连接了三星手机 学生使用华硕电脑连接了小米手机 ``` ``` 举例: 车分为很多种(小轿车,公交车),并且每种车都会跑在不同的道路上(街道,高速路),如果使用继承的方式我们可以实现这些场景 但是那样做的话会使得代码变得可扩展行很差,但是使用桥接模式就不一样啦 ``` <pre class="calibre10">``` abstract class <span class="token4">Road</span><span class="token3">{</span> public $car<span class="token3">;</span> public <span class="token5">function</span> <span class="token4">__construct</span><span class="token3">(</span>Car $car<span class="token3">)</span><span class="token3">{</span> $this<span class="token1">-</span><span class="token1">></span>car <span class="token1">=</span> $car<span class="token3">;</span> <span class="token3">}</span> public abstract <span class="token5">function</span> <span class="token4">run</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span> class <span class="token4">SpeedWay</span> extends <span class="token4">Road</span><span class="token3">{</span> public <span class="token5">function</span> <span class="token4">run</span><span class="token3">(</span><span class="token3">)</span><span class="token3">{</span> echo $this<span class="token1">-</span><span class="token1">></span>car<span class="token1">-</span><span class="token1">></span>name<span class="token3">.</span><span class="token2">" run on SpeedWay\n"</span><span class="token3">;</span> <span class="token3">}</span> <span class="token3">}</span> class <span class="token4">Street</span> extends <span class="token4">Road</span><span class="token3">{</span> public <span class="token5">function</span> <span class="token4">run</span><span class="token3">(</span><span class="token3">)</span><span class="token3">{</span> echo $this<span class="token1">-</span><span class="token1">></span>car<span class="token1">-</span><span class="token1">></span>name<span class="token3">.</span><span class="token2">" run on Street\n"</span><span class="token3">;</span> <span class="token3">}</span> <span class="token3">}</span> abstract class <span class="token4">Car</span><span class="token3">{</span> public $name<span class="token3">;</span> <span class="token3">}</span> class <span class="token4">SmallCar</span> extends <span class="token4">Car</span><span class="token3">{</span> public <span class="token5">function</span> <span class="token4">__construct</span><span class="token3">(</span><span class="token3">)</span><span class="token3">{</span> $this<span class="token1">-</span><span class="token1">></span>name <span class="token1">=</span> <span class="token2">"SmallCar"</span><span class="token3">;</span> <span class="token3">}</span> <span class="token3">}</span> class <span class="token4">Bus</span> extends <span class="token4">Car</span><span class="token3">{</span> public <span class="token5">function</span> <span class="token4">__construct</span><span class="token3">(</span><span class="token3">)</span><span class="token3">{</span> $this<span class="token1">-</span><span class="token1">></span>name <span class="token1">=</span> <span class="token2">"Bus"</span><span class="token3">;</span> <span class="token3">}</span> <span class="token3">}</span> $small_car <span class="token1">=</span> <span class="token5">new</span> <span class="token4">SmallCar</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span> $SpeedWay <span class="token1">=</span> <span class="token5">new</span> <span class="token4">SpeedWay</span><span class="token3">(</span>$small_car<span class="token3">)</span><span class="token3">;</span> $SpeedWay<span class="token1">-</span><span class="token1">></span><span class="token4">run</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span> $bus <span class="token1">=</span> <span class="token5">new</span> <span class="token4">Bus</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span> $Street <span class="token1">=</span> <span class="token5">new</span> <span class="token4">Street</span><span class="token3">(</span>$bus<span class="token3">)</span><span class="token3">;</span> $Street<span class="token1">-</span><span class="token1">></span><span class="token4">run</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span> ``` ``` 例子: ![](https://img.kancloud.cn/3b/7e/3b7e0d7a04c514247c6ca5b0b82fb8ae_661x525.png) ``` <pre class="calibre10">``` <span class="token1"><</span><span class="token1">?</span>php <span class="token">//实现化角色:颜色</span> interface <span class="token4">Color</span><span class="token3">{</span> <span class="token5">function</span> <span class="token4">getColor</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span> <span class="token">//具体实现化角色:黄色</span> class <span class="token4">Yellow</span> implements <span class="token4">Color</span><span class="token3">{</span> public <span class="token5">function</span> <span class="token4">getColor</span><span class="token3">(</span><span class="token3">)</span><span class="token3">{</span> <span class="token5">return</span> <span class="token2">"yellow"</span><span class="token3">;</span> <span class="token3">}</span> <span class="token3">}</span> <span class="token">//具体实现化角色:红色</span> class <span class="token4">Red</span> implements <span class="token4">Color</span><span class="token3">{</span> public <span class="token5">function</span> <span class="token4">getColor</span><span class="token3">(</span><span class="token3">)</span><span class="token3">{</span> <span class="token5">return</span> <span class="token2">"red"</span><span class="token3">;</span> <span class="token3">}</span> <span class="token3">}</span> <span class="token">//抽象化角色:包</span> abstract class <span class="token4">Bag</span><span class="token3">{</span> protected $color<span class="token3">;</span> public <span class="token5">function</span> <span class="token4">setColor</span><span class="token3">(</span>$color<span class="token3">)</span><span class="token3">{</span> $this<span class="token1">-</span><span class="token1">></span>color<span class="token1">=</span>$color<span class="token3">;</span> <span class="token3">}</span> abstract public <span class="token5">function</span> <span class="token4">getName</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span> <span class="token">//扩展抽象化角色:挎包</span> class <span class="token4">HandBag</span> extends <span class="token4">Bag</span><span class="token3">{</span> public <span class="token5">function</span> <span class="token4">getName</span><span class="token3">(</span><span class="token3">)</span><span class="token3">{</span> <span class="token5">return</span> $this<span class="token1">-</span><span class="token1">></span>color<span class="token1">-</span><span class="token1">></span><span class="token4">getColor</span><span class="token3">(</span><span class="token3">)</span><span class="token3">.</span><span class="token2">"的HandBag(挎包)"</span><span class="token3">;</span> <span class="token3">}</span> <span class="token3">}</span> <span class="token">//扩展抽象化角色:钱包</span> class <span class="token4">Wallet</span> extends <span class="token4">Bag</span><span class="token3">{</span> public <span class="token5">function</span> <span class="token4">getName</span><span class="token3">(</span><span class="token3">)</span><span class="token3">{</span> <span class="token5">return</span> $this<span class="token1">-</span><span class="token1">></span>color<span class="token1">-</span><span class="token1">></span><span class="token4">getColor</span><span class="token3">(</span><span class="token3">)</span><span class="token3">.</span><span class="token2">"的Wallet(钱包)"</span><span class="token3">;</span> <span class="token3">}</span> <span class="token3">}</span> class <span class="token4">BagManage</span><span class="token3">{</span> public static <span class="token5">function</span> <span class="token4">main</span><span class="token3">(</span><span class="token3">)</span><span class="token3">{</span> $color<span class="token1">=</span><span class="token5">new</span> <span class="token4">Yellow</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span> $bag<span class="token1">=</span><span class="token5">new</span> <span class="token4">HandBag</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span> $bag<span class="token1">-</span><span class="token1">></span><span class="token4">setColor</span><span class="token3">(</span>$color<span class="token3">)</span><span class="token3">;</span> echo $bag<span class="token1">-</span><span class="token1">></span><span class="token4">getName</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span> $color<span class="token1">=</span><span class="token5">new</span> <span class="token4">Red</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span> $bag<span class="token1">=</span><span class="token5">new</span> <span class="token4">Wallet</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span> $bag<span class="token1">-</span><span class="token1">></span><span class="token4">setColor</span><span class="token3">(</span>$color<span class="token3">)</span><span class="token3">;</span> echo $bag<span class="token1">-</span><span class="token1">></span><span class="token4">getName</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span> <span class="token3">}</span> BagManage<span class="token3">:</span><span class="token3">:</span><span class="token4">main</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span> ``` ``` 使用场景: 当一个类存在两个独立变化的维度,且这两个维度都需要进行扩展时。 当一个系统不希望使用继承或因为多层次继承导致系统类的个数急剧增加时。 当一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性时。 ## 桥接模式模式的扩展 在软件开发中,有时桥接(Bridge)模式可与[适配器模式](http://c.biancheng.net/view/1361.html)联合使用。当桥接(Bridge)模式的实现化角色的接口与现有类的接口不一致时,可以在二者中间定义一个适配器将二者连接起来,其具体结构图如图 5 所示。 ![](https://img.kancloud.cn/a6/67/a66767a81c6c38956fe57fea4c49d44b_598x494.png)