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

白俊遥博客
请先登录后发表评论
  • latest comments
  • 总共1条评论
白俊遥博客

NULL :get白俊遥博客白俊遥博客白俊遥博客白俊遥博客白俊遥博客白俊遥博客白俊遥博客

2019-03-18 16:47:28 回复