桥接模式,就是实现系统可能有多角度分类,每一种分类都有可能变化,可能增加或减少。那么,就把这种多角度分离出来让他们独自变化,减少它们之间的耦合。
比如,现在的智能手机,安卓的ipk文件就不能安装在苹果的ios系统上。分类一(按照手机操作系统来分):手机系统分为安卓和IOS,安卓的软件分为游戏、音乐等,IOS的软件也分为游戏、音乐等。分类二(按照软件来分):软件分为游戏和音乐,游戏分为安卓游戏和IOS游戏,音乐也分为安卓音乐和IOS音乐。
思考:增加一个手机系统,如Windos 8。那么,分类就变了。如下:分类一(按照手机操作系统来分):手机系统分为安卓和IOS和Windows 8,安卓的软件分为游戏、音乐等,IOS的软件也分为游戏、音乐等,Windows 8的软件也分为游戏和音乐等。分类二(按照软件来分):软件分为游戏和音乐,游戏分为安卓游戏和IOS游戏和Windows 8游戏,音乐也分为安卓音乐和IOS音乐和Windows 8音乐。
这种分类的弊病非常明显,如果要增加一个手机的操作系统,相应的需要改变原有分类,增加大量的class文件。操作系统和手机软件的分类是高强度耦合。
在面向对象的变成里,耦合度越高的越不利于复用,设计模式的重点就是降低耦合,减少复制-粘贴的编码模式。在这个例子中,引出了一种设计模式,叫做桥接模式。
桥接模式:将抽象的部分与它的实现分离,使他们可以独立变化。
所谓的实现,就是抽象类和派生类用来实现自己的对象。白话文就是:就是实现系统可能有多角度分类,每一种分类都有可能变化,可能增加或减少。那么,就把这种多角度分离出来让他们独自变化,减少它们之间的耦合。
桥接模式的分类:手机操作系统分为安卓和IOS,手机软件分为游戏和音乐。操作系统和软件相互独立,没有强的明显关系,操作系统和手机软件不进行分类关联,它们俩的真实关系请继续往后看。
那么,耦合度降低了,增加windows8只需要在操作系统分类下增加一个windows8,软件则不需要变化。
再引入一个原则,合成-聚合复用原则:尽量使用合成-聚合,尽量不要使用类的继承。
聚合是弱拥有关系,A可以包含B,但是B不是A的一部分。合成是强拥有关系,严格的部分和整体,两者拥有相同的生命周期。
大雁的翅膀和大雁本身是合成关系,生命周期一样,是强拥有关系。大雁和雁群是聚合关系,大雁只属于一个雁群,但是雁群不仅仅只有这一个大雁。(本例摘自《大话设计模式》)
回到上一个话题,在桥接模式的分类下,手机操作系统和手机软件之间的关系,就是聚合关系,弱的关系,才可以降低耦合。
以PHP为代码环境,说明手机的例子。

<?php
abstract class Soft{
    public function run(){}
}
class Game extends Soft{
    public function run(){
        echo '手机游戏正在运行...<br>';
    }
}
class Mp3 extends Soft{
    public function run(){
        echo '手机音乐播放器正在运行...<br>';
    }
}
abstract class OS{
    protected $softObj;
    public function setSoftObj($softObj){
        $this->softObj = $softObj;
    }
    public function run(){}
}
class Ios extends OS{
    public function run(){
        $this->softObj->run();
    }
}
class Android extends OS{
    public function run(){
        $this->softObj->run();
    }
}
//客户端/接口
echo '购买了Iphone一台,搭载IOS操作系统<br>';
$iphone = new Ios();
$iphone->setSoftObj(new Game());
$iphone->run();
$iphone->setSoftObj(new Mp3());
$iphone->run();

echo '购买了三星一台,搭载安卓操作系统<br>';
$samsung = new Ios();
$samsung->setSoftObj(new Game());
$samsung->run();
$samsung->setSoftObj(new Mp3());
$samsung->run();

标签: PHP, 设计模式, 桥接模式

添加新评论