我见过的复合设计模式的大多数描述都使Composite
实现了add()
和remove()
方法,并且在Leaf
对象中保留了这些方法的实现。例如,主题Wiki Page中的图表显示了这一点,与GoF图表大致相同。
关于在父Component
课程中实施这些课程,GoF有如下说法:
在类层次结构的根目录中定义子管理界面可以提供透明性,因为您可以统一处理所有组件。然而,这会让您感到安全,因为客户可能会尝试做无意义的事情,例如在树叶中添加和删除对象。
我同意拥有Leaf
工具remove()
很难处理。 (你自己删除了吗?你必须实现某种NullLeaf
对象吗?)但是因为模式的要点是让Leaf
和Composite
的行为方式相同我不明白为什么add()
可以在Component
中实施。
我的问题:为什么Component
至少无法实施add()
?这样做会违反任何关键设计原则吗?这样做不再使这成为复合设计模式吗?下面是Python中的一个示例,它捕获了我在自己的工作中尝试实现的内容:
class Component:
def add(self, other):
# in Python, may be more natural to define __add__
c = Composite()
c.children = self.children + other.children
return c
class Leaf(Component):
def __init__(self):
self.children = [self] # possibly strange?
def operation(self):
# operation specific to this leaf
class Composite(Component):
def __init__(self):
self.children = []
def operation(self):
for child in self.children:
child.operation()
使用“示例用法”:
>>> l1 = Leaf()
>>> l2 = Leaf()
>>> c = l1.add(l2) # c is a `Composite` instance
>>> c.operation()
答案 0 :(得分:0)
为什么组件至少不能实现add()?这样做会违反 任何关键设计原则?这样做不再是一个 复合设计模式?
你自己回答了这个问题,正如你写的那样
在类的根目录中定义子管理界面 层次结构为您提供透明度,因为您可以处理所有组件 均匀。然而,这会让您感到安全,因为客户可能会尝试这样做 无意义的事情,比如从树叶中添加和删除对象。
将子管理方法添加到界面是一种权衡。执行此操作时,您将获得统一处理层次结构中所有对象的好处。但是对于叶子你必须决定一个处理界面的策略是没有意义的。可以做的是为方法创建空实现或在调用它们时抛出异常。另一种方法是创建一个定义Component
和add()
方法的抽象基类remove()
,然后在Composite
中使用该实现并覆盖方法例如,Leaf
中有一个空实现。所有这些实现都是Composite
模式变体。恕我直言,这些模式不应该逐字逐句阅读,而应作为指导原则,让您自己定制实施。