设计模式——组合模式

文章目录

    • 1.动机
    • 2.定义
    • 3.使用场景
    • 4.UML图
    • 5.透明方式和安全方式
      • 5.1透明方式
        • 5.1.1 优点
        • 5.1.2 缺点:
      • 5.2安全方式
        • 5.2.1 优点
        • 5.2.2 缺点
    • 6.代码模板(使用透明方式)
      • Component
      • Leaf
      • Composite
      • Client
      • 运行结果

1.动机

软件在某些情况下,客户代码过多地依赖于对象容器复杂的内部实现结构,对象容器内部实现结构(而非抽象接口)的变化将引起客户代码的频繁变化,带来了代码的维护性、扩展性等弊端。

2.定义

组合模式,将对象组合成树形结构以表示 ‘ 部分-整体 ’ 的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。

3.使用场景

出现树形结构的地方:如文件管理系统、办公管理系统(如图)。
设计模式——组合模式_第1张图片

4.UML图

设计模式——组合模式_第2张图片

5.透明方式和安全方式

两者各有好处,视情况而定

5.1透明方式

在Component中 声明所有管理子对象的方法,实现Component接口的所有子类都具各Add和Remove以及Display等方法。

5.1.1 优点

叶节点和枝节点对于外界没有区别,它们具备完全一致的行为接口,客户端可以同等的对待所有的对象。

5.1.2 缺点:

不够安全,因为树叶类对象和合成类对象在本质.上是有区别的。树叶类对象不可能有下一个层次的对象,因此add()、remove()以及Display()方法没有意义。

5.2安全方式

在Component中不去声明Add和Remove方法,那么子类的Leaf也就不需要去实现它,而是在合成类Composite (不是Component类)声明所有用来管理子类对象的方法。
设计模式——组合模式_第3张图片

5.2.1 优点

这样的做法是安全的做法,树叶类型的对象根本就没有管理子类对象的方法,因此,如果客户端对树叶类对象使用这些方法时,程序会在编译时期出错。

5.2.2 缺点

不够透明,树叶类和合成类将具有不同的接口,客户端的调用雪要做相应的判断,带来了不便。

6.代码模板(使用透明方式)

Component

//节点抽象类
abstract class Component {

	protected String name;

	public Component(String name) {
		super();
		this.name = name;
	}

	public abstract void Add(Component c);

	public abstract void Remove(Component c);

	public abstract void Display(int depth);

}

Leaf

//叶子节点
class Leaf extends Component {

	public Leaf(String name) {
		super(name);
	}

	@Override
	public void Add(Component c) {
		System.out.println("can't add to a leaf!");
	}

	@Override
	public void Remove(Component c) {
		System.out.println("can't remove from a leaf");
	}

	@Override
	public void Display(int depth) {
		for(int i = 1;i<depth;i++)
			System.out.print(" ");
		System.out.println("--" + depth + name);  //显示节点内容
	}

}

Composite

//分支节点
class Composite extends Component {
	private List<Component> children = new ArrayList<Component>(); //用list存放下级节点(叶子节点或分支节点)

	public Composite(String name) {
		super(name);
	}

	@Override
	public void Add(Component c) {
		this.children.add(c);
	}

	@Override
	public void Remove(Component c) {
		this.children.remove(c);
	}

	@Override
	public void Display(int depth) {
		for(int i = 1;i<depth;i++)
			System.out.print(" ");
		System.out.println("--" + depth + name);  //显示节点内容
		for (Component component : children) {   //遍历下级节点
			component.Display(depth + 1);
		}
	}
}

Client

//客户端代码
public class Main {
	public static void main(String[] args) {
		//给root根节点添加叶子
		Composite root = new Composite("root");
		root.Add(new Leaf("Leaf RA"));
		root.Add(new Leaf("Leaf RB"));
		
		//给分支节点comp添加叶子
		Composite comp = new Composite("comp");
		comp.Add(new Leaf("Leaf CA"));
		comp.Add(new Leaf("Leaf CB"));
		
		//将comp 加入到root下
		root.Add(comp);
		
		//给分支节点comp2添加叶子,并加到comp下
		Composite comp2 = new Composite("comp2");
		comp2.Add(new Leaf("Leaf C2A"));
		comp2.Add(new Leaf("Leaf C2B"));
		
		comp.Add(comp2);
		
		Leaf leaf_c = new Leaf("leaf_c");
		root.Add(leaf_c);
		
		//打印信息
		root.Display(1);
	}
}

运行结果

设计模式——组合模式_第4张图片

你可能感兴趣的:(设计模式)