2014/7/20 组合模式

一:组合模式例子:

附上源码:

类图参见书p241

IRoot.java

package combinePattern;

import java.util.ArrayList;

//根节点接口
public interface IRoot
{
	public String getInfo();
	public void add(IBranch branch);
	public void add(ILeaf leaf);
	public ArrayList getSubordinateInfo();
}

Root.java

package combinePattern;

import java.util.ArrayList;

//根节点实现
public class Root implements IRoot {

	//下级的树枝节点和树叶节点
	private ArrayList subordinateList = new ArrayList();
	//根节点名称
	private String name = "";
	//根节点职位
	private String position = "";
	//根节点薪水
	private int salary = 0;
	
	public Root(String name,String positon,int salary)
	{
		this.name = name;
		this.position = position;
		this.salary = salary;
	}
	
	public void add(IBranch branch) 
	{
		this.subordinateList.add(branch);
	}

	public void add(ILeaf leaf)
	{
		this.subordinateList.add(leaf);
	}

	public String getInfo() 
	{
		String info = "";
		info = "名称:"+this.name;
		info += "\t职位:"+this.position;
		info += "\t薪水:"+this.salary;
		return info;
	}

	public ArrayList getSubordinateInfo()
	{
		return this.subordinateList;
	}

}

IBranch.java

package combinePattern;

import java.util.ArrayList;

//有分支节点接口
public interface IBranch 
{
	public String getInfo();
	public void add(IBranch branch);
	public void add(ILeaf leaf);
	public ArrayList getSubordinateInfo();
}

Branch.java

package combinePattern;

import java.util.ArrayList;

//分支节点实现类
public class Branch implements IBranch {

	private ArrayList subordinateList = new ArrayList();
	private String name = "";
	private String position = "";
	private int salary = 0;
	
	public Branch(String name,String position,int salary)
	{
		this.name = name;
		this.position = position;
		this.salary = salary;
	}
	
	public void add(IBranch branch)
	{
		this.subordinateList.add(branch);
	}

	public void add(ILeaf leaf) 
	{
		this.subordinateList.add(leaf);
	}

	public String getInfo() 
	{
		String info = "";
		info = "名称:"+this.name;
		info += "\t职位:"+this.position;
		info += "\t薪水:"+this.salary;
		return info;
	}

	public ArrayList getSubordinateInfo()
	{
		return this.subordinateList;
	}

}

ILeaf.java

package combinePattern;

//叶子节点的接口
public interface ILeaf 
{
	public String getInfo();
}

Leaf.java

package combinePattern;

public class Leaf implements ILeaf 
{
    private String name = "";
    private String position = "";
    private int salary = 0;
    
    public Leaf(String name,String position,int salary)
    {
    	this.name = name;
    	this.position = position;
    	this.salary = salary;
    }
	
	public String getInfo() 
	{
		String info = "";
		info = "名称:"+this.name;
		info += "\t职位:"+this.position;
		info += "\t薪水:"+this.salary;
		return info;
	}

}

Client.java

package combinePattern;

import java.util.ArrayList;

public class Client 
{
	public static void main(String[] args)
	{
		//根节点
		IRoot ceo = new Root("王大麻子","总经理",100000);
		//树枝节点
		IBranch developDep = new Branch("刘大瘸子","研发部门经理",30000);
		IBranch salesDep = new Branch("马二拐子","销售部门经理",20000);
		IBranch financeDep = new Branch("赵三驼子","财务部门经理",10000);
		//小组长
		IBranch firstDevGroup = new Branch("杨三乜斜","开发一组组长",5000);
		IBranch secondDevGroup = new Branch("吴大棒槌","开发二组组长",6000);
		//叶子节点
		ILeaf a = new Leaf("a","开发人员",4000);
		ILeaf b = new Leaf("b","开发人员",4000);
		ILeaf c = new Leaf("c","开发人员",4000);
		ILeaf d = new Leaf("d","开发人员",4000);
		ILeaf e = new Leaf("e","开发人员",4000);
		ILeaf f = new Leaf("f","开发人员",4000);
		ILeaf g = new Leaf("g","开发人员",4000);
		ILeaf h = new Leaf("h","销售人员",2000);
		ILeaf i = new Leaf("i","销售人员",2000);
		ILeaf j = new Leaf("j","财务人员",2000);
		ILeaf k = new Leaf("k","CEO秘书",8000);
		ILeaf zhengLaoLiu = new Leaf("郑老六","研发部副总",20000);
		
		//组装树
		ceo.add(developDep);
		ceo.add(salesDep);
		ceo.add(financeDep);
		ceo.add(k);
		developDep.add(firstDevGroup);
		developDep.add(secondDevGroup);
		developDep.add(zhengLaoLiu);
		firstDevGroup.add(a);
		firstDevGroup.add(b);
		firstDevGroup.add(c);
		secondDevGroup.add(d);
		secondDevGroup.add(e);
		secondDevGroup.add(f);
		salesDep.add(h);
		salesDep.add(i);
		financeDep.add(j);
		//打印
		System.out.println(ceo.getInfo());
		//遍历
		getAllSubordinateInfo(ceo.getSubordinateInfo());
	}
	
	private static void getAllSubordinateInfo(ArrayList subordinateList)
	{
		int length = subordinateList.size();
		for(int m=0;m<length;m++)
		{
			Object s = subordinateList.get(m);
			if(s instanceof Leaf)
			{
				ILeaf employee = (ILeaf)s;
				System.out.println(((Leaf)s).getInfo());
			}
			else
			{
				IBranch branch = (IBranch)s;
				System.out.println(branch.getInfo());
				getAllSubordinateInfo(branch.getSubordinateInfo());
			}
		}
	}
}

评价:每个接口都有getInfo()方法,所以应该抽象出来

           Root类和Branch类差别不大,合并成一个类

           修改后的类图参见书p247:

附上源码:

ICorp.java

package combinePattern2;

public interface ICorp 
{
	public String getInfo();
}

IBranch.java

package combinePattern2;

import java.util.ArrayList;

public interface IBranch extends ICorp
{
	public void addSubordinate(ICorp corp);
	public ArrayList<ICorp> getSubordinate();
}

Branch.java

package combinePattern2;

import java.util.ArrayList;

public class Branch implements IBranch {

	private String name = "";
	private String position = "";
	private int salary = 0;
	ArrayList<ICorp> subordinateList = new ArrayList<ICorp>();
	
	public Branch(String name,String position,int salary)
	{
		this.name = name;
		this.position = position;
		this.salary = salary;
	}
	
	public void addSubordinate(ICorp corp) 
	{
		this.subordinateList.add(corp);
	}

	public ArrayList<ICorp> getSubordinate() 
	{
		return this.subordinateList;
	}

	public String getInfo() 
	{
		String info = "";
		info = "名称:"+this.name;
		info += "\t职位:"+this.position;
		info += "\t薪水:"+this.salary;
		return info;
	}

}

ILeaf.java

package combinePattern2;

public interface ILeaf extends ICorp
{

}

Leaf.java

package combinePattern2;

public class Leaf implements ILeaf 
{
	private String name = "";
	private String position = "";
	private int salary = 0;
	
	public Leaf(String name,String position,int salary)
	{
		this.name = name;
		this.position = position;
		this.salary = salary;
	}
	
	public String getInfo() 
	{
		String info = "";
		info = "名称:"+this.name;
		info += "\t职位:"+this.position;
		info += "\t薪水:"+this.salary;
		return info;
	}

}

Client.java

package combinePattern2;

import java.util.ArrayList;


public class Client
{
	public static void main(String[] args)
	{
		//调用组装函数:先组装一棵树
		Branch ceo = compositeCorpTree();
		//打印ceo节点
		System.out.println(ceo.getInfo());
		//调用遍历函数
		System.out.println(getTreeInfo(ceo));
	}
	
	public static Branch compositeCorpTree()
	{
		Branch root = new Branch("王大麻子","总经理",100000);
		Branch developDep = new Branch("刘大瘸子","研发部门经理",30000);
		Branch salesDep = new Branch("马二拐子","销售部门经理",20000);
		Branch financeDep = new Branch("赵三驼子","财务部门经理",10000);
		Branch firstDevGroup = new Branch("杨三乜斜","开发一组组长",5000);
		Branch secondDevGroup = new Branch("吴大棒槌","开发二组组长",6000);
		Leaf a = new Leaf("a","开发人员",4000);
		Leaf b = new Leaf("b","开发人员",4000);
		Leaf c = new Leaf("c","开发人员",4000);
		Leaf d = new Leaf("d","开发人员",4000);
		Leaf e = new Leaf("e","开发人员",4000);
		Leaf f = new Leaf("f","开发人员",4000);
		Leaf g = new Leaf("g","开发人员",4000);
		Leaf h = new Leaf("h","销售人员",2000);
		Leaf i = new Leaf("i","销售人员",2000);
		Leaf j = new Leaf("j","财务人员",2000);
		Leaf k = new Leaf("k","CEO秘书",8000);
		Leaf zhengLaoLiu = new Leaf("郑老六","研发部副总",20000);
		
		//组装
		root.addSubordinate(k);
		root.addSubordinate(developDep);
		root.addSubordinate(salesDep);
		root.addSubordinate(financeDep);
		developDep.addSubordinate(zhengLaoLiu);
		developDep.addSubordinate(firstDevGroup);
		developDep.addSubordinate(secondDevGroup);
		firstDevGroup.addSubordinate(a);
		firstDevGroup.addSubordinate(b);
		firstDevGroup.addSubordinate(c);
		secondDevGroup.addSubordinate(d);
		secondDevGroup.addSubordinate(e);
		secondDevGroup.addSubordinate(f);
		salesDep.addSubordinate(h);
		salesDep.addSubordinate(i);
		financeDep.addSubordinate(j);
		return root;
	}
	
	public static String getTreeInfo(Branch root)
	{
		ArrayList<ICorp> subordinateList = root.getSubordinate();
		String info = "";
		for(ICorp s : subordinateList)
		{
			//是叶子节点就直接输出信息
			if(s instanceof Leaf)
			{
				info += s.getInfo()+"\n";
			}
			else
			{
				info += s.getInfo()+"\n"+getTreeInfo((Branch)s);
			}
		}
		return info;
	}
}

继续改进:将接口改成抽象类,把方法放到具体实现类中,场景类只和抽象类进行交互

类图参见书p251

附上改进后的源码:

Corp.java

package combinePattern3;

public abstract class Corp 
{
	private String name = "";
	private String position = "";
	private int salary = 0;
	
	public Corp(String _name,String _position,int _salary)
	{
		this.name = _name;
		this.position = _position;
		this.salary = _salary;
	}
	
	public String getInfo()
	{
		String info = "";
		info = "名称:"+this.name;
		info += "\t职位:"+this.position;
		info += "\t薪水:"+this.salary;
		return info;
	}
}

Leaf.java

package combinePattern3;

public class Leaf extends Corp
{
	public Leaf(String name, String position, int salary) {
		super(name, position, salary);
		// TODO Auto-generated constructor stub
	}
}

Branch.java

package combinePattern3;

import java.util.ArrayList;

public class Branch extends Corp
{
	ArrayList<Corp> subordinateList = new ArrayList<Corp>();
	
	public Branch(String name, String position, int salary) {
		super(name, position, salary);
		// TODO Auto-generated constructor stub
	}

	public void addSubordinate(Corp corp)
	{
		this.subordinateList.add(corp);
	}
	
	public ArrayList<Corp> getSubordinate()
	{
		return this.subordinateList;
	}
}

二:组合模式的定义:

组合模式的几个角色:

1.Component抽象构建角色:定义参加组合对象的共有方法和属性

2.Leaf叶子构件:叶子对象,遍历的最小单位

3.Composite树枝构件:树枝对象,组合树枝节点和叶子节点形成一个树形结构

通用源码如下:

Component.java

package compositePattern;

//抽象构件
public abstract class Component 
{
	public void doSomething()
	{
		//编写业务逻辑
	}
}

Composite.java

package compositePattern;

import java.util.ArrayList;

//树枝构件
public class Composite extends Component
{
	private ArrayList<Component> componentArrayList = new ArrayList<Component>();
	
	//增加一个叶子构件或树枝构件
	public void add(Component component)
	{
		this.componentArrayList.add(component);
	}
	
	//删除一个叶子构件或树枝构件
	public void remove(Component component)
	{
		this.componentArrayList.remove(component);
	}
	
	public ArrayList<Component> getChildren()
	{
		return this.componentArrayList;
	}
}

Leaf.java

package compositePattern;

public class Leaf extends Component
{
	/*可以覆写该方法doSomething()*/
}

Client.java

package compositePattern;

public class Client 
{
	public static void main(String[] args)
	{
		//创建一个根节点
		Composite root = new Composite();
		root.doSomething();
		//创建一个树枝构件
		Composite branch = new Composite();
		//创建一个叶子节点
		Leaf leaf = new Leaf();
		//构件树
		root.add(branch);
		branch.add(leaf);
	}
	
	//递归遍历树
	public static void display(Composite root)
	{
		for(Component c : root.getChildren())
		{
			if(c instanceof Leaf)//叶子节点
				c.doSomething();
			else //树枝节点
				display((Composite)c);
		}
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值