我正在阅读这本书"设计模式"并复习复合模式。请仔细阅读link以获取问题的背景信息。书中给出了以下类图: -
我的问题是关于在Java中实现这种模式的做法。
Graphic
- 接口或抽象类?Graphic
声明Add(Graphic)
,Remove(Graphic)
和GetChild(int)
等方法。正在实现(或扩展)Graphic
的类必须为这些方法提供实现。但是Line
,Rectangle
和Text
等类不需要这些方法。因此,在实现Graphic
接口或扩展Graphic
抽象类时,这些类对这些方法的作用是什么。他们可以为这些方法设置空白或空白吗?答案 0 :(得分:2)
Composite Design Pattern Details
请参阅上面链接中的图片了解复合设计图案。
复合模式基本上将责任委托给孩子。复合模式中有三个感兴趣的元素。
<强> 1。核心接口此接口是模式的根。在我们的示例中,它是Drawing接口。它仅包含需要委派的行为。它不包含与创建复合相关的行为。
<强> 2。复合接口这是核心接口的扩展它定义添加方法,在另一个对象中添加一个对象,从而使复合设计。< / p>
这两个接口都可以通过许多子类实现。
实现核心接口的对象称为终端元素。 例如。线,矩形
实现复合接口的对象称为复合元素 例如。图层,绘图
复合材料可能包含其他复合材料或终端。因此它提供了树结构。对root执行的任何操作都将委托给子级。
复合对象的创建超出了复合模式的范围。
答案 1 :(得分:1)
我的看法是:
由于Graphic
是客户端与之交互的主要(或唯一)类,因此它应该是一个接口。虽然它是一个抽象类并不“错误”,但它既是更好的设计,也更适合在服务器和客户端之间以代理等模式传递。
您的观点提出了区分不是由儿童图形组成的SimpleGraphic
和区分ComplexGraphic
的必要性。这些抽象类实现了接口,并包含一些接口方法的默认实现。 (我会让SimpleGraphic
为所有与树有关的方法抛出UnsupportedOperationException
。所有具体的Graphics都会扩展上面提到的一个抽象类。我还要在界面中添加canAddGraphic()
方法,以便客户轻松构建复杂的图形。
答案 2 :(得分:1)
1.如何定义Graphic - 作为接口还是抽象类?
从概念上讲,Graphic
应该是一个界面
现在,复制叶子组件的常用方法的实现是没有意义的
因此,添加一个实现AbstractLeafGraphic
的{{1}}抽象类可能是有意义的。
- ...因此,在实现Graphic接口或扩展Graphic抽象类时,这些类将如何处理这些类 方法。他们可以为这些实现空白或空白 方法
醇>
复合模式是一种模式,提供了一个简单的API,以透明的方式操作复合(包含组件)和叶组件。
它具有以下优点:API容易。
它有缺点:为不需要它们的类定义方法。
从你引用的书中,给出了一个简单而精细的建议:
通常最好在默认情况下使添加和删除失败(也许通过 提出异常)如果不允许该组件 孩子...
答案 3 :(得分:0)
<强> 1 强>
根据您提供的UML图,我会说Graphic是一个抽象类,因为斜体名称。 (有关详细信息,请查看UML, Abstract Classes and Methods, and Interfaces。)但是,正如其他人所建议的那样,您也可以使用界面。这将在未来为您提供更多模块化。
2。
此模式的用途是“..复合模式是 抽象类,它代表基元及其容器。”作为第一个UML图之后的第一段中的source for your picture describes。
可以在Sourcemaking上找到有关此模式的更好描述,您可以在其中找到有关此模式用法的更好示例和更多信息。
Line
,Rectangle
和Text
都是简单的“叶子”组件,它们不包含任何子项Graphics
,因此不需要这些方法。
因此,在实现Graphic接口或扩展Graphic抽象类时,这些类对这些方法的作用是什么。他们可以为这些方法设置空白或空白吗?
我会说这个图有点令人困惑,因为你不希望在代码中悬空的方法。您可以实现这些方法来抛出异常或处理不同类型的转换。例如:可以实现向Graphic
对象添加另一个Text
对象,以创建Composite
两个Graphics
对象作为叶子。但这可能有些复杂。
但是,我在使用此模式时学到的是,您的目标是让用户能够统一使用合成和单个对象。您可以根据需要调整实施以实现此目标。这就是模式,它们是结构和行为的指导,而不是代码。
希望这有帮助!
答案 4 :(得分:0)
您正在阅读一本考虑使用C ++实现的书,因此类图反映了缺少接口(在Java意义上)。因此,如果您计划在C ++中实现,那么您的答案就是抽象类。
对于基于接口的方法,请考虑维基百科文章,其中给出了基于接口的示例。 https://en.wikipedia.org/wiki/Composite_pattern
关于第二个问题 - 这是一个权衡。您可以使它无所作为,冒着图书馆用户冒险进行无意义操作的风险,例如将子节点添加到叶节点。或者您可以在使用之前对每个类进行类型检查并采取相应的行动。