组合模式设计问题

6

我有一个关于组合类图中常见的两个操作的问题:
* GetDescendents
* GetChild(int)

一个常见的例子是文件和目录,我们以此为例。假设我们感兴趣的操作是Size,那么File有一个实际的大小,而Directory有一个从GetDescendents递归迭代得出的Size。到目前为止还好。我的问题与客户端对GetDescendents的使用有关。比如说你需要某个操作中的目录中的图片文件。因此在实践中,你可以使用GetDescendents和Children的某种组合来返回imageFiles(取决于客户端是否想要所有嵌套的imageFiles还是只在根级别)。

所以第一个问题是,你不太可能在组合体上有一个GetImageFiles方法而不是让客户端自己想出来吧?并且假设如此,在组合之外,将GetDescendents暴露给客户端调用者(如ImageViewer)是否实用?

关于GetChild(int)的第二个问题:int是否是返回单个子项的序数位置索引?是GetDescendents的深度级别吗?客户端如何使用该方法的例子是什么?

祝好,
Berryl

1个回答

4
这些问题与组合模式本身无关,而是关于如何进行API设计并明确传达类开发人员的意图的更大问题。
例如,如果您想让GetChild(int)返回索引的直接子项,则可以将其命名为GetChildAtIndex(int index);如果您想在层次结构中给定级别的子代,则可以将其命名为GetChildrenAtLevel(int level)(请注意,这是复数形式并返回一个集合)。
作为类设计者,您需要公开足够的操作来使您的类可理解和可用。如果您认为获取目录结构上的图像文件是非常常见的操作,则可以公开GetAllImageFiles()方法。但对于更一般的目录类,这个选择似乎是武断的,并且处于错误的抽象级别。为什么图像文件如此特殊?相反,您可以提供一个更一般的方法,该方法根据扩展名获取所有文件或采用谓词的方法,根据客户端提供的条件过滤结果。

没错。我的问题是,是否有必要向不属于组合的客户端公开子操作,或者至少与之有非常密切的关系 - 即它们是内部操作,用于生成客户端可消耗的操作,如GetFilesOfType()。 - Berryl
@Berryl:这取决于你的类代表什么。 "模式" 只是一种实现细节,重要的是 "概念"。 - Jordão

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接