设计模式-1-组合模式

简介: 组合模式(Composite Pattern),又叫部分整体模式,就是将对象组合成树形结构以表示“部分-整体”的层次结构。它将一些对象按层次关系组织成树形结构,这些对象可能是单个,也可能是组合,然后用同一种逻辑处理这些对象。组合类别属于结构型模式。

什么是组合模式呢?

       组合模式(Composite Pattern),又叫部分整体模式,就是将对象组合成树形结构以表示“部分-整体”的层次结构。它将一些对象按层次关系组织成树形结构,这些对象可能是单个,也可能是组合,然后用同一种逻辑处理这些对象。组合类别属于结构型模式。

哪些使用场景使用呢?

你想表示对象的部分-整体层次结构

你希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。

光念不好理解哈,举个例子:一个公司,最高层是ceo,下面是销售部、营销部各部门,每个部门也都有自己的员工(经理、员工),当然再往下也可以分各个小组等等。

     比如可以将整个公司看作一个整体,每个部门也是一个整体,部门可以是公司的一部分,人员也可以是公司的一部分。公司就像是大树,部门像是枝丫,员工像是叶子,树枝上可以有叶子,叶子就必须是最终节点了。

我们下面用代码来实现这个结构:

       1.先建立一个抽象节点对象,抽象出共有属性:

packagecom.xing.design.composite.ep2;
/***  * @author xing*/publicabstractclassNode {
/*** 名字*/protectedStringname;
/*** 工资*/protecteddoublesalary;
/*** 人数*/protectedintcount;
publicNode(Stringname) {
this.name=name;
  }
publicabstractdoublegetAllSalary();
publicabstractintgetAllCount();
publicStringgetName() {
returnname;
  }
publicvoidsetName(Stringname) {
this.name=name;
  }
publicdoublegetSalary() {
returnsalary;
  }
publicvoidsetSalary(doublesalary) {
this.salary=salary;
  }
publicintgetCount() {
returncount;
  }
publicvoidsetCount(intcount) {
this.count=count;
  }
@OverridepublicStringtoString() {
return"Node [name="+name+", salary="+salary+", count="+count+"]";
  }
}

       2.建立部门对象,提供了计算部门的工资和人数的方法:

packagecom.xing.design.composite.ep2;
importjava.util.ArrayList;
importjava.util.List;
/*** 部门* @author xing*/publicclassDepartmentextendsNode{
/*** 存放下级元素*/privateList<Node>subList;
publicDepartment(Stringname) {
super(name);
this.subList=newArrayList<Node>();
  }
@OverridepublicdoublegetAllSalary() {
doubleallSalary=0;
for(Nodenode : subList) {
allSalary+=node.getAllSalary();
    }
this.salary=allSalary;
returnallSalary;
  }
@OverridepublicintgetAllCount() {
intallCount=0;
for(Nodenode : subList) {
allCount+=node.getAllCount();
    }
this.count=allCount;
returnallCount;
  }
publicvoidaddSub(Nodenode) {
subList.add(node);
  }
publicList<Node>getSubList(){
returnsubList;
  }
}

       3.建立员工对象,员工简单:

packagecom.xing.design.composite.ep2;
/***  员工* @author xing*/publicclassEmployeeextendsNode{
publicEmployee(Stringname, doublesalary) {
super(name);
this.salary=salary;
  }
@OverridepublicdoublegetAllSalary() {
returnsalary;
  }
@OverridepublicintgetAllCount() {
return1;
  }
}

       4.使用上述类来实现部门和员工组成公司的部分-整体结构:

packagecom.xing.design.composite.ep2;
/***  组合模式*    组合模式(Composite Pattern),又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象。组合模式依据树形结构来组合对象,用来表示部分以及整体层次。*    这种类型的设计模式属于结构型模式,它创建了对象组的树形结构。*    这种模式创建了一个包含自己对象组的类。该类提供了修改相同对象组的方式。* @author xing*/publicclassCompositePattern {
publicstaticvoidmain(String[] args) {
// 公司Departmentdepartment=newDepartment("苏念科技");
// 建立头ceoEmployeeCEO=newEmployee("ceo", 300);
department.addSub(CEO);
department.addSub(newEmployee("混日子人员", 200));
// 销售部门Departmentsales=newDepartment("销售部门");
// 销售头EmployeeheadSales=newEmployee("Robert", 200);
// 销售员工1EmployeesalesExecutive1=newEmployee("Richard", 10);
// 销售员工2EmployeesalesExecutive2=newEmployee("Rob", 10);
sales.addSub(headSales);
sales.addSub(salesExecutive1);
sales.addSub(salesExecutive2);
department.addSub(sales);
// 营销部门Departmentmarketing=newDepartment("营销部门");
// 营销头EmployeeheadMarketing=newEmployee("Michel", 20);
// 营销员工1Employeeclerk1=newEmployee("Laura", 10);
// 营销员工2Employeeclerk2=newEmployee("Bob", 10);
marketing.addSub(headMarketing);
marketing.addSub(clerk1);
marketing.addSub(clerk2);
department.addSub(marketing);
// 秘书部门Departmentgrils=newDepartment("秘书部");
// 秘书兼财务兼老板娘Employeegril=newEmployee("少妇", 10000);
// 二奶Employeegril2=newEmployee("二奶", 1000);
grils.addSub(gril);
grils.addSub(gril2);
department.addSub(grils);
System.out.println("公司总工资:"+department.getAllSalary());
System.out.println("公司总人数:"+department.getAllCount());
System.out.println("公司平均工资:"+department.getAllSalary() /department.getAllCount());
System.out.println("------------------------打印本公司所有员工开始----------------------------");
//公司System.out.println("公司:"+department.getName());
//公司人员for(Nodenode : department.getSubList()) {
System.out.println("------------------------打印"+node.getName()+"开始----------------------------");
if(nodeinstanceofDepartment) {
DepartmentsubDepartment= (Department) node;
for(NodesubNode : subDepartment.getSubList()) {
System.out.println(node.getName()+"部门内人员:"+subNode);
        }
      }else {
System.out.println("人员:"+node.getName());
      }
System.out.println("------------------------打印"+node.getName()+"结束----------------------------");
System.out.println("");
    }
System.out.println("------------------------打印本公司所有员工完毕----------------------------");
  }
}

       ok。从Java角度看,我们通过在类中存储成员变量来完成了功能的扩展,玩的就是成员变量。

组合模式组成元素:

  • 抽象元素:包含共有元素的类。
  • 树叶元素:只包含自身属性的简单对象,没有子节点。
  • 树枝元素:包含自身类型的子节点及树叶元素的对象。
  • 组合使用类:组合树枝和树叶元素形成树结构的类。

       在树型结构的问题中,模糊了简单元素(树叶)和复杂元素(树枝)的概念,客户程序可以像处理简单元素一样来处理复杂元素,从而使得组合使用类与复杂元素的内部结构解耦。

总结

       组合模式就是按照层级关系将不同的对象组装成树形结构,来表达部分和整体的关系。这些对象可以是单个对象(员工),也可以是整体(部门)。

       日常中,如果遇到了如角色与菜单、部门与员工、班级与学生、文件夹与文件等业务场景,还有二叉树,我们都可以用组合模式来表示。如一个文件夹里可以有子级文件夹,也可以有文件,子级文件夹下面还可以递归,无线套娃。。。

       在组合模式里,我们可以把一个部门看作一个整体,也可以看成公司的一个部分。一个员工可以是一个整体(CEO和混日子那个),也可以是部门或者公司的一部分。我们这样看来就可以一致性的使用单个对象或组合对象,因为都只是一个节点而已。

     

END

目录
相关文章
|
6月前
|
设计模式 JavaScript 前端开发
js设计模式【详解】—— 组合模式
js设计模式【详解】—— 组合模式
83 7
|
4月前
|
设计模式 Java
Java设计模式:组合模式的介绍及代码演示
组合模式是一种结构型设计模式,用于将多个对象组织成树形结构,并统一处理所有对象。例如,统计公司总人数时,可先统计各部门人数再求和。该模式包括一个通用接口、表示节点的类及其实现类。通过树形结构和节点的通用方法,组合模式使程序更易扩展和维护。
Java设计模式:组合模式的介绍及代码演示
|
4月前
|
设计模式 存储 安全
Java设计模式-组合模式(13)
Java设计模式-组合模式(13)
|
7月前
|
设计模式 存储 安全
Java设计模式:组合模式之透明与安全的两种实现(七)
Java设计模式:组合模式之透明与安全的两种实现(七)
|
7月前
|
设计模式 Java
Java设计模式之组合模式详解
Java设计模式之组合模式详解
|
7月前
|
设计模式
组合模式-大话设计模式
组合模式-大话设计模式
|
8月前
|
设计模式 Java 容器
【设计模式系列笔记】组合模式
组合模式(Composite Pattern)是一种结构型设计模式,它允许将对象组合成树状结构以表示部分-整体的层次结构。组合模式使得客户端可以统一处理单个对象和对象组合,而无需区分它们的类型。
99 12
|
8月前
|
设计模式 Go
[设计模式 Go实现] 结构型~组合模式
[设计模式 Go实现] 结构型~组合模式
|
8月前
|
设计模式 安全 Java
[设计模式Java实现附plantuml源码~结构型]树形结构的处理——组合模式
[设计模式Java实现附plantuml源码~结构型]树形结构的处理——组合模式
|
8月前
|
设计模式 存储 Java
23种设计模式,组合模式的概念优缺点以及JAVA代码举例
【4月更文挑战第5天】组合模式(Composite Pattern)是一种结构型设计模式,旨在通过将对象组合成树形结构以表示部分-整体的层次结构,使用户对单个对象和组合对象的使用具有一致性。这种模式让客户可以统一地处理单个对象和组合对象
89 6