行为型设计模式的PHP实现

14、责任链模式(Chain of Responsibility Pattern)

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
<?php
abstract class AbstractLogger {
    public const INFO = 1;
    public const DEBUG = 2;
    public const ERROR = 3;
    protected $level;
    protected $nextLogger;
 
    public function setNextLogger(AbstractLogger $nextLogger) {
        $this->nextLogger = $nextLogger;
    }
 
    public function logMessage(int $level, String $message) {
        if ($this->level <= $level) {
            $this->write($message);
        }
        if ($this->nextLogger) {
            $this->nextLogger->logMessage($level, $message);
        }
    }
 
    protected abstract function write(String $message);
}
 
class ConsoleLogger extends AbstractLogger {
    public function __construct(int $level) {
        $this->level = $level;
    }
 
    protected function write(String $message) {
        echo 'Standard Console::Logger: ' . $message . "\n";
    }
}
 
class ErrorLogger extends AbstractLogger {
    public function __construct(int $level) {
        $this->level = $level;
    }
 
    protected function write(String $message) {
        echo 'Error Console::Logger: ' . $message . "\n";
    }
}
 
class FileLogger extends AbstractLogger {
    public function __construct(int $level) {
        $this->level = $level;
    }
 
    protected function write(String $message) {
        echo 'File::Logger: ' . $message . "\n";
    }
}
 
function getChainOfLoggers(): AbstractLogger {
    $errorLogger = new ErrorLogger(AbstractLogger::ERROR);
    $fileLogger = new FileLogger(AbstractLogger::DEBUG);
    $consoleLogger = new ConsoleLogger(AbstractLogger::INFO);
 
    $errorLogger->setNextLogger($fileLogger);
    $fileLogger->setNextLogger($consoleLogger);
 
    return $errorLogger;
}
 
$loggerChain = getChainOfLoggers();
$loggerChain->logMessage(AbstractLogger::INFO, 'This is an information.');
$loggerChain->logMessage(AbstractLogger::DEBUG, 'This is an debug level information.');
$loggerChain->logMessage(AbstractLogger::ERROR, 'This is an error information.');

15、命令模式(Command Pattern)

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
<?php
 
interface Order {
    public function execute();
}
 
class Stock {
    private $name = 'ABC';
    private $quantity = 10;
 
    public function buy() {
        echo 'Stock [ Name: ' . $this->name . ', Quantity: '
            . $this->quantity . " ] bought\n";
    }
 
    public function sell() {
        echo 'Stock [ Name: ' . $this->name . ', Quantity: '
            . $this->quantity . " ] sold\n";
    }
}
 
class BuyStock implements Order {
    private $abcStock;
 
    public function __construct(Stock $abcStock) {
        $this->abcStock = $abcStock;
    }
 
    public function execute() {
        $this->abcStock->buy();
    }
}
 
class SellStock implements Order {
    private $abcStock;
 
    public function __construct(Stock $abcStock) {
        $this->abcStock = $abcStock;
    }
 
    public function execute() {
        $this->abcStock->sell();
    }
}
 
class Broker {
    private $orderList = [];
 
    public function takeOrder(Order $order) {
        $this->orderList[] = $order;
    }
 
    public function placeOrders() {
        foreach ($this->orderList as $order) {
            $order instanceof Order && $order->execute();
        }
        $this->orderList = [];
    }
}
 
$abcStock = new Stock();
$buyStockOrder = new BuyStock($abcStock);
$sellStockOrder = new SellStock($abcStock);
 
$broker = new Broker();
$broker->takeOrder($buyStockOrder);
$broker->takeOrder($sellStockOrder);
$broker->placeOrders();

16、解释器模式(Interpreter Pattern)

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
<?php
 
interface Expression {
    public function interpret(String $context);
}
 
class TerminalExpression implements Expression {
    private $data;
 
    public function __construct(String $data) {
        $this->data = $data;
    }
 
    public function interpret(String $context) {
        return strpos($context, $this->data) !== false;
    }
}
 
class OrExpression implements Expression {
    private $expr1 = null;
    private $expr2 = null;
 
    public function __construct(Expression $expr1, Expression $expr2) {
        $this->expr1 = $expr1;
        $this->expr2 = $expr2;
    }
 
    public function interpret(String $context) {
        return $this->expr1->interpret($context) || $this->expr2->interpret($context);
    }
}
 
class AndExpression implements Expression {
    private $expr1 = null;
    private $expr2 = null;
 
    public function __construct(Expression $expr1, Expression $expr2) {
        $this->expr1 = $expr1;
        $this->expr2 = $expr2;
    }
 
    public function interpret(String $context) {
        return $this->expr1->interpret($context) && $this->expr2->interpret($context);
    }
}
 
// 规则:Robert 和 John 是男性
function getMaleExpression() {
    $robert = new TerminalExpression('Robert');
    $john = new TerminalExpression('John');
    return new OrExpression($robert, $john);
}
 
// 规则:Julie 是一个已婚的女性
function getMarriedWomanExpression() {
    $julie = new TerminalExpression('Julie');
    $married = new TerminalExpression('Married');
    return new AndExpression($julie, $married);
}
 
$isMale = getMaleExpression();
$isMarriedWoman = getMarriedWomanExpression();
 
echo "John is male? " . $isMale->interpret('John');
echo "\nJulie is a married women? "
    . $isMarriedWoman->interpret('Married Julie');

17、迭代器模式(Iterator Pattern)

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
<?php
 
interface MyIterator {
    public function hasNext(): bool;
    public function next();
}
 
class NameIterator implements MyIterator {
    private $index = 0;
    private $names = ['Robert', 'John', 'Julie', 'Lora'];
 
    public function hasNext(): bool {
        return $this->index < count($this->names);
    }
 
    public function next() {
        if($this->hasNext()){
            return $this->names[$this->index++];
        }
        return null;
    }
}
 
$it = new NameIterator;
while ($it->hasNext()) {
    echo $it->next() . "\n";
}

18、中介者模式(Mediator Pattern)

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
<?php
 
class User {
    private $name;
 
    public function __construct($name) {
        $this->name = $name;
    }
 
    public function getName() {
        return $this->name;
    }
 
    public function sendMessage(String $message) {
        ChatRoom::showMessage($this, $message);
    }
}
 
class ChatRoom {
    public static function showMessage(User $user, String $message) {
        echo date('Y-m-d H:i:s') . " [" . $user->getName() . "] : " . $message . "\n";
    }
}
 
$robert = new User('Robert');
$john = new User('John');
 
$robert->sendMessage('Hi! John!');
$john->sendMessage('Hello! Robert!');

19、备忘录模式(Memento Pattern)

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
<?php
 
class Memento {
    private $state;
 
    public function __construct(String $state) {
        $this->state = $state;
    }
 
    public function getState(): String {
        return $this->state;
    }
}
 
class Originator {
    private $state;
 
    public function getState() {
        return $this->state;
    }
 
    public function setState($state) {
        $this->state = $state;
    }
 
    public function saveStateToMemento() {
        return new Memento($this->state);
    }
 
    public function getStateFromMemento(Memento $memento) {
        $this->state = $memento->getState();
    }
}
 
class CareTaker {
    private $mementoList = [];
 
    public function add(Memento $memento) {
        $this->mementoList[] = $memento;
    }
 
    public function get(int $index) {
        if (isset($this->mementoList[$index])) {
            return $this->mementoList[$index];
        }
        return null;
    }
}
 
$originator = new Originator();
$careTaker = new CareTaker();
$originator->setState("State #1");
$originator->setState("State #2");
$careTaker->add($originator->saveStateToMemento());
$originator->setState("State #3");
$careTaker->add($originator->saveStateToMemento());
$originator->setState("State #4");
 
echo "Current State: " . $originator->getState() . "\n";
$originator->getStateFromMemento($careTaker->get(0));
echo "First saved State: " . $originator->getState() . "\n";
$originator->getStateFromMemento($careTaker->get(1));
echo "Second saved State: " . $originator->getState() . "\n";

20、观察者模式(Observer Pattern)

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
<?php
 
class Subject {
    private $observers = [];
    private $state;
 
    public function getState() {
        return $this->state;
    }
 
    public function setState($state) {
        $this->state = $state;
        $this->notifyAllObservers();
    }
 
    public function attach(Observer $observer) {
        $this->observers[] = $observer;
    }
 
    public function notifyAllObservers() {
        foreach ($this->observers as $observer) {
            $observer instanceof Observer && $observer->update();
        }
    }
}
 
abstract class Observer {
    protected $subject;
    public abstract function update();
}
 
class BinaryObserver extends Observer {
    public function __construct(Subject $subject) {
        $this->subject = $subject;
        $this->subject->attach($this);
    }
 
    public function update() {
        echo "Binary String: " . decbin($this->subject->getState()) . "\n";
    }
}
 
class OctalObserver extends Observer {
    public function __construct(Subject $subject) {
        $this->subject = $subject;
        $this->subject->attach($this);
    }
 
    public function update() {
        echo "Octal String: " . decoct($this->subject->getState()) . "\n";
    }
}
 
class HexaObserver extends Observer {
    public function __construct(Subject $subject) {
        $this->subject = $subject;
        $this->subject->attach($this);
    }
 
    public function update() {
        echo "Hex String: " . strtoupper(dechex($this->subject->getState())) . "\n";
    }
}
 
$subject = new Subject();
new HexaObserver($subject);
new OctalObserver($subject);
new BinaryObserver($subject);
echo "First state change: 15\n";
$subject->setState(15);
echo "Second state change: 10\n";
$subject->setState(10);

21、状态模式(State Pattern)

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
<?php
 
interface State {
    public function doAction(Context $context);
}
 
class StartState implements State {
    public function doAction(Context $context) {
        echo "Player is in start state\n";
        $context->setState($this);
    }
 
    public function toString() {
        return "Start State";
    }
}
 
class StopState implements State {
    public function doAction(Context $context) {
        echo "Player is in stop state\n";
        $context->setState($this);
    }
 
    public function toString() {
        return "Stop State";
    }
}
 
class Context {
    private $state;
 
    public function __construct() {
        $this->state = null;
    }
 
    public function setState(State $state) {
        $this->state = $state;
    }
 
    public function getState() {
        return $this->state;
    }
}
 
$context = new Context();
 
$startState = new StartState();
$startState->doAction($context);
 
echo $context->getState()->toString() . "\n";
 
$stopState = new StopState();
$stopState->doAction($context);
 
echo $context->getState()->toString() . "\n";

22、空对象模式(Null Object Pattern)

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
<?php
 
abstract class AbstractCustomer {
    protected $name;
 
    public abstract function isNil();
 
    public abstract function getName();
}
 
class RealCustomer extends AbstractCustomer {
    public function __construct(String $name) {
        $this->name = $name;
    }
 
    public function getName() {
        return $this->name;
    }
 
    public function isNil() {
        return false;
    }
}
 
class NullCustomer extends AbstractCustomer {
    public function getName() {
        return "Not Available in Customer Database\n";
    }
 
    public function isNil() {
        return true;
    }
}
 
class CustomerFactory {
    public static $names = ["Rob", "Joe", "Julie"];
 
    public static function getCustomer(String $name): AbstractCustomer {
        foreach (self::$names as $thisName) {
            if (strtoupper($thisName) === $name) {
                return new RealCustomer($name);
            }
        }
        return new NullCustomer();
    }
}
 
$customer1 = CustomerFactory::getCustomer("Rob");
$customer2 = CustomerFactory::getCustomer("Bob");
$customer3 = CustomerFactory::getCustomer("Julie");
$customer4 = CustomerFactory::getCustomer("Laura");
 
echo $customer1->getName() . "\n";
echo $customer2->getName() . "\n";
echo $customer3->getName() . "\n";
echo $customer4->getName() . "\n";

23、策略模式(Strategy Pattern)

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<?php
 
interface Strategy {
    public function doOperation(int $num1, int $num2);
}
 
class OperationAdd implements Strategy {
    public function doOperation(int $num1, int $num2) {
        return $num1 + $num2;
    }
}
 
class OperationSubtract implements Strategy {
    public function doOperation(int $num1, int $num2) {
        return $num1 - $num2;
    }
}
 
class OperationMultiply implements Strategy {
    public function doOperation(int $num1, int $num2) {
        return $num1 * $num2;
    }
}
 
class Context {
    private $strategy;
 
    public function __construct(Strategy $strategy) {
        $this->strategy = $strategy;
    }
 
    public function executeStrategy(int $num1, int $num2) {
        return $this->strategy->doOperation($num1, $num2);
    }
}
 
$context = new Context(new OperationAdd());
echo "10 + 5 = " . $context->executeStrategy(10, 5) . "\n";
 
$context = new Context(new OperationSubtract());
echo "10 - 5 = " . $context->executeStrategy(10, 5) . "\n";
 
$context = new Context(new OperationMultiply());
echo "10 * 5 = " . $context->executeStrategy(10, 5) . "\n";

24、模板模式(Template Pattern)

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
<?php
 
abstract class Game {
    abstract function initialize();
 
    abstract function startPlay();
 
    abstract function endPlay();
 
    // 模板
    public final function play() {
        // 初始化游戏
        $this->initialize();
 
        // 开始游戏
        $this->startPlay();
 
        // 结束游戏
        $this->endPlay();
    }
}
 
class Cricket extends Game {
    public function endPlay() {
        echo "Cricket Game Finished!\n";
    }
 
    public function initialize() {
        echo "Cricket Game Initialized! Start playing.\n";
    }
 
    public function startPlay() {
        echo "Cricket Game Started. Enjoy the game!\n";
    }
}
 
class Football extends Game {
    public function endPlay() {
        echo "Football Game Finished!\n";
    }
 
    public function initialize() {
        echo "Football Game Initialized! Start playing.\n";
    }
 
    public function startPlay() {
        echo "Football Game Started. Enjoy the game!\n";
    }
}
 
$game = new Cricket();
$game->play();
echo "\n";
$game = new Football();
$game->play();

25、访问者模式(Visitor Pattern)

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
<?php
 
interface ComputerPart {
    public function accept(ComputerPartVisitor $computerPartVisitor);
}
 
class Keyboard implements ComputerPart {
    public function accept(ComputerPartVisitor $computerPartVisitor) {
        $computerPartVisitor->visit($this);
    }
}
 
class Monitor implements ComputerPart {
    public function accept(ComputerPartVisitor $computerPartVisitor) {
        $computerPartVisitor->visit($this);
    }
}
 
class Mouse implements ComputerPart {
    public function accept(ComputerPartVisitor $computerPartVisitor) {
        $computerPartVisitor->visit($this);
    }
}
 
class Computer implements ComputerPart {
    private $parts = [];
 
    public function __construct() {
        $this->parts = [new Mouse(), new Keyboard(), new Monitor()];
    }
 
    public function accept(ComputerPartVisitor $computerPartVisitor) {
        foreach ($this->parts as $part) {
            $part->accept($computerPartVisitor);
        }
        $computerPartVisitor->visit($this);
    }
}
 
interface ComputerPartVisitor {
    public function visit(ComputerPart $part);
}
 
class ComputerPartDisplayVisitor implements ComputerPartVisitor {
    public function visit(ComputerPart $part) {
        $ref = new \ReflectionClass($part);
        echo "Displaying " . $ref->getName() . ".\n";
    }
}
 
$computer = new Computer();
$computer->accept(new ComputerPartDisplayVisitor());

发表评论

电子邮件地址不会被公开。 必填项已用*标注