一天一个设计模式(7)——桥接模式

桥接模式

桥接模式将抽象化(Abstraction)与实现化(Implementation)脱耦,使得二者可以独立地变化。

应用场景

桥接模式的定义比较难以理解。这里的抽象化和实现化与面向对象的抽象类和实例是不一样的,是指的对现实需求的抽象。

我们还是用例子来解释。

桥接模式最基本的应用是不同平台或者引擎的图形渲染。我们知道PHP有GD和Gmagick两种绘制图像的库。如果我们要画一个圆形和一个方形,分别使用两个库进行绘制。按照一般的方法要创建4个类,即采用GD绘制圆形,采用Gmagick绘制圆形,采用GD绘制方形,采用Gmagick绘制方形。

当我们要增加一个图形或者一个引擎时,类的数量会成几何增长,对维护带来极大的困难。

桥接模式就是为了解决这种问题而产生的。在上例中有“两个非常强的变化维度”,即引擎和图形。

类图

实例

  图形绘制接口:

interface DrawAPI
{
    public function drawCircle($radius);
    public function drawSquare($width, $height);
}

  实现接口的引擎:

class GD implements DrawAPI
{
    public function drawCircle($radius)
    {
        echo 'Draw a circle using gd.Radius:' . $radius . "\n";
    }

    public function drawSquare($width, $height)
    {
        echo 'Draw a square using gd.Width:' . $width . '.Height:' . $height . "\n";
    }
}

class Gmagick implements DrawAPI
{
    public function drawCircle($radius)
    {
        echo 'Draw a circle using gmagick.Radius:' . $radius . "\n";
    }

    public function drawSquare($width, $height)
    {
        echo 'Draw a square using gmagick.Width:' . $width . '.Height:' . $height . "\n";
    }
}
View Code

  图形抽象类:

abstract class Shape
{
    /**
     * @var DrawAPI
     */
    public $drawAPI;

    function __construct($drawAPI)
    {
        $this->drawAPI = $drawAPI;
    }

    abstract public function draw();
}

  图形类:

class Circle extends Shape
{
    public $radius;

    function __construct($drawAPI, $radius)
    {
        parent::__construct($drawAPI);
        $this->radius = $radius;
    }

    public function draw()
    {
        $this->drawAPI->drawCircle($this->radius);
    }
}

class Square extends Shape
{
    public $width;
    public $height;

    function __construct($drawAPI, $width, $height)
    {
        parent::__construct($drawAPI);
        $this->width = $width;
        $this->height = $height;
    }

    public function draw()
    {
        $this->drawAPI->drawSquare($this->width, $this->height);
    }
}
View Code

  执行代码:

$shape1 = new Circle(new GD(), 10);
$shape1->draw();

$shape2 = new Square(new Gmagick(), 100, 80);
$shape2->draw();

 

posted @ 2017-05-03 17:15  Bin_x  阅读(177)  评论(0编辑  收藏  举报