欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  后端开发

php面向对象进阶设计模式:装饰器模式

程序员文章站 2022-03-19 22:56:28
...
什么是装饰器模式?

如果对已有对象的部分内或功能性发生改变,但是不需要修改原始对象的结构,那么使用装饰器设计模式最适合。

装饰器模式应用问题与解决方案:

我们最开始学习面向对象编程的相关知识时,第一个障碍往往是理解继承当中的父子关系。随着时间的推移,我们会更加熟悉这种编程方法。当面对新的挑战时,经验丰富的面向对象编程人员会立即为某个对象扩展更多的功能。不过,正如万物皆有度,只有适度的使用才能保证这种工作的良好开展。

代码库应当对类层次的数量有限制。如果对象开始要求启用过多的子类,那么相应的代码就会牺牲编程人员的理解力和可维护性。通常,我竭力保证用于一个对象的父子关系不超过3个。我发现:只要创建较多的父子关系,那么代码就会变得混乱和难以控制。除此之外,使用一般的纸张也无法答应出应用程序中任何对象的UML图表示。

不过,我并不希望阻止类扩展的使用。实际上,我们经常使用适当的解决方案来扩展对象。但是,对于某些问题来说,使用基于装饰器设计模式的类是更好的解决方案。

装饰器设计模式适用于编程人员话费大量时间所处的下列工作场合:变化是快速和细小的,而且几乎不影响应用程序的其余部分。使用装饰器设计模式设计类的目标是:不必重写任何已有的功能性,而是对某个基对象应用增量变化。装饰器采用这样的构建方式:在主代码流中应当能够直接插入一个或多个更改或“装饰”目标对象的装饰器,同时不影响其他代码流。

UML

下UML图详细说明了一个使用装饰器设计模式的类设计。

php面向对象进阶设计模式:装饰器模式

下面对上图的说明:

1.MyObject是具有现有功能性的基类。这个类包含名为items的公共数组和名为show ItemsFormatted()的公共方法。

2.show ItemsFormatted()方法负责接受items数组,并且使用预定义的功能性格式化该数组后提交输出。

3.MyObjectDecorator类包含MyObject的一个私有实例和两个公共方法:MyObjectDecorator()和decorateItems()。

4.MyObjectDecorator()方法代表构造函数,它接受一个MyObject类型参数并将其存储在内部。

5.decorateItems()方法可修改MyObject实例的items数组。

我们来看下面这个例子,为了计算一块区域的价值,我们把代码写成下面这个样子:

// 区域抽象类
abstract class Area
{
    abstract public function treasure();
}
//森林类,价值100
class Forest extends Area 
{
    public function treasure()
    {
        return 100;
    }
}
//沙漠类,价值10
class Desert extends Area
{
    function function treasure()
    {
        return 10;
    }
}

上面的代码看上去好像没有什么问题,但是如果需要给一片被破坏的森林计算价值怎么办呢,添加DamageForest子类么?显然是不可行的,因为很有可能还有其他很多类型叠加的类,这会导致类中可能会有重复的代码,且子类也会变的越来越多。

装饰器模式使用组合和委托,而不是使用继承来解决上述的问题,我们在来看下面改良过的代码:

// 区域抽象类
abstract class Area
{    
   abstract public function treasure();
}

//森林类,价值100
class Forest extends Area 
{
   public function treasure()
   {
       return 100;
   }
}
//沙漠类,价值10
class Desert extends Area
{
   function function treasure()
   {
       return 10;
   }
}
//区域类的装饰器类
abstract class AreaDecorateor extends Area
{
   protected $_area = null;

   public function __construct(Area $area)
   {
       $this->_area = $area;
   }
}

//被破坏了后的区域,价值只有之前的一半
class Damaged extends AreaDecorateor
{
   public function treasure()
   {
       return $this->_area->treasure() * 0.5;
   }
}

//现在我们来获取被破坏的森林类的价值
$damageForest = new Damaged(new Forest());
echo $damageForest->treasure();  //返回50

以上就是php面向对象进阶设计模式:装饰器模式的详细内容,更多请关注其它相关文章!