Java设计模式学习之组合模式
组合模式是结构型模式中的一种,他通常可以用来实现类似树结构的功能。
就比如一副画,画由矩形,三角形组成,其中各个形状的颜色不同。这里画就好比跟节点(Tree Root), 各个形状就好比 Tree Leaf,而这些形状就是组成画的基本元素
通过上述比喻,不难推断出组合模式有以下对象组成
- Base Component 组合模式中所有对象需要实现的接口类
- Leaf 实现Base Component的类,且各个Leaf是互不相关的
- Composite 包含Leaf,同时也实现了Base Component
下面我们通过画画这个例子来实现组合模式
Base Component
接口类,提供颜色来表明Leaf 的颜色
Shape.java1
2
3
4
5
6package com.walterlife.dp.CompositeDP;
public interface Shape {
public void draw(String color);
public String getName();
}
Leaf 对象
我们可以根据自己的需要创建不同形状的Leaf
Circle.java1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22package 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.java1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25package 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.java1
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
52package 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
20public 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
62015-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