设计模式----组合模式
组合模式也叫合成模式,用来描述部分和整体的关系。
组合模式,也是很多人没有听说过的,那就不妨了解一下。
其实组合模式就是上级管理下级的关系模式,比如说经理可以管理几个员工,他是有增删改查功能,而经理也是被总经理管理。。。
一.组合模式的现实场景:我的设计
王小华大学毕业后到公司实习,实习岗位是软件开发。某个项目正好有个功能需要有人开发,领导便把这个任务分配給他。功能需求是统计全公司的员工信息,要按照部门、级别展示出来,达到既可以查看某个人的信息,又可以查看某部门员工信息的效果。王小华用树结构把公司的层次框架和人员信息设计出来,领导很满意。
在上面的场景中,项目的功能实现用到了设计模式中的组合模式。对公司某个人的信息统计和对部门所有员工的信息统计用到的方法是一样的,用树状结构和递归方法就可以统计出所有人的信息,同时还能清晰地体现公司的组织构架。
二.组合模式(Composite Pattern)的定义
将对象组合成树状结构以表示“部分-整体”的层次结构。使得用户对单个对象和组合对象的使用具有一致性。
三.组合模式的类图
四.组合模式的三个角色
1.抽象组件(Component)角色
该角色定义参加组合的对象的共有方法和属性,规范一些默认的行为接口。
2.叶子构件(Leaf)角色
该角色是叶子对象,其下没有其他的分支,定义出参加组合的原始对象的行为。
3.树枝构件(Composite)角色
该角色代表参加组合的、其下有分支的树枝对象,它的作用是将树枝和叶子组合成一个树形结构,并定义出管理子对象的方法,如add()、remove()等等。
五.组合模式的优缺点
优点:
1.高层模块调用简单。
一棵树形机构中的所有节点都是Component,局部和整体对调用者来说没有任何区别,即高层模块不必关心自己处理的是单个对象还是整个组合结构,简化了高层模块的代码。
2.节点*增加
使用组合模式后,如果想增加树枝节点、树叶节点,只需找到父节点即可。
缺点:
1.不易控制树枝构件的类型。
2.不易使用继承的方法来增加新的行为。
六.组合模式的使用场景
1.需要描述对象的部分和整体之间的等级结构关系,如树形菜单、文件和文件夹管理等等
2.需要客户端忽略个体和组合构件的区别,平等对待所有的构件。
组合模式在java和android源码中也是有不少的应用的,比如List框架,就用到了组合模式原理,实现了增删改查功能,局部和个体的各种操作都可以实现。
组合模式的实例
这里就以上面查看一个公司的架构和公司每个员工的信息为示例,创建对应代码。
实例类图
实例代码
1.抽象类:Company
package p9_composite;
import java.util.ArrayList;
/**
* 公司的抽象类,也可以写成接口.
*/
public abstract class Company {
ArrayList<Company> companyArrayList = new ArrayList<>();
String name;//姓名
String sex;//性别
String position;//职位
int salary;//薪水
//获取信息
public abstract String getInfo();
}
2.树节点类:ConcreteCompany
package p9_composite;
import java.util.ArrayList;
/**
* 树节点类,可以对分支节点进行增删改查等操作
*/
public class ConcreteCompany extends Company {
//构造函数,这里创建的是一个树节点,但是也是有支节点的基本属性
public ConcreteCompany(String name, String sex, String posion, int salary) {
this.name = name;
this.sex = sex;
this.position = posion;
this.salary = salary;
}
/**
* 增加:添加应给支节点
* <p>
* 这里看起来是添加Company接口对象,但是你后面用子类的实例化,实际添加的就是子类的实例
*/
public void add(Company company) {
companyArrayList.add(company);
}
/**
* 删除:删除某一个节点数据
* <p>
* 当然你也可多加其他的删除功能,你让删除某一类,或删除全部子节点数据等等
*/
public void remove(Company company) {
companyArrayList.remove(company);
}
/**
* 查询所有子节点的数据
* 返回的是子节点集合对象
*/
public ArrayList<Company> getChild() {
return companyArrayList;
}
//修改这里就不做了,有兴趣可以高一下
/**
* 树节点本身属性数据
*/
@Override
public String getInfo() {
String info = "领导: 名称:" + name + ", 性别:" + sex + ", 职位:" + position + ", 薪水:" + salary;
return info;
}
}
3.叶子节点类:Employee
package p9_composite;
/**
* 叶子节点类
* 被上级的树节点管理
* 这里叶子节点没有什么权力,只能创建自己和看看自己的信息
*/
public class Employee extends Company {
//构造函数,这里创建的是一个叶子节点,并设置基本属性
public Employee(String name, String sex, String posion, int salary) {
this.name = name;
this.sex = sex;
this.position = posion;
this.salary = salary;
}
/**
* 叶子节点本身属性数据
*/
@Override
public String getInfo() {
String info = "下属: 名称:" + name + ", 性别:" + sex + ", 职位:" + position + ", 薪水:" + salary;
return info;
}
}
4.组合模式测试类:CompositeDemo
package p9_composite;
/**
* 组合模式的使用示例
*/
public class CompositeDemo {
public static void main(String[] arg) {
//CEO
ConcreteCompany root = new ConcreteCompany("李文志", "男", "CEO", 100 * 1000);
//部门经理,既是树节点,也是上级的子节点
ConcreteCompany developDep = new ConcreteCompany("卢康", "男", "研发部经理", 10 * 1000);
ConcreteCompany salesDep = new ConcreteCompany("蔡良梁", "男", "销售经理", 11 * 1000);
ConcreteCompany finaceDep = new ConcreteCompany("习伟", "男", "财务经理", 12 * 1000);
//把三个经理添加到公司框架中
root.add(developDep);
root.add(salesDep);
root.add(finaceDep);
//部门员工
Employee e1 = new Employee("A", "男", "研发部", 6000);
Employee e2 = new Employee("B", "男", "研发部", 6000);
Employee e3 = new Employee("C", "男", "研发部", 6000);
Employee e4 = new Employee("D", "男", "销售部", 6000);
Employee e5 = new Employee("E", "男", "销售部", 6000);
Employee e6 = new Employee("F", "男", "销售部", 6000);
Employee e7 = new Employee("G", "男", "财务部", 6000);
Employee e8 = new Employee("H", "男", "财务部", 6000);
//把底层员工添加到特定的区域
developDep.add(e1);//研发部门
developDep.add(e2);
developDep.add(e3);
salesDep.add(e4);//销售部门
salesDep.add(e5);
salesDep.add(e6);
finaceDep.add(e7);//财务部门
finaceDep.add(e8);
//公司的框架已经完成,并添加如数据
//可以进行后续的操作
System.out.println("" + root.getInfo());//查询最大的Boss情况
display(root);//查询整个公司所有人员的情况,所有子节点的数据
}
//遍历打印数据
private static void display(ConcreteCompany root) {
for (Company c : root.getChild()) {
if (c instanceof Employee) {//如果节点类型是子节点
System.out.println(c.getInfo());//查询,打印
} else {//如果节点类型是树节点
System.out.println("\n" + c.getInfo());//查询,打印树节点
display((ConcreteCompany) c);//再递归调用,打印里面的子节点
}
}
}
}
程序运行结果显示:
其实你跟别人说组合设计模式,只要说到是整体和部分的关系,并且树节点可以对子节点进行增删改查等操作就表示你有一些理解了。
上一篇: CAD2014中多个任务栏怎么合并?
下一篇: MAYA分层渲染功能完全解析