php设计模式(十一)桥接模式

桥接模式有一个常见的示例;
有正方形、三角形、圆形等形状;
还有红、黄、绿颜色;
要实现形状和颜色的组合;
how to do it?
我这里画了张有点丑但很直观的图;

最简单的方式就是通过继承;
建12个类就行了;
但是如果按照此图的形式来组织代码;
当需要增加形状或者颜色的时候;
比如说增加一个梯形;
这时候就需要再增加3个颜色的梯形类;
再如果增加一个蓝色;
那每个形状都要再增加一个类;
想想都蛮心累的;

这时候就需要转变下方式了;
我这里又画了张有点丑但很直观的图;

把形状和颜色类单独创建;
然后通过组合的方式来实现各种形状和颜色搭配的图案;

桥接模式就是把抽象部份与实现部分分离;
使它们都可以有独立的变化组合;

结构

Abstraction:抽象类 在本示例中指 形状;
RefinedAbstraction:扩充抽象类 在本示例中指 正方形、三角形、圆形;
Implementor:实现类 在本示例中指 颜色;
ConcreteImplementor:具体实现类 在本示例中指红、黄、绿;

示例

Color.php 颜色抽象类

<?php

namespace Baijunyao\DesignPatterns\Bridge;

/**
 * 颜色抽象类
 *
 * Class Color
 * @package Baijunyao\DesignPatterns\Bridge
 */
abstract class Color
{
    /**
     * @return mixed
     */
    abstract public function run();
}

具体的颜色类;
Red.php 红色

<?php

namespace Baijunyao\DesignPatterns\Bridge;

/**
 * 红色
 *
 * Class Red
 * @package Baijunyao\DesignPatterns\Bridge
 */
class Red extends Color
{
    /**
     * @return mixed|string
     */
    public function run()
    {
        return '红色';
    }
}

Yellow.php 黄色

<?php

namespace Baijunyao\DesignPatterns\Bridge;

/**
 * 黄色
 *
 * Class Yellow
 * @package Baijunyao\DesignPatterns\Bridge
 */
class Yellow extends Color
{
    /**
     * @return mixed|string
     */
    public function run()
    {
        return '黄色';
    }
}

Green.php 绿色

<?php

namespace Baijunyao\DesignPatterns\Bridge;

/**
 * 绿色
 *
 * Class Green
 * @package Baijunyao\DesignPatterns\Bridge
 */
class Green extends Color
{
    /**
     * @return mixed|string
     */
    public function run()
    {
        return '绿色';
    }
}

Graph.php 形状抽象类

<?php

namespace Baijunyao\DesignPatterns\Bridge;

/**
 * 形状抽象类
 *
 * Class Graph
 * @package Baijunyao\DesignPatterns\Bridge
 */
abstract class Graph
{
    /**
     * 颜色
     *
     * @var Color
     */
    protected $color;

    /**
     * Graph constructor.
     * @param Color $color
     */
    public function __construct(Color $color)
    {
        $this->color = $color;
    }

    /**
     * @return mixed
     */
    abstract public function draw();
}

Square.php 正方形

<?php

namespace Baijunyao\DesignPatterns\Bridge;

/**
 * 正方形
 *
 * Class Square
 * @package Baijunyao\DesignPatterns\Bridge
 */
class Square extends Graph
{
    /**
     * @return mixed|void
     */
    public function draw()
    {
        echo "画一个 {$this->color->run()} 的正方形";
    }
}

Triangle.php 三角形

<?php

namespace Baijunyao\DesignPatterns\Bridge;

/**
 * 三角形
 *
 * Class Triangle
 * @package Baijunyao\DesignPatterns\Bridge
 */
class Triangle extends Graph
{
    /**
     * @return mixed|void
     */
    public function draw()
    {
        echo "画一个 {$this->color->run()} 的三角形";
    }
}

Circle.php 圆形

<?php

namespace Baijunyao\DesignPatterns\Bridge;

/**
 * 圆形
 * 
 * Class Circle
 * @package Baijunyao\DesignPatterns\Bridge
 */
class Circle extends Graph
{
    /**
     * @return mixed|void
     */
    public function draw()
    {
        echo "画一个 {$this->color->run()} 的圆形";
    }
}

运行;
index.php

<?php

namespace Baijunyao\DesignPatterns\Bridge;

require __DIR__.'/../vendor/autoload.php';

/**
 * 客户端
 *
 * Class Client
 * @package Baijunyao\DesignPatterns\Bridge
 */
class Client
{
    /**
     * 运行
     */
    public function run()
    {
        $red = new Red();
        $yellow = new Yellow();
        $green = new Green();

        // 红色的正方形
        $redSquare = new Square($red);
        $redSquare->draw();
        echo '<hr>';

        // 黄色的正方形
        $yellowSquare = new Square($yellow);
        $yellowSquare->draw();
        echo '<hr>';

        // 绿色的正方形
        $greenSquare = new Square($green);
        $greenSquare->draw();
        echo '<hr>';


        // 红色的三角形
        $redTriangle = new Triangle($red);
        $redTriangle->draw();
        echo '<hr>';

        // 黄色的三角形
        $yellowTriangle = new Triangle($yellow);
        $yellowTriangle->draw();
        echo '<hr>';

        // 绿色的三角形
        $greenTriangle = new Triangle($green);
        $greenTriangle->draw();
        echo '<hr>';


        // 红色的圆形
        $redCircle = new Circle($red);
        $redCircle->draw();
        echo '<hr>';

        // 黄色的圆形
        $yellowCircle = new Circle($yellow);
        $yellowCircle->draw();
        echo '<hr>';

        // 绿色的圆形
        $greenCircle = new Circle($green);
        $greenCircle->draw();
        echo '<hr>';

    }
}

$client = new Client();
$client->run();

从代码我们可以发现跟上篇文章的适配器模式有点像;
它们都是让两个类配合工作;
但是适配器是为了让已有的两个类互相兼容;
而桥接模式则是为了让抽象和实现解耦;
在减少创建类的同时还可以方便组合功能;

github示例:https://github.com/baijunyao/design-patterns/tree/master/Bridge

白俊遥博客
请先登录后发表评论
  • 最新评论
  • 总共0条评论