一、组合模式概念
组合模式:(整体与部分关系)将对象组合成树形结构以表示“部分-整体”的层次结构,组合模式使得用户对单个对象和组合对象的使用具有一致性。掌握组合模式的重点是要理解清楚 “部分/整体” 还有 ”单个对象“ 与 "组合对象" 的含义。
涉及角色:
- 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); } }
运行测试效果:
北京总公司 --总公司人力资源部 --总公司财务部 --山东分公司 ----山东分公司人力资源部 ----山东分公司账务部 ----济南办事处 ------济南办事处财务部 ------济南办事处人力资源部 ----枣庄办事处 ------枣庄办事处财务部 ------枣庄办事处人力资源部 --上海华东分公司 ----上海华东分公司人力资源部 ----上海华东分公司账务部 ----杭州办事处 ------杭州办事处财务部 ------杭州办事处人力资源部 ----南京办事处 ------南京办事处财务部 ------南京办事处人力资源部