组合模式是结构型模式中的一种,他通常可以用来实现类似树结构的功能。

就比如一副画,画由矩形,三角形组成,其中各个形状的颜色不同。这里画就好比跟节点(Tree Root), 各个形状就好比 Tree Leaf,而这些形状就是组成画的基本元素

通过上述比喻,不难推断出组合模式有以下对象组成

  1. Base Component 组合模式中所有对象需要实现的接口类
  2. Leaf 实现Base Component的类,且各个Leaf是互不相关的
  3. Composite 包含Leaf,同时也实现了Base Component

下面我们通过画画这个例子来实现组合模式

Base Component

接口类,提供颜色来表明Leaf 的颜色

Shape.java

1
2
3
4
5
6
package com.walterlife.dp.CompositeDP;

public interface Shape {
public void draw(String color);
public String getName();
}

Leaf 对象

我们可以根据自己的需要创建不同形状的Leaf

Circle.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.walterlife.dp.CompositeDP;

import org.apache.log4j.Logger;

public class Circle implements Shape {

private String name;

private static Logger logger = Logger.getLogger(Circle.class);

public Circle(String name) {
this.name = name;
}

public void draw(String color) {
logger.info("Circle draw with Color: " + color);
}

public String getName() {
return name;
}
}

Triangle.java

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
package com.walterlife.dp.CompositeDP;

import org.apache.log4j.Logger;

public class Triangle implements Shape {

private String name;

private static Logger logger = Logger.getLogger(Circle.class);

public Triangle(String name) {
this.name = name;
}

public void draw(String color) {
logger.info("Triangle draw with Color: " + color);
}

/**
* @return the name
*/

public String getName() {
return name;
}
}

Composite

该类需包含Leaf Objects,同时我们需要提供方法方便添加/删除Leaf,清除全部也可以提供

Drawing.java

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
package com.walterlife.dp.CompositeDP;

import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;

public class Drawing implements Shape {

private List<Shape> shapes = new ArrayList<Shape>();
private String name;

private static Logger logger = Logger.getLogger(Drawing.class);

public void draw(String color) {
for(Shape shape: shapes) {
shape.draw(color);
}
}

public Drawing(String name) {
this.name= name;
}

public void addShapes(Shape shape) {
if(shape == null) {
logger.error("Drawing addShapes: shape is null, not valid!!!");
} else if(shapes.contains(shape)) {
logger.warn("Drawing addShapes: shape " + shape.getName() + " is already existing!!!");
} else {
shapes.add(shape);
}
}

public void removeShapes(Shape shape) {
if(!shapes.remove(shape)) {
logger.warn("Drawing removeShapes: shape does not exist!!!");
}
}

public void clear() {
logger.info("Drawing clear: clear all shape!!!");
shapes.clear();
}

/**
* @return the name
*/

public String getName() {
return name;
}
}

Drawing 类和Leaf Classes 类似,也实现了Shape 类的draw 方法,除了他包含了所有Leaf Objects

测试代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public static void testComposite() {
Drawing drawing = new Drawing("Drawing");

Shape cir = new Circle("Circle");
Shape tri1 = new Triangle("Triangle");
Shape tri2 = new Triangle("Triangle");

drawing.addShapes(cir);
drawing.addShapes(tri1);
drawing.addShapes(tri2);

drawing.draw("RED");

drawing.clear();

drawing.addShapes(cir);
drawing.addShapes(tri1);

drawing.draw("GREEN");
}

测试结果

1
2
3
4
5
6
2015-09-06 01:15:02 INFO  com.walterlife.dp.CompositeDP.Circle draw:16 -> Circle draw with Color: RED
2015-09-06 01:15:03 INFO com.walterlife.dp.CompositeDP.Triangle draw:16 -> Triangle draw with Color: RED
2015-09-06 01:15:03 INFO com.walterlife.dp.CompositeDP.Triangle draw:16 -> Triangle draw with Color: RED
2015-09-06 01:15:03 INFO com.walterlife.dp.CompositeDP.Drawing clear:42 -> Drawing clear: clear all shape!!!
2015-09-06 01:15:03 INFO com.walterlife.dp.CompositeDP.Circle draw:16 -> Circle draw with Color: GREEN
2015-09-06 01:15:03 INFO com.walterlife.dp.CompositeDP.Triangle draw:16 -> Triangle draw with Color: GREEN

留言