一、组合模式概念
组合模式: (整体与部分关系)将对象组合成树形结构以表示“部分-整体”的层次结构,组合模式使得用户对单个对象和组合对象的使用具有一致性。掌握组合模式的重点是要理解清楚 “部分/整体” 还有 ”单个对象“ 与 "组合对象" 的含义。
涉及角色:
- 1.Component 是组合中的对象声明接口,在适当的情况下,实现所有类共有接口的默认行为。声明一个接口用于访问和管理Component子部件。
- 2.Leaf 在组合中表示叶子结点对象,叶子结点没有子结点。
- 3.Composite 定义有枝节点行为,用来存储子部件,在Component接口中实现与子部件有关操作,如增加(add)和删除(remove)等。
二、组合模式通用类图
component (抽象构件:容器): 它可以是接口或者抽象类,为叶子构建和子容器构建对象声明接口,在该角色中可以包含所有子类共有的行为的实现和声明。在抽象构建中定义了访问及管理它的子构件的方法,如增加子构件,删除子构件,获取子构件等。
leaf(叶子构建): 叶子构建可以说就是各种类型的文件!叶子构建没有子构件。它实现了抽象构建中的定义的行为。对于那些访问子容器,删除子容器,增加子容器的就报错。
compsite(子容器构建): 它在组合模式中表示容器节点对象,容器结点是子节点,可以是子容器,也可以是叶子构建,它提供一个集合来存储子节点。
首先写抽象构件:
package com.ssy.wlj.composite2;
/**
* 抽象构件
*
* @author Administrator
* @since 2019/05/23
*
*/
public abstract class Component {
protected String name;
public Component(String name) {
this.name = name;
}
public Component() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
// 这个是容器类的抽象类,定义好行为,定义创建移除子容器的方法抽象的。
public abstract void addComposite(Component c); // 添加成员
public abstract void removeComposite(Component c);// 移除成员
public abstract Component getComposite(int i);// 获取子容器
public abstract void operation(int depth);// 业务方法
}
写子容器构件:
package com.ssy.wlj.composite2;
import java.util.ArrayList;
/**
* 子容器构建
*
* @author Administrator
* @since 2019/05/23
*
*/
public class Composite extends Component {
// 首先来一个存储的集合
private ArrayList<Component> list;
public Composite(String name) {
super(name);
list = new ArrayList<Component>();
}
public Composite() {
list = new ArrayList<Component>();
}
@Override
public void addComposite(Component c) {
list.add(c);
}
@Override
public void removeComposite(Component c) {
list.remove(c);
}
@Override
public Component getComposite(int c) {
Component c1 = list.get(c);
return c1;
}
@Override
public void operation(int depth) {
StringBuilder sb = new StringBuilder("");
for (int i = 0; i < depth; i++) {
sb.append("-");
}
System.out.println(new String(sb) + this.getName());
for (Component c : list) {
c.operation(depth + 2);
}
}
}
叶子构件:
package com.ssy.wlj.composite2;
/**
* 叶子构建
*
* @author Administrator
* @since 2019/05/23
*
*/
public class Leaf extends Component {
public Leaf(String name) {
super(name);
}
// 首先重写component的方法
// 叶子节点关键点在于业务
@Override
public void operation(int depth) {
StringBuilder sb = new StringBuilder("");
for (int i = 0; i < depth; i++) {
sb.append("-");
}
System.out.println(new String(sb) + this.getName());
}
public Component addComponent(int c) {
System.out.print("不是子容器");
return null;
}
@Override
public void addComposite(Component c) {
System.out.print("不是子容器");
}
@Override
public void removeComposite(Component c) {
System.out.print("不是子容器");
}
@Override
public Component getComposite(int i) {
System.out.print("不是子容器");
return null;
}
}
最后写个测试类:
package com.ssy.wlj.composite2;
public class Client {
public static void main(String[] args) {
Component root = new Composite("zs");
root.addComposite(new Leaf("a"));
root.addComposite(new Leaf("b"));
Component file = new Composite("ls");
file.addComposite(new Leaf("c"));
file.addComposite(new Leaf("d"));
root.addComposite(file);
root.operation(1);
}
}
三、组合模式场景展示
这里以公司的组织机构为例,公司分为人力资源部、财务部等。
类图如下:
首先创建公司抽象类:
package com.ssy.wlj.composite;
/**
* 抽象接口类:用来管理子类
* @author Administrator
* @since 2019/05/23
*
*/
public abstract class Company {
// 公司名称
private String name;
public Company(String name) {
super();
this.name = name;
}
public Company() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
// 添加公司如:新增分公司
protected abstract void add(Company company);
// 删除公司:如因故关闭分公司
protected abstract void romove(Company company);
//显示公司所在的层级:总公司,分公司,办事处等
protected abstract void display(int depth);
}
创建分公司类:
package com.ssy.wlj.composite;
import java.util.ArrayList;
import java.util.List;
/**
* 分公司对象
* @author Administrator
* @since 2019/05/23
*
*/
public class ConcreteCompany extends Company {
private List<Company> cList;
public ConcreteCompany() {
cList = new ArrayList();
}
public ConcreteCompany(String name) {
super(name);
cList = new ArrayList();
}
@Override
protected void add(Company company) {
cList.add(company);
}
@Override
protected void display(int depth) {
StringBuilder sb = new StringBuilder("");
for (int i = 0; i < depth; i++) {
sb.append("-");
}
System.out.println(new String(sb) + this.getName());
for (Company c : cList) {
c.display(depth + 2);
}
}
@Override
protected void romove(Company company) {
cList.remove(company);
}
}
创建Leaf节点:公司人力资源部门
package com.ssy.wlj.composite;
/**
* Leaf结点类:公司人力资源部门
* @author Administrator
* @since 2019/05/23
*
*/
public class HRDepartment extends Company {
public HRDepartment(String name) {
super(name);
}
@Override
protected void add(Company company) {
}
@Override
protected void display(int depth) {
StringBuilder sb = new StringBuilder("");
for (int i = 0; i < depth; i++) {
sb.append("-");
}
System.out.println(new String(sb) + this.getName());
}
@Override
protected void romove(Company company) {
}
}
创建Leaf节点:公司财务部门
package com.ssy.wlj.composite;
/**
* Leaf结点类:公司财务部门
* @author Administrator
* @since 2019/05/23
*
*/
public class FinanceDepartment extends Company {
public FinanceDepartment(String name) {
super(name);
}
@Override
protected void add(Company company) {
}
@Override
protected void display(int depth) {
StringBuilder sb = new StringBuilder("");
for (int i = 0; i < depth; i++) {
sb.append("-");
}
System.out.println(new String(sb) + this.getName());
}
@Override
protected void romove(Company company) {
}
}
最后编写测试类:
package com.ssy.wlj.composite;
public class Client {
public static void main(String[] args) {
Company root = new ConcreteCompany();
root.setName("北京总公司");
root.add(new HRDepartment("总公司人力资源部"));
root.add(new FinanceDepartment("总公司财务部"));
Company shandongCom = new ConcreteCompany("山东分公司");
shandongCom.add(new HRDepartment("山东分公司人力资源部"));
shandongCom.add(new FinanceDepartment("山东分公司账务部"));
Company zaozhuangCom = new ConcreteCompany("枣庄办事处");
zaozhuangCom.add(new FinanceDepartment("枣庄办事处财务部"));
zaozhuangCom.add(new HRDepartment("枣庄办事处人力资源部"));
Company jinanCom = new ConcreteCompany("济南办事处");
jinanCom.add(new FinanceDepartment("济南办事处财务部"));
jinanCom.add(new HRDepartment("济南办事处人力资源部"));
shandongCom.add(jinanCom);
shandongCom.add(zaozhuangCom);
Company huadongCom = new ConcreteCompany("上海华东分公司");
huadongCom.add(new HRDepartment("上海华东分公司人力资源部"));
huadongCom.add(new FinanceDepartment("上海华东分公司账务部"));
Company hangzhouCom = new ConcreteCompany("杭州办事处");
hangzhouCom.add(new FinanceDepartment("杭州办事处财务部"));
hangzhouCom.add(new HRDepartment("杭州办事处人力资源部"));
Company nanjingCom = new ConcreteCompany("南京办事处");
nanjingCom.add(new FinanceDepartment("南京办事处财务部"));
nanjingCom.add(new HRDepartment("南京办事处人力资源部"));
huadongCom.add(hangzhouCom);
huadongCom.add(nanjingCom);
root.add(shandongCom);
root.add(huadongCom);
//如果还需要新增分公司或办事处等,就继续按照上述操作处理
root.display(0);
}
}
运行测试效果:
北京总公司
--总公司人力资源部
--总公司财务部
--山东分公司
----山东分公司人力资源部
----山东分公司账务部
----济南办事处
------济南办事处财务部
------济南办事处人力资源部
----枣庄办事处
------枣庄办事处财务部
------枣庄办事处人力资源部
--上海华东分公司
----上海华东分公司人力资源部
----上海华东分公司账务部
----杭州办事处
------杭州办事处财务部
------杭州办事处人力资源部
----南京办事处
------南京办事处财务部
------南京办事处人力资源部