Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Design patterns 装饰设计模式_Design Patterns_Oop_Decorator - Fatal编程技术网

Design patterns 装饰设计模式

Design patterns 装饰设计模式,design-patterns,oop,decorator,Design Patterns,Oop,Decorator,我刚开始学习设计模式,我有两个问题与装饰师有关 我想知道为什么decorator模式建议decorator实现它所装饰的组件的所有公共方法 decorator类难道不能仅仅用来提供额外的行为,然后具体的组件(被传递到它中)就可以用来调用其他的一切吗 其次,如果您想要装饰的具体组件没有抽象装饰器也可以从中派生的基类,该怎么办 提前谢谢 我想你误解了装饰师。您正在考虑一个使用附加功能扩展具体类的简单案例。在这种情况下,是的,在大多数OO语言中,派生类只允许其超类处理任何未实现的方法 class Ba

我刚开始学习设计模式,我有两个问题与装饰师有关

我想知道为什么decorator模式建议decorator实现它所装饰的组件的所有公共方法

decorator类难道不能仅仅用来提供额外的行为,然后具体的组件(被传递到它中)就可以用来调用其他的一切吗

其次,如果您想要装饰的具体组件没有抽象装饰器也可以从中派生的基类,该怎么办


提前谢谢

我想你误解了装饰师。您正在考虑一个使用附加功能扩展具体类的简单案例。在这种情况下,是的,在大多数OO语言中,派生类只允许其超类处理任何未实现的方法

class Base {

  function foo() {
    return "foo";
  }

  function bar() {
    return "bar";
  }

}

// Not what we think of as a Decorator,
// really just a subclass.
class Decorator extends Base {

  // foo() inherits behavior from parent Base class 

  function bar() {
    return parent::bar() . "!"; // add something
  }

}

装饰器类不扩展其“装饰”类的基类。它是另一种类型,具有修饰类的成员对象。因此,它必须实现相同的接口,即使只是调用装饰对象的相应方法

class Decorator { // extends nothing
  protected $base;

  function __construct(Base $base) {
    $this->base = $base;
  }

  function foo() {
    return $base->foo();
  }

  function bar() {
    return $base->foo() . "!"; // add something
  }

}
为修饰类和修饰类定义一个接口(如果您的语言支持这样做的话)可能是值得的。这样,您可以在编译时检查Decorator是否实现了相同的接口

interface IBase {
  function foo();
  function bar();
}

class Base implements IBase {
  . . .
}

class Decorator implements IBase {
  . . .
}

Re:@Yossi Dahan的评论:我看到wikipedia文章中的歧义,但是如果你仔细阅读,它确实说被修饰的组件是decorator对象中的一个字段,并且组件作为参数传递给decorator构造函数。这与继承不同

尽管wikipedia文章确实说装饰器继承自组件,但您应该将其视为实现一个接口,正如我在上面的PHP示例中所示。装饰器仍然必须代理组件对象,如果它继承了组件对象,就不会代理。这允许装饰器装饰实现该接口的任何类的对象

interface IBase {
  function foo();
  function bar();
}

class Base implements IBase {
  . . .
}

class Decorator implements IBase {
  . . .
}
下面是Gamma、Helm、Johnson和Vlissides的“设计模式:可重用面向对象软件的元素”的一些摘录:

室内装修设计师 意图 将附加责任附加到对象 动态地。装饰师提供了一个 子类化的灵活替代方案 用于扩展功能

动机 。。。 装饰器符合 它装饰的组件,使其 在场对公众是透明的 组件的客户端

参与者
  • 装饰师 维护对组件对象的引用并定义接口 这符合组件的接口
我想知道为什么decorator模式建议decorator实现它所装饰的组件的所有公共方法

装饰器应该是它装饰的组件的替代品,具有额外的功能(“装饰”)。只有当它完全实现组件的接口时,才会发生这种情况

interface IBase {
  function foo();
  function bar();
}

class Base implements IBase {
  . . .
}

class Decorator implements IBase {
  . . .
}
decorator类难道不能仅仅用来提供额外的行为,然后具体的组件(被传递到它中)就可以用来调用其他的一切吗

这就假设了装饰器是如何实现的。您不能确定它所修饰的组件的整个公共接口是否直接通过。装饰器有可能在其实现中重写某些方法

其次,如果您想要装饰的具体组件没有抽象装饰器也可以从中派生的基类,该怎么办


装饰器通常继承他们正在装饰的组件的类,而不是组件的基类。

“装饰器类不扩展其“装饰”类的基类。它是另一种类型,具有装饰类的成员对象”-我很困惑,维基百科中的定义不是正好相反吗?()@Yossi Dahan:请参阅上面的其他内容。