桥接模式【Bridge】

实例

abstract class Soft
{
    protected $name;
    public function __construct($name)
    {
        $this->name = $name;
    }
    public abstract function run();
}
class GameSoft extends Soft
{
    public function run()
    {
        echo '运行:', $this->name, PHP_EOL;
    }
}
class ChatSoft extends Soft
{
    public function run()
    {
        echo '运行:', $this->name, PHP_EOL;
    }
}
abstract class Handset
{
    protected $name;
    public function __construct($name)
    {
        $this->name = $name;
    }
    public abstract function installSoft(Soft $soft);
    public abstract function run();
}
class HandsetA extends Handset
{
    private $soft;
    public function run()
    {
        echo '手机:', $this->name, PHP_EOL;
        foreach ($this->soft as $soft) {
            $soft->run();
        }
    }
    public function installSoft(Soft $soft)
    {
        $this->soft[] = $soft;
    }
}
class HandsetB extends Handset
{
    private $soft = [];
    public function run()
    {
        echo '手机:', $this->name, PHP_EOL;
        foreach ($this->soft as $soft) {
            $soft->run();
        }
    }
    public function installSoft(Soft $soft)
    {
        $this->soft[] = $soft;
    }
}
$gameSoft = new GameSoft('刺激战场');
$chatSoft = new ChatSoft('微信');

$handsetA = new HandsetA('小米');
$handsetB = new HandsetB('苹果');

$handsetA->installSoft($gameSoft);
$handsetA->installSoft($chatSoft);
$handsetB->installSoft($gameSoft);
$handsetB->installSoft($chatSoft);

$handsetA->run();
$handsetB->run();
/*
手机:小米
运行:刺激战场
运行:微信
手机:苹果
运行:刺激战场
运行:微信
*/

总结

桥接模式通过合成/聚合解耦了事物的抽象(做什么)和实现(怎么做),适用于存在两个独立变化维度的场景,以防止继承导致的类爆炸和僵硬。

意图

将一个事物的抽象部分与其实现部分分离,使二者都能独立地进行变化和扩展。

主要解决

解决多角度分类问题,即存在两个或多个独立变化的维度时,避免使用多层继承导致的类爆炸和不灵活。

何时使用

实现系统可能有多个角度分类,每一种角度都可能变化。

如何解决

把这种多角度分类分离出来,让它们独立变化,减少它们之间耦合。

关键代码

抽象类依赖实现类。

优点

缺点

引入了抽象层和关联关系,增加了系统的理解和设计难度

使用场景

  1. 如果一个系统需要在构建的抽象化角色和具体化角色之间增加更多的灵活性,避免在两个层次之间建立静态的继承联系,通过桥接模式可以使它们在抽象层建立一个关联关系。
  2. 对于那些不希望使用继承或因为多层次继承导致系统类的个数急剧增加的系统,桥接模式尤为适用。
  3. 一个类存在两个独立变化的维度,且这两个维度都需要进行扩展。

注意事项

对于两个独立变化的维度,使用桥接模式再适合不过了。