设计模式——组合模式

1.动机

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

2.定义

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

3.使用场景

出现树形结构的地方:如文件管理系统、办公管理系统(如图)。
在这里插入图片描述

4.UML图

在这里插入图片描述

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类)声明所有用来管理子类对象的方法。
在这里插入图片描述

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);
	}
}

运行结果

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值