目的

将抽象与实现分离,这样两者可以独立地改变

UML 图

代码

1
2
3
4
5
6
7
FormatterInterface.php
<?php
namespace DesignPatterns\Structural\Bridge;
interface FormatterInterface
{
public function format(string $text);
}

1
2
3
4
5
6
7
8
9
10
PlainTextFormatter.php
namespace DesignPatterns\Structural\Bridge;
//创建 PlainTextFormatter 文本格式类实现 FormatterInterface 接口
class PlainTextFormatter implements FormatterInterface
{
public function format(string $text)
{
return $text;
}
}

1
2
3
4
5
6
7
8
9
10
HtmlFormatter.php
<?php
namespace DesignPatterns\Structural\Bridge;
class HtmlFormatter implements FormatterInterface
{
public function format (string $text)
{
return sprintf('<p>%s</p>',$text);
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
namespac DesignPatterns\Structural\Brideg;
abstract class Service
{
protected $implementation;
public function __construct(FormatterInterface $printer)
{
$this->implementation = $printer;
}

public function setImplementation(FormatterInterface $printer)
{
$this->implementation $printer;
}

abstract public function get();
}

1
2
3
4
5
6
7
8
9
10
HelloWorldService.php
<?php
namespace DesignPatterns\Structural\Bridge;
class HelloWorldService extends Service
{
public function get()
{
return $this->implementation->format('Hello World');
}
}

测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
Tests/BridgeTest.php
<?php

namespace DesignPatterns\Structural\Bridge\Tests;

use DesignPatterns\Structural\Bridge\HelloWorldService;
use DesignPatterns\Structural\Bridge\HtmlFormatter;
use DesignPatterns\Structural\Bridge\PlainTextFormatter;
use PHPUnit\Framework\TestCase;

/**
* 创建自动化测试单元 BridgeTest 。
*/
class BridgeTest extends TestCase
{

/**
* 使用 HelloWorldService 分别测试文本格式实现类和 HTML 格式实
* 现类。
*/
public function testCanPrintUsingThePlainTextPrinter()
{
$service = new HelloWorldService(new PlainTextFormatter());
$this->assertEquals('Hello World', $service->get());

// 现在更改实现方法为使用 HTML 格式器。
$service->setImplementation(new HtmlFormatter());
$this->assertEquals('<p>Hello World</p>', $service->get());
}
}