一、概念
组合模式:将对象组合成树型结构以表示部分-整体的层次结构,组合模式使用户对单个对象和组合对象的使用具有一致性。
二、类图及基本代码
Leaf是叶子节点,没有子节点。
Composite是枝节点,用于存储子部件,实现与子部件相关的行为,如Add,Remove等。
Component是一个接口,用于访问和管理子部件。
/*
* 声明一个接口负责访问和管理Component的子部件
*/
public abstract class Component {
protected String name;
public Component(String name){
this.name=name;
}
public abstract void Add(Component component);
public abstract void Remove(Component component);
public abstract void Display(int depth);
}
/*
* 定义有枝节点行为,用来存储子部件
*/
public class Composite extends Component{
private List<Component> list=new ArrayList();
public Composite(String name) {
super(name);
}
@Override
public void Add(Component component) {
list.add(component);
}
@Override
public void Remove(Component component) {
list.remove(component);
}
@Override
public void Display(int depth) {
String string="";
for(int i=0;i<depth;i++){
string+="-";
}
System.out.println(string+name);
//展示枝节点上的所有节点
for (Component component : list) {
component.Display(depth+2);
}
}
}
/*
* 叶子节点
*/
public class Leaf extends Component{
public Leaf(String name) {
super(name);
}
@Override
public void Add(Component component) {
System.out.println("Cann't add to a leaf");
}
@Override
public void Remove(Component component) {
System.out.println("Cann't remove from a leaf");
}
//展示
@Override
public void Display(int depth) {
String string="";
for(int i=0;i<depth;i++){
string+="-";
}
System.out.println(string+name);
}
}
package com.hwj.www.model19.version1;
public class Show {
public static void main(String[] args) {
Composite root=new Composite("root");//root节点
root.Add(new Leaf("Leaf A"));//主节点上放入两个叶子节点
root.Add(new Leaf("Leaf B"));
Composite composite=new Composite("Composite X");
composite.Add(new Leaf("Leaf XA"));
composite.Add(new Leaf("Leaf XB"));
root.Add(composite);//枝节点Compostie X上放了两个叶子节点
Composite composite2=new Composite("Composite XY");
composite2.Add(new Leaf("Leaf XYA"));
composite2.Add(new Leaf("Leaf XYB"));
composite.Add(composite2);//将枝节点Composite XY放到枝节点Composite X上
root.Add(new Leaf("Leaf C"));
Leaf leaf=new Leaf("Leaf D");
root.Add(leaf);
root.Remove(leaf);
root.Display(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 dept);//展示
public abstract void LineOfDuty();//履行职责
}
//具体公司
public class ConcreteCompany extends Company{
private List<Company> list=new ArrayList<>();
public ConcreteCompany(String name) {
super(name);
}
@Override
public void Add(Company c) {
list.add(c);
}
@Override
public void Remove(Company c) {
list.remove(c);
}
@Override
public void Display(int dept) {
String string="";
for(int i=0;i<dept;i++){
string+="-";
}
System.out.println(string+name);
for(Company company:list){
company.Display(dept+2);
}
}
@Override
public void LineOfDuty() {
}
}
//人力资源部
public class HRDepartment extends Company{
public HRDepartment(String name) {
super(name);
}
@Override
public void Add(Company c) {
System.out.println("不能操作");
}
@Override
public void Remove(Company c) {
System.out.println("不能操作");
}
@Override
public void Display(int dept) {
String string="";
for(int i=0;i<dept;i++){
string+="-";
}
System.out.println(string+name);
}
@Override
public void LineOfDuty() {
System.out.println("员工招聘管理"+name);
}
}
//财务部
class FinanceDepartment extends Company{
public FinanceDepartment(String name) {
super(name);
}
@Override
public void Add(Company c) {
System.out.println("不能操作");
}
@Override
public void Remove(Company c) {
System.out.println("不能操作");
}
@Override
public void Display(int dept) {
String string="";
for(int i=0;i<dept;i++){
string+="-";
}
System.out.println(string+name);
}
@Override
public void LineOfDuty() {
System.out.println("公司财务管理"+name);
}
}
//客户端
public class Show {
public static void main(String[] args) {
ConcreteCompany root=new ConcreteCompany("总公司");
root.Add(new HRDepartment("总公司人力资源部"));
root.Add(new FinanceDepartment("总公司财务部门"));
ConcreteCompany company=new ConcreteCompany("分公司1");
company.Add(new HRDepartment("分公司1人力资源部"));
company.Add(new FinanceDepartment("分公司1财务部门"));
root.Add(company);
ConcreteCompany company2=new ConcreteCompany("分公司1");
company2.Add(new HRDepartment("分公司1人力资源部"));
company2.Add(new FinanceDepartment("分公司1财务部门"));
root.Add(company2);
ConcreteCompany company3=new ConcreteCompany("分公司1");
company3.Add(new HRDepartment("分公司1人力资源部"));
company3.Add(new FinanceDepartment("分公司1财务部门"));
root.Add(company3);
root.Display(1);
}
}
结果:
四、总结
(1)、通过使用组合模式,可以解决整体与部分被一致对待的问题,如公司管理系统实例中,通过组合模式使得子公司和总公司一样都具有财务部,人力资源部这两部分。
(2)、组合模式有透明方式和安全方式两种,上述采用的是透明方式,所谓透明方式就是Leaf叶子节点和Composite枝节点具有完全一致的行为接口,但实际上Leaf叶子节点不应该有Add(),Remove()这样的方法的,因此在叶子节点中实现了这两个方法是完全没有意义的。而安全方式就是不在Component中声明Add(),Remove()这样的方法,但是在客户端调用时需要相应的判断(区分叶子节点和枝节点),如果是实现了相同接口的话,就不用这么麻烦了。
I know someone in the world is waiting for me, although I’ve no idea of who he is. But I feel happy every day for this.