• 组合模式:

  允许你将对象组合成树形结构来表现“整体/部分”层次结构。组合能让客户以一致的方式处理个别对象以及对象组合。

  组合模式适用于创建复杂的对象,这个对象包含某些个别的对象以及这些对象的组合。

  从操作的角度而言,客户端对于 个别对象/组合 的操作是一致的。

  • 模拟场景

  如图所示,总公司下属有多个部门,而子公司可以视为多个部门的组合。

  整个数据结构呈树状,完美契合组合模式的应用场景。

  • UML:

  在这个场景中:

  1. 个别对象 -> 人事部(HRDepartment)和财务部(FinanceDepartment)
  2. 个别对象的组合 -> 公司(Company)
  3. 无论是 Company 还是 Department,对于 Client 而言,都被当做 CompanyItem 使用。
  4. 从树形结构来理解,Department 是叶节点,Company 是非叶节点。
  • 代码:
@Data
@AllArgsConstructor
@ToString
public abstract class CompanyItem { protected String name; protected void addCompanyItem(CompanyItem companyItem) {
throw new UnsupportedOperationException("Not support to add companyItem");
} protected void removeCompanyItem(CompanyItem companyItem) {
throw new UnsupportedOperationException("Not support to remove companyItem");
} protected abstract void lineOfDuty(); protected abstract void showStructure(int depth);
}
public final class Company extends CompanyItem {

    private List<CompanyItem> childCompanyItems = new ArrayList<>();

    public Company(String name) {
super(name);
} @Override
public void addCompanyItem(CompanyItem component) {
childCompanyItems.add(component);
} @Override
public void removeCompanyItem(CompanyItem component) {
childCompanyItems.remove(component);
} @Override
public void lineOfDuty() {
childCompanyItems.forEach(companyItem -> companyItem.lineOfDuty());
} @Override
public void showStructure(int depth) {
StringBuilder builder = new StringBuilder();
for (int i = 0; i < depth; ++i) {
builder.append("-");
}
System.out.println(builder.append(name));
childCompanyItems.forEach(companyItem -> companyItem.showStructure(depth + 1));
}
}
public final class FinanceDepartment extends CompanyItem {

    public FinanceDepartment(String name) {
super(name);
} @Override
public void lineOfDuty() {
System.out.println(name + ", treasurer is in charge of payroll");
} @Override
public void showStructure(int depth) {
StringBuilder builder = new StringBuilder();
for (int i = 0; i < depth; ++i) {
builder.append("-");
}
System.out.println(builder.append(name));
}
}
public final class HRDepartment extends CompanyItem {

    public HRDepartment(String name) {
super(name);
} @Override
public void lineOfDuty() {
System.out.println(name + ", HR is responsible for recruiting new employees");
} @Override
public void showStructure(int depth) {
StringBuilder builder = new StringBuilder();
for (int i = 0; i < depth; ++i) {
builder.append("-");
}
System.out.println(builder.append(name));
}
}
  • 客户端调用:
    private CompanyItem createParentCompany() {
CompanyItem parentCompany = new Company("Shanghai parent company");
parentCompany.addCompanyItem(new HRDepartment("Parent company HR department"));
CompanyItem southChildCompany = new Company("South child company");
southChildCompany.addCompanyItem(new HRDepartment("South child company HR department"));
parentCompany.addCompanyItem(southChildCompany);
CompanyItem hongKongOffice = new Company("HongKong office");
hongKongOffice.addCompanyItem(new FinanceDepartment("Hongkong office Finance department"));
southChildCompany.addCompanyItem(hongKongOffice);
parentCompany.addCompanyItem(new FinanceDepartment("Parent company Finance department"));
return parentCompany;
} @Test
void testComposite() {
CompanyItem parentCompany = createParentCompany();
parentCompany.showStructure(1);
System.out.println("===========================");
parentCompany.lineOfDuty();
}
  • 输出:

最新文章

  1. svn清理失败且路径显示乱码
  2. 屠龙之路_击败DB小boss_FifthDay
  3. Linux---从start_kernel到init进程启动
  4. ADO访问Access数据库错误解决心得随笔
  5. mongodb操作:利用javaScript封装db.collection.find()后可调用函数源码解读
  6. tab奇偶行颜色交替+插件
  7. Filter ,Interceptor,AOP
  8. HDU1223 Order Count 动态规划 组合数
  9. bootstrap-table 表格加载中....处理
  10. 9.8、Libgdx的返回键和菜单键捕获
  11. Docker入门(三)使用Docker Compose
  12. openKM部署二次开发,eclipse环境
  13. mysql登录密码相关
  14. Luogu 3698 [CQOI2017]小Q的棋盘
  15. 关于ProjectServer定制化项目中心页面
  16. ManicTime软件破解版自用
  17. Rainmeter如何打开控制面板的小程序
  18. Android5.0以后,materialDesign风格的加阴影和裁剪效果
  19. [置顶] kubernetes资源类型--Service
  20. MongoDB增删改查操作详解(命令行)

热门文章

  1. window对象的几个重要方法
  2. 简单案列完美搞定Mvc设计模式
  3. 洛谷 P2380 狗哥采矿
  4. 1968: C/C++经典程序训练6---歌德巴赫猜想的证明
  5. python之道09
  6. 主题模型LDA及在推荐系统中的应用
  7. 洛谷P3372线段树1
  8. 【思维题 kmp 构造】bzoj4974: [Lydsy1708月赛]字符串大师
  9. 【莫队】bzoj4542: [Hnoi2016]大数
  10. 在Linux系统中重现黑客帝国经典画面