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

## 从一个情景开始

``````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 基础入门》

《L05 电商实战》

2年前 评论

2年前 评论

2年前 评论

2年前 评论

2年前 评论

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

2年前 评论

1年前 评论

1周前 评论

11

97

500

364