
组合模式(Composite Pattern)是一种结构型设计模式,它创建了对象组的树形结构,将对象组合成树状结构以表示“整体-部分”的关系。组合模式使得用户对单个对象和组合对象的访问具有一致性,即:组合能让客户以一致的方式处理个别对象以及组合对象。


这里举一个例子来说明如何实现组合模式以及组合模式的适用场景。比如XXX上市的科技公司的组织架构如上图,需要展示一下它的的组织架构,这个程序应该怎么写呢?这个场景就比较适合使用组合模式,先来画一下UML类图:

- /**
- * 抽象组织,抽象构件(AbstractComponent)角色
- */
- public abstract class AbstractOrganization {
- /**
- * 组织名称
- *
- * @return
- */
- public abstract String getOrgName();
-
- /**
- * 组织实际领导
- *
- * @return
- */
- public abstract String getLeaderName();
-
- /**
- * 添加组织
- *
- * @param abstractOrganization
- */
- public void add(AbstractOrganization abstractOrganization) {
- }
-
- /**
- * 移除组织
- *
- * @param abstractOrganization
- */
- public void remove(AbstractOrganization abstractOrganization) {
- }
-
- /**
- * 组织信息展示
- */
- public void show() {
- }
- }
- /**
- * 分公司 ,树枝构件(Composite)角色
- */
- public class BranchCompany extends AbstractOrganization {
- /**
- * 组织名称
- */
- private String orgName;
- /**
- * 组织实际领导
- */
- private String leaderName;
- private List
organizations = new ArrayList<>(); -
- public BranchCompany(String orgName, String leaderName) {
- this.orgName = orgName;
- this.leaderName = leaderName;
- }
-
- @Override
- public String getOrgName() {
- return this.orgName;
- }
-
- @Override
- public String getLeaderName() {
- return this.leaderName;
- }
-
- @Override
- public void add(AbstractOrganization abstractOrganization) {
- this.organizations.add(abstractOrganization);
- }
-
- @Override
- public void remove(AbstractOrganization abstractOrganization) {
- this.organizations.remove(abstractOrganization);
- }
-
- @Override
- public void show() {
- System.out.println("公司名称:" + this.orgName + ",主要领导:" + this.leaderName);
- for (AbstractOrganization organization : organizations) {
- organization.show();
- }
- }
- }
- /**
- * 总公司 ,树枝构件(Composite)角色
- */
- public class Company extends AbstractOrganization {
- private List
organizations = new ArrayList<>(); - /**
- * 组织名称
- */
- private String orgName;
- /**
- * 组织实际领导
- */
- private String leaderName;
-
- public Company(String orgName, String leaderName) {
- this.orgName = orgName;
- this.leaderName = leaderName;
- }
-
- @Override
- public String getOrgName() {
- return this.orgName;
- }
-
- @Override
- public String getLeaderName() {
- return this.leaderName;
- }
-
- @Override
- public void add(AbstractOrganization abstractOrganization) {
- this.organizations.add(abstractOrganization);
- }
-
- @Override
- public void remove(AbstractOrganization abstractOrganization) {
- this.organizations.remove(abstractOrganization);
- }
-
- @Override
- public void show() {
- System.out.println("公司名称:" + this.orgName + ",主要领导:" + this.leaderName);
- for (AbstractOrganization organization : organizations) {
- organization.show();
- }
- }
- }
- /**
- * 部门 ,树叶构件(Leaf)角色
- */
- public class Department extends AbstractOrganization {
- /**
- * 组织名称
- */
- private String orgName;
- /**
- * 组织实际领导
- */
- private String leaderName;
-
- public Department(String orgName, String leaderName) {
- this.orgName = orgName;
- this.leaderName = leaderName;
- }
-
- @Override
- public String getOrgName() {
- return this.orgName;
- }
-
- @Override
- public String getLeaderName() {
- return this.leaderName;
- }
-
- @Override
- public void show() {
- System.out.println("部门名称:" + this.orgName + ",主要领导:" + this.leaderName);
- }
- }
- public class Test {
- public static void main(String[] args) {
- AbstractOrganization huawei = new Company("华为科技", "任正非");
- AbstractOrganization henan = new BranchCompany("河南分公司", "张三");
- huawei.add(henan);
- AbstractOrganization yanfabu = new Department("研发部", "小李");
- AbstractOrganization xiaoshoubu = new Department("销售部", "小张");
- henan.add(yanfabu);
- henan.add(xiaoshoubu);
- AbstractOrganization shangdong = new BranchCompany("山东分公司", "李四");
- huawei.add(shangdong);
- AbstractOrganization xiaoshoubu2 = new Department("销售部", "小美");
- AbstractOrganization caiwubu = new Department("财务部", "小花");
- shangdong.add(xiaoshoubu2);
- shangdong.add(caiwubu);
- huawei.show();
- }
- }
总之,组合模式适用于构建复杂的树形结构,希望客户端忽略组合对象与单个对象的差异,以及处理树形结构的场景。它能够清晰地定义分层次的复杂对象,简化客户端代码,符合开闭原则。但也存在一些缺点。在应用组合模式时,需要根据具体情况进行权衡,并考虑是否适合使用该模式。