组合模式
定义
组合模式(Composite Pattern)又称为合成模式、部分-整体模式(Part-Whole),主要用来描述部分与整体的关系。
定义:将对象组合成树形结构以表示“部分-整体”的层次结构,使用户对单个对象和组合对象的使用具有一致性
组合模式的优点、缺点、使用场景
优点
- 高层模型调用简单。一棵树形结构中所有节点都一视同仁,高层模型不必关心自己处理的是单个对象还是整个组合结构,简化了高层模块的代码
- 节点自由增加
使用组合模式后,想增加一个树枝节点、叶子节点是简单的,只要找到它的父节点即可,拓展性很强。且符合开闭原则,对以后的维护非常有利
缺点
定义节点时使用的是节点实现类,会与依赖倒置原则冲突,限制了接口的使用范围。例如入口类中各个节点都是定义为实现类的类型
使用场景
- 如树形菜单、文件、文件夹管理
- 从一个整体中独立出部分模块或功能的场景
UML
运行结果
输入:root节点
输入:Branch节点
输入:Leaf节点
代码实现
Root根节点的接口、实现、个性
public interface IRoot<R extends RootModel, B extends BranchModel, L extends LeafModel> extends ICorp<R> {
/**
* 总经理添加部门经理
*
* @param branch 分支节点
*/
void add(B branch);
/**
* 总经理添加部门员工
*
* @param leaf 叶子结点
*/
void add(L leaf);
/**
* 部门经理遍历下属
*
* @return
*/
List<Object> getSubordinateInfo();
}
public class Root<R extends RootModel, B extends BranchModel, L extends LeafModel> extends RootModel implements IRoot<R, B, L> {
/**
* 下属列表
*/
private final List<Object> subordinateList = new ArrayList<>();
public Root(String name, String position, double salary) {
super(name, position, salary);
}
@Override
public R getInfo() {
return (R) this;
}
@Override
public void add(B branch) {
subordinateList.add(branch);
}
@Override
public void add(L leaf) {
subordinateList.add(leaf);
}
@Override
public List<Object> getSubordinateInfo() {
return subordinateList;
}
@Override
public String toString() {
return "name: " + this.name + "\t" + "position: " + this.position + "\t" + this.salary;
}
}
public class RootModel extends Corps {
public RootModel(String name, String position, double salary) {
super(name, position, salary);
}
}
Branch分支节点的接口、实现、个性
public interface IBranch<B extends BranchModel, L extends LeafModel> extends ICorp<B> {
/**
* 添加部门
*
* @param branch 分支节点
*/
void add(B branch);
/**
* 添加部门下的员工
*
* @param leaf 叶子结点
*/
void add(L leaf);
/**
* 部门经理获取下属信息
*
* @return 下属信息列表
*/
List<Object> getSubordinateInfo();
}
public class Branch<B extends BranchModel, L extends LeafModel> extends BranchModel implements IBranch<B, L> {
/**
* 下属列表
*/
private final List<Object> subordinateList = new ArrayList<>();
public Branch(String name, String position, double salary) {
super(name, position, salary);
}
@Override
public B getInfo() {
return (B) this;
}
@Override
public void add(B branch) {
subordinateList.add(branch);
}
@Override
public void add(L leaf) {
subordinateList.add(leaf);
}
@Override
public List<Object> getSubordinateInfo() {
return subordinateList;
}
@Override
public String toString() {
return "name: " + this.name + "\t" + "position: " + this.position + "\t" + this.salary;
}
}
public class BranchModel extends Corps {
public BranchModel(String name, String position, double salary) {
super(name, position, salary);
}
}
Leaf叶子结点接口、实现、个性
public interface ILeaf<L extends LeafModel> extends ICorp<L> {
}
public class Leaf<L extends LeafModel> extends LeafModel implements ILeaf<L> {
public Leaf(String name, String position, double salary) {
super(name, position, salary);
}
@Override
public L getInfo() {
return (L) this;
}
@Override
public String toString() {
return "name: " + this.name + "\t" + "position: " + this.position + "\t" + this.salary;
}
}
public class LeafModel extends Corps {
public LeafModel(String name, String position, double salary) {
super(name, position, salary);
}
}
所有员工的公共信息接口、抽象类
public interface ICorp<T> {
/**
* 获取员工信息
*
* @return 员工信息
*/
T getInfo();
}
public abstract class Corps {
/**
* 名称
*/
protected String name;
/**
* 职位
*/
protected String position;
/**
* 薪水
*/
protected double salary;
protected Corps(String name, String position, double salary) {
this.name = name;
this.position = position;
this.salary = salary;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPosition() {
return position;
}
public void setPosition(String position) {
this.position = position;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
}
帮助类
public class SubordinateHelper {
/**
* 遍历该节点
* 只有Root和Branch节点才有下属,Leaf没有下属
*
* @param node 节点
*/
public static <T extends ICorp<R>, R> void getAllSubordinateInfo(T node) {
printCurrentInfo(node);
if (node instanceof BranchModel) {
IBranch<BranchModel, LeafModel> branch = (IBranch<BranchModel, LeafModel>) node;
iterateSubordinateList(branch.getSubordinateInfo());
} else if (node instanceof RootModel) {
IRoot<RootModel, BranchModel, LeafModel> root = (IRoot<RootModel, BranchModel, LeafModel>) node;
iterateSubordinateList(root.getSubordinateInfo());
}
}
/**
* 遍历下属列表
*
* @param subordinateList 下属列表
*/
private static void iterateSubordinateList(List<Object> subordinateList) {
for (Object subordinate : subordinateList) {
// 如果是叶子结点,也就是员工
if (subordinate instanceof LeafModel) {
ILeaf<LeafModel> leaf = (ILeaf<LeafModel>) subordinate;
System.out.println("\t\t" + leaf.getInfo());
} else if (subordinate instanceof BranchModel) {
// 如果是分支节点,则递归遍历
IBranch<BranchModel, LeafModel> branch = (IBranch<BranchModel, LeafModel>) subordinate;
System.out.println("\t" + branch.getInfo());
iterateSubordinateList(branch.getSubordinateInfo());
}
}
}
/**
* 打印当前节点的信息
*
* @param root 当前节点
* @param <T> 当前节点的类型,IRoot、IBranch、ILeaf
* @param <R> 节点的个性类型,RootModel、BranchModel、LeafModel
*/
private static <T extends ICorp<R>, R> void printCurrentInfo(T root) {
System.out.println(root.getInfo());
}
}
入口类
public class CompositePatternMain {
public static void main(String[] args) {
// 生产一个总经理
Root<RootModel, BranchModel, LeafModel> root = new Root<>("王总", "总经理", 100000d);
// 生产个秘书
Leaf<LeafModel> secretary = new Leaf<>("小蓝", "总经理秘书", 20000);
// 生产三个部门经理
Branch<BranchModel, LeafModel> liuBranch = new Branch<>("刘经理", "研发部门经理", 30000);
Branch<BranchModel, LeafModel> zhangBranch = new Branch<>("张经理", "销售部门经理", 31000);
Branch<BranchModel, LeafModel> heBranch = new Branch<>("何经理", "财务部门经理", 32000);
// 生产个研发部门副经理
Leaf<LeafModel> zhengBranch = new Leaf<>("郑副经理", "研发部门副经理", 20000);
// 生产几个小组长
Branch<BranchModel, LeafModel> wuBranch = new Branch<>("吴工", "研发一组组长", 10000);
Branch<BranchModel, LeafModel> liBranch = new Branch<>("李工", "研发二组组长", 11000);
Branch<BranchModel, LeafModel> songBranch = new Branch<>("宋工", "销售一组组长", 12000);
Branch<BranchModel, LeafModel> liangBranch = new Branch<>("梁工", "销售二组组长", 13000);
Branch<BranchModel, LeafModel> zhouBranch = new Branch<>("周工", "财务一组组长", 14000);
Branch<BranchModel, LeafModel> zhaoBranch = new Branch<>("赵工", "财务二组组长", 15000);
// 生产员工
Leaf<LeafModel> a = new Leaf<>("A", "研发一组人员", 3000);
Leaf<LeafModel> b = new Leaf<>("B", "研发一组人员", 3000);
Leaf<LeafModel> c = new Leaf<>("C", "研发一组人员", 3000);
Leaf<LeafModel> d = new Leaf<>("D", "研发二组人员", 3000);
Leaf<LeafModel> e = new Leaf<>("E", "研发二组人员", 3000);
Leaf<LeafModel> f = new Leaf<>("F", "研发二组人员", 3000);
Leaf<LeafModel> g = new Leaf<>("G", "销售一组人员", 3000);
Leaf<LeafModel> h = new Leaf<>("H", "销售一组人员", 3000);
Leaf<LeafModel> i = new Leaf<>("I", "销售二组人员", 3000);
Leaf<LeafModel> j = new Leaf<>("J", "财务一组人员", 3000);
Leaf<LeafModel> k = new Leaf<>("K", "财务二组人员", 3000);
// 总经理管理部门经理
root.add(liuBranch);
root.add(zhangBranch);
root.add(heBranch);
// 总经理管理秘书
root.add(secretary);
// 研发、销售、财务部门组长管理
liuBranch.add(wuBranch);
liuBranch.add(liBranch);
liuBranch.add(zhengBranch);
zhangBranch.add(songBranch);
zhangBranch.add(liangBranch);
heBranch.add(zhouBranch);
heBranch.add(zhaoBranch);
// 研发部门员工管理
wuBranch.add(a);
wuBranch.add(b);
wuBranch.add(c);
liBranch.add(d);
liBranch.add(e);
liBranch.add(f);
// 销售部门员工管理
songBranch.add(g);
songBranch.add(h);
liangBranch.add(i);
// 财务部门员工管理
zhouBranch.add(j);
zhaoBranch.add(k);
// 遍历节点
SubordinateHelper.getAllSubordinateInfo(a);
}
}