组合模式

定义:

组合多个对象形成树形结构以表示具有部分-整 体关系的层次结构。组合模式让客户端对单个对 象和组合对象的使用具有一致性。(组合模式屏蔽了单个对象与容器对象在使用时候的差异,为客户端提供统一的操作接口)。

 

结构图:

组合模式_第1张图片

例子:

/*
 * 公司类:充当抽象构件类 
 */
public abstract class Company {
	protected String name;

	public Company(String name) {
		this.name = name;
	}
	
	public abstract void Add(Company c);
	public abstract void Remove(Company c);
	public abstract void Display(int depth);
	public abstract void LineOfDuty();
}

 

/*
 * 具体公司:充当容器构件类 
 */
public class ConcreteCompany extends Company {
	private List children = new ArrayList();

	public ConcreteCompany(String name) {
		super(name);
		// TODO Auto-generated constructor stub
	}

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

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

	@Override
	public void Display(int depth) {
		System.out.println("-" + name);
		for (Company c : children) {
			for (int i = 0; i < depth; i++) {
				System.out.print("--");
			}
			c.Display(depth + 2);
		}
	}

	@Override
	public void LineOfDuty() {
		for (Company c : children) {
			c.LineOfDuty();
		}
	}

}
/*
 * 公司具体部门1:充当叶子节点
 */
public class HRDepartment extends Company{

	public HRDepartment(String name) {
		super(name);
		// TODO Auto-generated constructor stub
	}

	@Override
	public void Add(Company c) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void Remove(Company c) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void Display(int depth) {
		System.out.println("-" + name);

		
	}

	@Override
	public void LineOfDuty() {
		System.out.println(name + " staffs' trainning and managing");
		
	}

}

/*
 * 公司具体部门2:充当叶子节点
 */
public class FinanceDepartment extends Company {
......
}
public class CompositeMain {
	public static void main(String[] args) {
		ConcreteCompany root = new ConcreteCompany("Beijing");
		root.Add(new HRDepartment("Beijing HR"));
		root.Add(new FinanceDepartment("Beijing Finance"));

		ConcreteCompany comp = new ConcreteCompany("Shanghai");
		comp.Add(new HRDepartment("Shanghai HR"));
		comp.Add(new FinanceDepartment("Shanghai Finance"));
		root.Add(comp);

		ConcreteCompany comp1 = new ConcreteCompany("Hangzhou");
		comp1.Add(new HRDepartment("Hangzhou HR"));
		comp1.Add(new FinanceDepartment("Hangzhou Finance"));
		comp.Add(comp1);

		ConcreteCompany comp2 = new ConcreteCompany("Nanjing");
		comp2.Add(new HRDepartment("Nanjing HR"));
		comp2.Add(new FinanceDepartment("Nanjing Finance"));
		comp.Add(comp2);

		System.out.println("\nConstruct-Map");
		root.Display(1);

		System.out.println("\nDuty");
		root.LineOfDuty();

	}

}

 

组合模式优点:

其实它的目的就是让客户可以一致地使用组合结构和单个对象。而组合模式定义了包含基本对象和组合对象的类层次结构,基本对象可以被组合成更复制的组合对象,这个组合对象还可以被组合,一直递归下去,在代码中任何用到基本对象的地方也都可以用组合对象。用户不用去关心处理的是一个基本对象还是组合对象,也就是不用为定义组合而写一些选择判断语句了。

 

透明组合模式与安全组合模式:

透明组合模式是在Component中声明了所有用于管理子类的 方法,包括add()、remove(),以及getChild()等 。这样实现Component接口的所有子类都具备了add()、remove(),以及getChild()等方法。好处是叶节点和枝节点有完全一样的行为接口,没有什么区别。但Leaf类本身不具有add()、remove(),以及getChild()等方法的功能,造成了多余的实现。

安全组合模式是在Component中不去声明add()、remove(),以及getChild()等 方法。那么子类Leaf就不需要去实现它。而是在Composite声明所有用于管理子类的方法。但这样的问题是叶节点和枝节点将不具有相同的接口。客户端在调用时需要做相应的判断。

 

所谓鱼与熊掌不可兼得,只能权衡选择~

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