为什么透明度在复合模式中超过安全性?

Ale*_*mia 5 design-patterns composite

我刚刚了解了Composite模式.据我了解,其背后的主要思想是统一处理树的边缘和节点.这意味着结构的"透明度"比"安全"更重要,导致我们这样的事情:

在此输入图像描述

我理解这个概念,但是在牺牲安全性以保证透明度是一个不错的选择时,却无法想到这种情况.换句话说,我们在哪些情况下需要透明度以至于我们愿意做出如此严肃的牺牲?

Dav*_*uth 5

更准确的说法是,在一些关于复合模式的讨论中,透明度比安全性更重要,包括四人帮的原始描述。但四人帮的描述认识到了这种权衡,而其他有影响力的讨论则更加支持安全。无论如何,这是透明度的情况:

安全性(仅在 Composite 中声明不适用于 Leaf 的方法)有成本:

  • 安全组件树的客户端需要在遍历树时检查每个组件是否是复合组件(可能使用 GoF 书第 168 页上所示的外部多态性技术)。要么树的每个客户端都需要实现此检查,要么如果在访问者或类似对象中提供检查,则需要处理这种复杂性。

  • 组件实现者需要选择每个组件是叶组件还是复合组件,如果改变选择,则需要更改代码。

“透明度”(Leaf 和 Composite 的一致性,即在 Component 中声明所有树操作方法)的价值在于最小化安全成本。

如果满足以下任一条件,透明度就会变得更有价值:

  • 叶子很少见或根本不存在。例如,在 UI 工具包中,可以将子组件添加到任何组件(甚至是通常对子组件几乎没有用处的组件,例如复选框),并期望它们能够智能地呈现。由此提供的视觉灵活性可能值得开发人员付出额外的努力,否则叶子将是叶子,并且组件中的默认实现可能会最大限度地减少额外的努力。

  • 树的许多用途不需要区分叶子和复合材料。例如,在 UI 工具包中,像绘图这样的操作可以通过迭代每个组件可能为零长度的子组件列表来统一处理叶子和复合组件。

  • 相对于程序的其余部分,具有子级列表的每个组件的运行时(内存和 CPU)成本较低。

如果上述情况属实,那么一致性会带来更多回报:树的客户端需要做更少的事情来使用树,并且这种易用性给客户端带来麻烦的情况很少见。UI 组件通常会出现这种情况:树的客户端唯一需要担心某些东西是否是 Composite 的时候可能是在他们构建(添加到)树时,此时他们知道什么无论如何,所有具体组件都是如此。

Java Swing 做出了这样的选择:JComponent包含add方法。开发人员只需不要将它们与JComponents不适合子组件的组件一起使用,这对于许多组件(同样,例如复选框)来说是显而易见的。

如果出现任何相反的情况,那么区分叶子和复合材料就变得更有价值,并且管理安全树的复杂性变得值得增加。如果叶子是常见的和/或树的许多客户端确实需要区分叶子和复合材料,但类型是“透明”的并且无法进行区分(也许 GoF 应该称此选择为不透明而不是透明),那么客户就更有可能犯错误。如果子级列表太昂贵,那么值得让组件实现者选择每个组件是叶组件还是复合组件。