在开发中存在不少总体和部分的关系,这个方式最大的体现就是树形结构。组合模式就是为了更好地解决这类业务场景的问题。先看下组合模式的定义:ide
将对象组合成树形结构以表示“总体—部分”的层次关系。组合模式使得用户对单个对象和组合对象的使用具备一致性。从定义中能够看出来组合二模式主要有两点; this
一、总体 - 部分 之间业务结构用树形表示。spa
二、让组合对象和各个对象的使用具备一致性。code
总体和部分的结构在生活中太普遍了,好比国家行政级别 中国 ,***省,**市 。学校管级别、公司管理组织机构等,下面以公司组织机构为例,来看看组合模式。对象
根据这个公司组织结构的图片,来引进助兴结构的专业名词:总经理称之为 root 根节点,财务经理、技术经理、开发组长称之为 树枝节点(branch),财务专员、秘书称之为 叶子节点(leaf)。blog
而具体到代码的实现层面就是,组合模式的核心关键就是把这三个对象实现相同的接口,无论是在组件过程,仍是后面的遍历,全部的节点都用相同的接口,使得对树形结构的操做更加方便。继承
接着介绍组合模式的组成元素接口
接下来吧上图中例子实现如下,可以更直观了解组合模式图片
// 至关因而 Component public abstract class Zhiwei { protected String name; protected String position; protected float salary; public Zhiwei(String name,String position,float salary){ this.name = name; this.position = position; this.salary = salary; } public abstract void addChild(Zhiwei zhiwei); public abstract void removeChild(Zhiwei zhiwei); public abstract void display(String empty); } //至关因而 Composite public class LingDao extends Zhiwei { private ArrayList<Zhiwei> children = new ArrayList<Zhiwei>(); public LingDao(String name,String position,float salary){ super(name,position,salary); } @Override public void addChild(Zhiwei zhiwei) { // TODO Auto-generated method stub children.add(zhiwei); } @Override public void removeChild(Zhiwei zhiwei) { // TODO Auto-generated method stub children.remove(zhiwei); } @Override public void display(String empty) { // TODO Auto-generated method stub System.out.println(empty+"职位:"+this.position+" 姓名:"+this.name+" 薪水:"+this.salary); for (Zhiwei zhiwei : children) { zhiwei.display(empty+" "); } } } //普通职员 public class Leaf extends Zhiwei { public Leaf(String name, String position, float salary) { super(name, position, salary); // TODO Auto-generated constructor stub } @Override public void addChild(Zhiwei zhiwei) { // TODO Auto-generated method stub System.out.println("cannot add zhiwei to leaf"); } @Override public void removeChild(Zhiwei zhiwei) { // TODO Auto-generated method stub } @Override public void display(String empty) { // TODO Auto-generated method stub System.out.println(empty+"职位:"+this.position+" 姓名:"+this.name+" 薪水:"+this.salary); } } //客户端 public class Client { public static void main(String[] args) { Zhiwei leader = new LingDao("张无忌","总经理",100000); Zhiwei manager = new LingDao("杨逍", "技术经理", 50000); Zhiwei managerB = new LingDao("范瑶","财务经理",50000); Zhiwei managerC = new LingDao("吴劲草","技术组长",20000); Zhiwei Employee = new LingDao("小昭","秘书",8000); Zhiwei EmployeeA = new LingDao("天字门","财务A",5000); Zhiwei EmployeeX = new LingDao("地字门","财务B",5200); Zhiwei EmployeeC = new LingDao("风字门","开发A",8800); Zhiwei EmployeeD = new LingDao("雷字门","开发B",8400); leader.addChild(manager); leader.addChild(managerB); leader.addChild(Employee); manager.addChild(managerC); manager.addChild(EmployeeC); managerC.addChild(EmployeeD); leader.display(""); } } /********************控制台************************/ - 职位:总经理 姓名:张无忌 薪水:100000.0 - 职位:技术经理 姓名:杨逍 薪水:50000.0 - 职位:技术组长 姓名:吴劲草 薪水:20000.0 - 职位:开发B 职位:雷字门 薪水:8400.0 - 职位:开发A 姓名:风字门 薪水:8800.0 - 职位:财务经理 姓名:范瑶 薪水:50000.0 - 职位:财务A 姓名:风字门 薪水:5000.0 - 职位:财务B 姓名:地字门 薪水:5200.0 - 职位:秘书 姓名:小昭 薪水:8000.0
经过这个例子能够看出来,不一样级别的节点经过同一接口在客户端试用是很是方便的,调用的时候不用管他表明的是什么节点。由于可以同一试用。只是在 leaf 级别的节点中,考虑 addChild 、removeChild 给出错误提示便可。开发
咱们进一步来分析组合模式的应用场景,除了在很明显的树形结构业务中用,在发挥咱们的发散能力,应该可以想到,只要拥有父子关系的场景中都是能够用的,好比窗体打开的父子窗口、各类单位的人事制度的组织结构、文件管理系统、软件系统的树形结构导航。
在思考了组合模式的应用场景后,在考虑下组合模式的优点:
一、定义了实现不一样层次的对象的统一接口,对象行为更具备一致性。使得客户端调用比较简单。
二、实现了整个业务场景的类层级的所属关系,经过类里面的 list 来实现。
三、类实现更具通常性,使得代码更具备可扩展性。主要表如今新定义的 composite 和 leaf 继承了统一的操做接口,客户端就不用改变。
组合模式应用场景是具备父子结构的场景,典型的就是树形结构。模式的本质就是对不一样级别的节点对象引入统一的接口,对不一样级别对象调用、操做具备了一致性。