设计模式/重构/UML建模|设计模式系列(组合模式)

一.名称 二.问题(为了解决什么问题) 比较好辨别,因为使用范围很窄

  • 当有一个结构可以组合成树形结构,且需要向客户端提供一致的操作接口,使得客户端操作忽略简单元素与复杂元素,如维护和展示部分-整体关系的场景,如树形菜单、文件和文件夹管理。
  • 从一个整体中能够独立出部分木块或功能的场景。
  • 当有一个结构可以组合成树形结构,且需要向客户端提供一致的操作接口,使得客户端操作忽略简单元素与复杂元素
三.解决方案(主要体现在uml和核心代码上)
组合模式也叫作部分-整体模式,主要来描述部分与整体的关系。官方定义:将对象组合成树形结构以表示部分-整体的层次结构,使得用户对单个对象和组合对象的使用具有一致性。组合模式的要点在于:提取共同点作为基类,把不同点作为子类
类图 设计模式/重构/UML建模|设计模式系列(组合模式)
文章图片

我们来说说组合模式的几个角色:
Component抽象构件角色:定义参加组合对象的共有方法和属性,可以定义一些默认的行为或属性,比如我们例子中的getInfo就封装到了抽象类中。
Leaf叶子构件:叶子对象,其下再也没有其他的分支,也就是遍历的最小单位。
Composite树枝构件:树枝对象,它的作用是组合树枝节点和叶子节点形成一个树形结构。
通用代码:
设计模式/重构/UML建模|设计模式系列(组合模式)
文章图片

设计模式/重构/UML建模|设计模式系列(组合模式)
文章图片

设计模式的扩展
  1. 透明的组合模式、安全的组合模式
  2. 为了解决问题:比如组织结构这棵树,我从中抽取一个用户,要找到它的上级有哪些,下级有哪些,怎么处理?
    解决方案:在基类中增加两个方法:setParent是设置父节点是谁,getParent是查找父节点是谁。
【设计模式/重构/UML建模|设计模式系列(组合模式)】组合模式体现了:开闭原则,里氏替换原则,依赖倒置原则
因为使用了抽象类——开闭原则
因为使用了抽象类——里氏替换原则
因为使用了抽象类和继承——依赖倒置原则
四.例子 一个公司有ceo,经理,员工,描述一下这个树形结构。
基类节点:
/** * Created by annuoaichengzhang on 16/3/25. */ 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() { return "姓名:" + this.name + "\t职位:" + this.position + "\t薪资:" + this.salary; } }

子类节点:
/** * Created by annuoaichengzhang on 16/3/25. */ public class Branch extends Corp { private ArrayList subordinateList = new ArrayList<>(); public Branch(String name, String position, int salary) { super(name, position, salary); }public void addSubordinate(Corp corp) { this.subordinateList.add(corp); }public ArrayList getSubordinateList() { return this.subordinateList; } }

/** * Created by annuoaichengzhang on 16/3/25. */ public class Leaf extends Corp {public Leaf(String name, String position, int salary) { super(name, position, salary); } }

client:
public class Client { public static void main(String[] args) { Root ceo = new Root("王大麻子", "总经理", 100000); IBranch developDep = new Branch("lisi", "研发部经理", 20000); IBranch salesDep = new Branch("wangwu", "销售部经理", 20000); IBranch firstZuZhang = new Branch("zuzhang1", "开发组长1", 5000); IBranch secondZuZhang = new Branch("zuzhang2", "开发组长2", 5000); ILeaf a = new Leaf("a", "开发人员", 2000); ILeaf b = new Leaf("b", "开发人员", 2000); ILeaf c = new Leaf("c", "开发人员", 2000); ILeaf d = new Leaf("d", "开发人员", 2000); ceo.add(developDep); ceo.add(salesDep); developDep.add(firstZuZhang); developDep.add(secondZuZhang); firstZuZhang.add(a); firstZuZhang.add(b); secondZuZhang.add(c); secondZuZhang.add(d); } }

四.效果(有啥优缺点) 设计模式/重构/UML建模|设计模式系列(组合模式)
文章图片

常见案例
杀毒软件。遍历每个文件,为不同类型的文件格式提供不同的杀毒方式。
?
界面控制库。界面控件分为两大类:一类是单元控件,例如按钮、文本框等,另一类是容器控件,例如窗体、中间面板灯。试用组合模式设计该界面控件库。

    推荐阅读