复合设计模式叶管理

时间:2015-07-27 18:42:41

标签: oop design-patterns

我见过的复合设计模式的大多数描述都使Composite实现了add()remove()方法,并且在Leaf对象中保留了这些方法的实现。例如,主题Wiki Page中的图表显示了这一点,与GoF图表大致相同。

关于在父Component课程中实施这些课程,GoF有如下说法:

  

在类层次结构的根目录中定义子管理界面可以提供透明性,因为您可以统一处理所有组件。然而,这会让您感到安全,因为客户可能会尝试做无意义的事情,例如在树叶中添加和删除对象。

我同意拥有Leaf工具remove()很难处理。 (你自己删除了吗?你必须实现某种NullLeaf对象吗?)但是因为模式的要点是让LeafComposite的行为方式相同我不明白为什么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()

1 个答案:

答案 0 :(得分:0)

  

为什么组件至少不能实现add()?这样做会违反   任何关键设计原则?这样做不再是一个   复合设计模式?

你自己回答了这个问题,正如你写的那样

  

在类的根目录中定义子管理界面   层次结构为您提供透明度,因为您可以处理所有组件   均匀。然而,这会让您感到安全,因为客户可能会尝试这样做   无意义的事情,比如从树叶中添加和删除对象。

将子管理方法添加到界面是一种权衡。执行此操作时,您将获得统一处理层次结构中所有对象的好处。但是对于叶子你必须决定一个处理界面的策略是没有意义的。可以做的是为方法创建空实现或在调用它们时抛出异常。另一种方法是创建一个定义Componentadd()方法的抽象基类remove(),然后在Composite中使用该实现并覆盖方法例如,Leaf中有一个空实现。所有这些实现都是Composite模式变体。恕我直言,这些模式不应该逐字逐句阅读,而应作为指导原则,让您自己定制实施。