我学设计模式之合成模式
1. 简介
合成模式属于对象的结构模式,有时又叫做 部分 – 整体模式。合成模式将对象组织到树结构中,可以用来描述整体与部分的关系。
合成模式把部分和整体的关系用树结构表示出来。合成模式使得客户端把一个个单独的成分对象和有他们复合而成的合成对象同等看待。
2. 组合模式的结构
先给出合成模式的简单类图如下:
从类图中可以看出合成模式涉及3个角色:
抽象构件角色(Component):这是一个抽象角色,他给参加组合的对象规定一个接口,这个角色给出共有的接口及其默认行为。
树叶构件角色(Leaf):代表参加组合的树叶对象。一个树叶没有下级的子对象。定义出参加原始对象的行为。
树枝构件角色(Composite):代表参加组合的有子对象的对象,并给出树枝构件对象的行为。
3. 安全和透明式的合成模式
合成模式的实现根据实现接口的区别分为两种形式,分别为安全式和透明式。他们的类图分别如下:
透明方式:就是在Component里面声明所有的用来管理子对象的方法,包括add()、remove()以及getChild()方法,这样做的好处是所有的构件类都有相同的接口。在客户端看来,树叶类对象与合成类对象的区别起码在接口层次上消失了,客户端可以同等的对待所有的对象。这就是透明形式的合成模式。
这个选择的缺点是不够安全的,因为树叶类对象和合成类对象在本质上是有区别的,树叶类对象不可能有一层的对象,因此add()、remove()以及getChild()方法没有意义,但是在编译时期不会出错,而只会在运行时期才会出错。
安全方式:是在Composite类里面声明所有的用来管理子类对象的方法。这样的做法是安全的做法,因为树叶类型的对象根本就没有管理子对象的方法。因此,如果客户端对树叶对象使用这些方法时会在编译时期出错。编译不通过,就不会出现运行时出错。
这个选择的缺点是不够透明,因为树叶类和合成类将具有不同的接口。
4. 组合模式的用法
在这里使用组合模式对公司人事管理的树状机构进行描述:
首先创建抽象构建,源代码如下:
package com.zsw.composite;
public abstract class Corp {
private String name; //名称 private String position; //职位 private int salary = 0; //薪水
public Corp(String name,String position,int salary){ this.name = name; this.position = position; this.salary = salary; }
public String getInfo(){ String info = ""; info = "姓名:" + this.name; info = info + "/t职位:" + this.position; info = info + "/t薪水: " + this.salary; return info; } } |
创建树叶构件源代码如下:
package com.zsw.composite;
public class Leaf extends Corp {
public Leaf(String name, String position, int salary) { super(name, position, salary); } } |
创建树枝构件源代码如下:
package com.zsw.composite; import java.util.ArrayList; public class Branch extends Corp {
ArrayList<Corp> subordinateList = new ArrayList<Corp>();
public Branch(String name, String position, int salary) { super(name, position, salary); }
public void addSubordinate(Corp corp){ this.subordinateList.add(corp); }
public ArrayList<Corp> getSubordinate(){ return this.subordinateList; } }
|
客户端源代码如下:
package com.zsw.composite; import java.util.ArrayList; public class Client {
public static void main(String[] args) { Branch ceo = compositeCorpTree(); System.out.println(ceo.getInfo()); System.out.println(getTreeInfo(ceo)); }
//把整个树组装出来 public static Branch compositeCorpTree(){ //总经理CEO Branch root = new Branch("王大","总经理",100000);
//三个部门经理 Branch developDep = new Branch("刘大","研发部门经理",10000); Branch salesDep = new Branch("刘大","销售部门经理",20000); Branch financeDep = new Branch("刘大","财务部门经理",30000);
//二个小组长 Branch firstDevGroup = new Branch("杨三","开发一组组长",5000);
|