桥接模式

目的

将抽象与实现解耦,使两者可以独立变化。

UML 类图

桥接模式类图

代码

Formatter.php

1
2
3
4
5
6
7
8
<?php declare(strict_types = 1);

namespace DesignPatterns\Structural\Bridge;

interface Formatter
{
public function format(string $text): string;
}

PlainTextFormatter.php

1
2
3
4
5
6
7
8
9
10
11
<?php declare(strict_types = 1);

namespace DesignPatterns\Structural\Bridge;

class PlainTextFormatter implements Formatter
{
public function format(string $text): string
{
return $text;
}
}

HtmlFormatter.php

1
2
3
4
5
6
7
8
9
10
11
<?php declare(strict_types = 1);

namespace DesignPatterns\Structural\Bridge;

class HtmlFormatter implements Formatter
{
public function format(string $text): string
{
return sprintf('<p>%s</p>', $text);
}
}

Service.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php declare(strict_types = 1);

namespace DesignPatterns\Structural\Bridge;

abstract class Service
{
protected Formatter $implementation;

public function __construct(Formatter $printer)
{
$this->implementation = $printer;
}

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

abstract public function get(): string;
}

HelloWorldService.php

1
2
3
4
5
6
7
8
9
10
11
<?php declare(strict_types = 1);

namespace DesignPatterns\Structural\Bridge;

class HelloWorldService extends Service
{
public function get(): string
{
return $this->implementation->format('Hello World');
}
}

PingService.php

1
2
3
4
5
6
7
8
9
10
11
<?php declare(strict_types = 1);

namespace DesignPatterns\Structural\Bridge;

class PingService extends Service
{
public function get(): string
{
return $this->implementation->format('pong');
}
}

测试

Tests/BridgeTest.php

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
<?php declare(strict_types = 1);

namespace DesignPatterns\Structural\Bridge\Tests;

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

class BridgeTest extends TestCase
{
public function testCanPrintUsingThePlainTextFormatter()
{
$service = new HelloWorldService(new PlainTextFormatter());

$this->assertSame('Hello World', $service->get());
}

public function testCanPrintUsingTheHtmlFormatter()
{
$service = new HelloWorldService(new HtmlFormatter());

$this->assertSame('<p>Hello World</p>', $service->get());
}
}