通俗易懂的谈谈装饰器模式

从一个情景开始

``````abstract class Land
{
abstract public function cost();
}
``````

Land 已经定义好了在这块地上盖房需要花钱的这个规则了，但是盖一间房间具体花多少钱呢？

``````class Room extends Land
{
private \$money = 1000;
public function cost()
{
return \$this->money;
}
}
``````

``````class LivingRoom extends Room
{
public function cost()
{
return parent::cost()+200; //客厅的建造费用在房屋建造费用的基础上多200，比如要买沙发，电视
}

}

class DiningRoom extends Room
{
public function cost()
{
return parent::cost()+100; //餐厅的建造费用在房屋建造费用的基础上多100，比如买餐桌
}
}
``````

``````\$livingRoomCost = new LivingRoom();
echo \$livingRoomCost->cost();
``````

解决问题

``````abstract class RoomDecorator extends Land
{
protected \$land;
public function __construct(Land \$land)
{
\$this->land = \$land;
}
}
``````

``````class LivingRoom extends RoomDecorator
{
public function cost()
{
return \$this->land->cost()+200;
}
}

class DiningRoom extends RoomDecorator
{
public function cost()
{
return \$this->land->cost()+100;
}
}
``````

``````\$livingRoomCost = new LivingRoom(new Room());
echo \$livingRoomCost->cost(); //输出1200
``````

``````\$diningRoomCost = new DiningRoom(new Room());
echo \$diningRoomCost->cost(); //输出1100
``````

``````\$livingRoom = new DiningRoom(new LivingRoom(new Room()));
echo \$livingRoom->cost(); //输出1300
``````

完整代码

``````<?php

abstract class Land
{
abstract function cost();
}

class Room extends Land
{
private \$money = 1000;
public function cost()
{
return \$this->money;
}
}

//装饰器
abstract class RoomDecorator extends Land
{
protected \$land;
public function __construct(Land \$land)
{
\$this->land = \$land;
}
}

class LivingRoom extends RoomDecorator
{
public function cost()
{
return \$this->land->cost()+200;
}
}

class DiningRoom extends RoomDecorator
{
public function cost()
{
return \$this->land->cost()+100;
}
}

\$livingRoomCost = new LivingRoom(new Room());
echo \$livingRoomCost->cost(); //输出1200

\$diningRoomCost = new DiningRoom(new Room());
echo \$diningRoomCost->cost(); //输出1100

\$livingDining = new DiningRoom(new LivingRoom(new Room()));
echo \$livingDining->cost(); //输出1300
``````

the end.

happy coding! ^_^

You can not connect the dots looking forward, you can only connect them looking backwards.

《L01 基础入门》

《L03 构架 API 服务器》

1年前 评论

1年前 评论

1年前 评论

1年前 评论

1年前 评论

@keer 楼上的回答有说了，在框架的源码中会用到这种设计模式，可以看看~

1年前 评论

9个月前 评论

12

80

489

311