树状结构,有些包含子节点,有些只有自己

文件夹和文件的关系
快递包装和快递内容物的关系
实现
- 确保应用的核心模型能够以树状结构表示。 尝试将其分解为简单元素和容器。 记住, 容器必须能够同时包含简单元素和其他容器。
- 声明组件接口及其一系列方法, 这些方法对简单和复杂元素都有意义。
- 创建一个叶节点类表示简单元素。 程序中可以有多个不同的叶节点类。
- 创建一个容器类表示复杂元素。 在该类中, 创建一个数组成员变量来存储对于其子元素的引用。 该数组必须能够同时保存叶节点和容器, 因此请确保将其声明为组合接口类型。
实现组件接口方法时, 记住容器应该将大部分工作交给其子元素来完成。
- 最后, 在容器中定义添加和删除子元素的方法。
记住, 这些操作可在组件接口中声明。 这将会违反_接口隔离原则_, 因为叶节点类中的这些方法为空。 但是, 这可以让客户端无差别地访问所有元素, 即使是组成树状结构的元素。
注意下面实现中,容器实现的时候除了自己的增加和删除方法,继承自父接口的方法都是尽量去调用自己的孩子节点去处理,调用孩子节点的同样的方法,因为他的孩子也一定实现了这个方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
| interface Graphic is method move(x, y) method draw()
class Dot implements Graphic is field x, y
constructor Dot(x, y) { ... }
method move(x, y) is this.x += x, this.y += y
method draw() is
class Circle extends Dot is field radius
constructor Circle(x, y, radius) { ... }
method draw() is
class CompoundGraphic implements Graphic is field children: array of Graphic
method add(child: Graphic) is
method remove(child: Graphic) is
method move(x, y) is foreach (child in children) do child.move(x, y)
method draw() is
class ImageEditor is field all: CompoundGraphic
method load() is all = new CompoundGraphic() all.add(new Dot(1, 2)) all.add(new Circle(5, 3, 10))
method groupSelected(components: array of Graphic) is group = new CompoundGraphic() foreach (component in components) do group.add(component) all.remove(component) all.add(group) all.draw()
|