设计模式--组合模式

这篇具有很好参考价值的文章主要介绍了设计模式--组合模式。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

缘起

某日,小明公司最近接到一个办公管理系统的项目,并且在每个城市都有分部。这属于是很常见的OA系统,只要前期将需求分析完善好,中后期开发维护是不难的。

然而,总部公司使用后觉得很OK,想要其他城市的分公司也执行使用。但是现在的问题是,其他分公司的部门和制度没有总公司那么清晰完善。

也许可以一个城市一套代码?但是总公司不乐意了,要求总部、分部等是需要成树状结构的,不可以平行管理。

那么部门Leader想到了一个合适的设计模式–组合模式。

组合模式

组合模式(Composite):将对象组合成树形结构以表示’部门-整体’的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。

结构图

设计模式--组合模式,设计模式,Java,设计模式,组合模式

Component:作为组合中的对象声明接口,在适当情况下,实现所有类共有接口的默认行为,声明一个接口用于访问和管理Component的子组件

通常使用add和remove增加或删除树枝或树叶的功能

public abstract class Component {
    
    protected String name;

    public Component(String name) {
        this.name = name;
    }
    public abstract void add(Component component);
    public abstract void remove(Component component);
	public abstract void display(int depth);
}
  • Leaf在组合中表示叶节点对象,叶子节点没有子节点,所以add和remove对于Leaf对象来说是没用的,给客户端个提示就行。
public class Leaf extends Component {

    public Leaf(String name) {
        super(name);
    }

    @Override
    public void add(Component component) {
        System.out.println("Cannot add to a leaf");
    }
    @Override
    public void remove(Component component) {
        System.out.println("Cannot remove from a leaf");
    }
    
    // 叶子节点展示职级和名称
    @Override
    public void display(int depth) {
        for (int i = 0; i < depth; i++) {
            System.out.print("-");
        }
        System.out.println(name);
    }
}
  • Composite定义有枝节点行为,用来存储子部件,在Component接口中实现与子部件有关的操作,比如增加add和删除remove
public class Composite extends Component {

    private List<Component> children = new ArrayList<>();

    public Composite(String name) {
        super(name);
    }

    @Override
    public void add(Component component) {
        children.add(component);
    }

    @Override
    public void remove(Component component) {
        children.remove(component);
    }

    @Override
    public void display(int depth) {
        for (int i = 0; i < depth; i++) {
            System.out.print("-");
        }
        System.out.println(name);
		// 表层级关系+2
        for (Component item : children) {
            item.display(depth + 2);
        }
    }
}
  • 客户端调用,可以通过Component接口操作组合部件的对象
// 顶级节点
Composite root = new Composite("root");
// 添加两个叶子节点
root.add(new Leaf("Leaf A"));
root.add(new Leaf("Leaf B"));

Composite comp = new Composite("Composite X");
// 加两个叶子节点
comp.add(new Leaf("Leaf A"));
comp.add(new Leaf("Leaf B"));

// 顶级节点加一个枝节点
root.add(comp);

Composite comp2 = new Composite("Composite XY");
// 加两个叶子节点
comp.add(new Leaf("Leaf XYA"));
comp.add(new Leaf("Leaf XYB"));

// 二级节点再加一个枝节点
comp.add(comp2);

// 展示整个架构
root.display(1);

结果

-root
---Leaf A
---Leaf B
---Composite X
-----Leaf A
-----Leaf B
-----Leaf XYA
-----Leaf XYB
-----Composite XY

当发现需求中是体现部分与整体层次的结构时,希望用户可以忽略组合对象与单个对象的不同,统一使用组合结构中的所有对象时,就应该考虑使用组合模式了。

在java开发窗体应用的容器控件Container继承了Component(java自带的),就有add和remove方法,所以它在上面增加控件,如Button、Label、Checkbox等就变成了很自然的事,这就是典型的组合模式的应用。

公司管理系统案例

设计模式--组合模式,设计模式,Java,设计模式,组合模式

公司类:抽象类或接口

public abstract class Company {
    protected String name;

    public Company(String name) {
        this.name = name;
    }
    
    public abstract void add(Company company);  // 增加
    public abstract void remove(Company company); // 删除
    public abstract void display(int depth);    // 展示
    public abstract void lineOfDuty();  // 展示职责
    
}

具体公司类:实现接口、树枝节点文章来源地址https://www.toymoban.com/news/detail-812412.html

public class ConcreteCompany extends Company {

    protected List<Company> children = new ArrayList<>();
    public ConcreteCompany(String name) {
        super(name);
    }

    @Override
    public void add(Company company) {
        children.add(company);
    }

    @Override
    public void remove(Company company) {
        children.remove(company);
    }

    @Override
    public void display(int depth) {
        for (int i = 0; i < depth; i++) {
            System.out.print("-");
        }
        System.out.println(name);

        for (Company child : children) {
            child.display(depth + 2);
        }
    }

    @Override
    public void lineOfDuty() {
        for (Company child : children) {
            child.lineOfDuty();
        }
    }
}
  • 人力资源部、财务部:叶子节点
// HR
public class HRDept extends Company {
    public HRDept(String name) {
        super(name);
    }

    @Override
    public void add(Company company) {

    }

    @Override
    public void remove(Company company) {

    }

    @Override
    public void display(int depth) {
        for (int i = 0; i < depth; i++) {
            System.out.print("-");
        }
        System.out.println(name);
    }

    @Override
    public void lineOfDuty() {
        System.out.println(name+"员工招聘培训");
    }
}
// 财务部
public class FinanceDept extends Company {

    public FinanceDept(String name) {
        super(name);
    }

    @Override
    public void add(Company company) {

    }

    @Override
    public void remove(Company company) {

    }

    @Override
    public void display(int depth) {
        for (int i = 0; i < depth; i++) {
            System.out.print("-");
        }
        System.out.println(name);
    }

    @Override
    public void lineOfDuty() {
        System.out.println(name + "公司财务收支管理");
    }
}
  • 客户端
// 顶级节点
ConcreteCompany root = new ConcreteCompany("总公司");
root.add(new HRDept("总公司人力资源"));
root.add(new FinanceDept("总公司财务部"));


ConcreteCompany comp = new ConcreteCompany("某分公司");
comp.add(new HRDept("某分公司人力资源"));
comp.add(new FinanceDept("某分公司财务部"));

// 给总公司增加下级部门
root.add(comp);

ConcreteCompany comp2 = new ConcreteCompany("A办事处");
comp2.add(new HRDept("A办事处人力资源"));
comp2.add(new FinanceDept("A办事处财务部"));
comp.add(comp2);

ConcreteCompany comp3 = new ConcreteCompany("B办事处");
comp3.add(new HRDept("B办事处人力资源"));
comp3.add(new FinanceDept("B办事处财务部"));

comp.add(comp3);
System.out.println("结构图");
root.display(1);

System.out.println("职责");
root.lineOfDuty();
结构图
-总公司
---总公司人力资源
---总公司财务部
---某分公司
-----某分公司人力资源
-----某分公司财务部
-----A办事处
-------A办事处人力资源
-------A办事处财务部
-----B办事处
-------B办事处人力资源
-------B办事处财务部
职责
总公司人力资源员工招聘培训
总公司财务部公司财务收支管理
某分公司人力资源员工招聘培训
某分公司财务部公司财务收支管理
A办事处人力资源员工招聘培训
A办事处财务部公司财务收支管理
B办事处人力资源员工招聘培训
B办事处财务部公司财务收支管理

到了这里,关于设计模式--组合模式的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Java设计模式之结构型-组合模式(UML类图+案例分析)

    目录 一、基础概念 二、UML类图 三、角色设计 四、案例分析 4.1、基本实现 4.2、菜单遍历  五、总结  组合模式(Composite Pattern)又叫部分-整体模式,它通过将对象组合成树形结构来表示“整体-部分”的层次关系,允许用户统一单个对象和组合对象的处理逻辑。 角色 描述

    2024年02月16日
    浏览(50)
  • 【设计模式——学习笔记】23种设计模式——组合模式Composite(原理讲解+应用场景介绍+案例介绍+Java代码实现)

    编写程序展示一个学校院系结构: 需求是这样,要在一个页面中展示出学校的院系组成,一个学校有多个学院,一个学院有多个系 【传统方式】 将学院看做是学校的子类,系是学院的子类,小的组织继承大的组织 分析: 在一个页面中展示出学校的院系组成,一个学校有多个

    2024年02月15日
    浏览(45)
  • 【Java面试题】设计模式之七种结构性模式——代理模式、适配器模式、桥接模式、装饰模式、外观模式、享元模式、组合模式

    目录 一、代理模式 二、适配器模式 三、桥接模式 四、装饰模式 五、外观模式 六、享元模式 七、组合模式 概念: 代理模式是为其他对象提供一种以代理控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对

    2023年04月09日
    浏览(52)
  • 设计模式-组合模式

    组合模式可以使用一棵树来表示 组合模式使得用户可以使用一致的方法操作单个对象和组合对象 组合模式又叫部分整体模式,将对象组合成树形结构以表示“部分-整体”的层次结构,可以更好的实现管理操作,部分-整体对象的操作基本一样,但是应该还会有不一样的地方

    2024年02月10日
    浏览(50)
  • 设计模式——组合模式08

    组合模式:把类似对象或方法组合成结构为树状的设计思路。 例如部门之间的关系。 设计模式,一定要敲代码理解 满足开闭原则。叶子结点与非叶子结点都继承或实现同一抽象,只是叶子功能权限少,而非叶子结点需要容器记录子节点。 代码下载

    2024年04月11日
    浏览(48)
  • 设计模式--组合模式

    某日,小明公司最近接到一个办公管理系统的项目,并且在每个城市都有分部。这属于是很常见的OA系统,只要前期将需求分析完善好,中后期开发维护是不难的。 然而,总部公司使用后觉得很OK,想要其他城市的分公司也执行使用。但是现在的问题是,其他分公司的部门和

    2024年01月21日
    浏览(58)
  • 设计模式——组合模式

    组合模式(Composite Pattern):组合多个对象形成树形结构以表示具有“整体—部分”关系的层次结构。组合模式对单个对象(即叶子对象)和组合对象(即容器对象)的使用具有一致性,组合模式又可以称为“整体—部分”(Part-Whole)模式,它是一种对象结构型模式。 组合模式将

    2024年02月11日
    浏览(69)
  • 设计模式:组合模式

    组合模式是一种结构型设计模式,用于将对象组织成树形结构,以表示“部分-整体”的层次结构。组合模式使得客户端可以统一地处理单个对象和组合对象,而不需要区分它们之间的差异。 在组合模式中,有两种主要类型的对象:叶节点和组合节点。叶节点表示树结构中的

    2024年02月07日
    浏览(60)
  • 设计模式——10. 组合模式

    组合模式是一种结构型设计模式,用于将对象组合成树状结构以表示“部分-整体”的层次结构。它允许客户端以一致的方式处理单个对象和组合对象(包含多个对象的容器),使得客户端无需关心它们之间的差异。 组合模式通常涉及两种主要角色: 叶子节点(Leaf):这是组

    2024年02月07日
    浏览(67)
  • 设计模式浅析(十) ·设计模式之迭代器&组合模式

    日常叨逼叨 java设计模式浅析,如果觉得对你有帮助,记得一键三连,谢谢各位观众老爷😁😁 案例 有两家门店,门店A呢只提供早餐,门店B呢只提供午餐,有一天这两家店铺想要进行合并,一起做大做强,再创辉煌。 合并后呢,对于菜单的定制存在了一定的问题: 门店A的

    2024年04月11日
    浏览(48)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包