首页 > 其他分享 >17 设计模式之组合模式(公司员工结构案例)

17 设计模式之组合模式(公司员工结构案例)

时间:2024-12-06 18:28:12浏览次数:9  
标签:公司员工 17 经理 节点 Employee 组合 薪资 设计模式 下属

一、组合模式的定义

        组合模式(Composite Pattern)是一种结构型设计模式,它让我们可以将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式允许客户端以统一的方式对待单个对象和对象集合。它适用于表示具有层次关系的对象结构。

        组合模式允许你将多个对象(无论是单个对象还是对象集合)组合成一个树形结构,以便客户端可以像操作单一对象一样操作整个对象树。它使得客户端在处理对象的集合时不需要关心集合中的元素类型,统一通过相同的接口进行操作。


二、组合模式的组成

  • Component(组件):这是一个抽象类或接口,定义了叶子对象和组合对象的共同行为。所有的对象(无论是叶子节点还是组合节点)都应该实现该接口。

  • Leaf(叶子节点):在组合结构中,叶子节点表示树的最底层节点,它没有子节点。通常是一些基本的操作。

  • Composite(组合节点):它定义了具有子节点的对象,作为容器来存放叶子节点或者其他组合节点。它实现了 Component 接口,并且能够管理和操作其子节点。

  • Client(客户端):客户端通过调用 Component 接口来操作树形结构,无论是操作单一对象还是操作对象集合。


三、组合模式的优点

  • 透明性:客户端不需要关心对象是叶子节点还是组合节点,客户端代码通过 Component 接口来操作所有对象。

  • 递归结构:组合模式能够自然地表示递归结构,比如文件系统、组织结构等。

  • 简化代码:通过组合多个对象,可以减少客户端代码的复杂度,避免了大量条件判断。


四、组合模式的缺点

  • 设计复杂:组合模式可能会引入过多的子类和接口,从而使得系统变得复杂。尤其是如果不需要层次结构时,引入组合模式可能是过度设计。

  • 过度泛化:由于所有对象(无论是叶子节点还是组合节点)都通过相同的接口进行操作,可能会出现不必要的泛化,导致某些行为变得不够直观或不合理。


五、组合模式的实现示例

1.业务场景

        假设我们有一个公司,员工分为普通员工和经理。经理有下属员工,并且经理的薪资包含了下属员工的薪资。经理也可以是其他经理的下属,因此形成了树形结构。我们要实现一个组合模式,其中 Worker(普通员工)和 Manager(经理)是两种角色,而 Manager 可以拥有多个 Worker 和其他 Manager

2.角色说明

  • Employee:员工接口,定义了所有员工的基本操作,例如显示信息和计算薪资。
  • Worker:普通员工类,属于叶子节点,没有下属。
  • Manager:经理类,属于组合节点,可以有多个下属(其他员工或经理)。

3.代码实现

// Employee 接口,表示员工的基本操作
public interface Employee {
    void showDetails();  // 显示员工信息
    double getSalary();  // 获取员工薪资
}

// Worker 类,表示普通员工
public class Worker implements Employee {
    private String name;
    private String position;
    private double salary;

    public Worker(String name, String position, double salary) {
        this.name = name;
        this.position = position;
        this.salary = salary;
    }

    @Override
    public void showDetails() {
        System.out.println("员工姓名:" + name + ", 职位:" + position + ", 薪资:" + salary);
    }

    @Override
    public double getSalary() {
        return salary;
    }
}

// Manager 类,表示经理,负责管理下属
public class Manager implements Employee {
    private String name;
    private String position;
    private double salary;
    private List<Employee> subordinates = new ArrayList<>(); // 存储下属员工

    public Manager(String name, String position, double salary) {
        this.name = name;
        this.position = position;
        this.salary = salary;
    }

    // 添加下属
    public void addSubordinate(Employee employee) {
        subordinates.add(employee);
    }

    // 移除下属
    public void removeSubordinate(Employee employee) {
        subordinates.remove(employee);
    }

    @Override
    public void showDetails() {
        System.out.println("经理姓名:" + name + ", 职位:" + position + ", 薪资:" + salary);
        System.out.println("下属:");
        for (Employee subordinate : subordinates) {
            subordinate.showDetails();
        }
    }

    @Override
    public double getSalary() {
        double totalSalary = salary;
        for (Employee subordinate : subordinates) {
            totalSalary += subordinate.getSalary(); // 累加下属的薪资
        }
        return totalSalary;
    }
}

4.代码解析

  • Employee 接口:所有员工都实现了这个接口,包含了 showDetails()getSalary() 方法,提供了展示员工信息和计算薪资的功能。

  • Worker 类:普通员工类实现了 Employee 接口,表示树的叶子节点,没有下属,只能提供自身的薪资和信息。

  • Manager 类:经理类实现了 Employee 接口,表示树的组合节点,能够包含下属员工。它有 addSubordinate()removeSubordinate() 方法来添加和移除下属。它会遍历所有下属来计算总薪资。

5.测试类

public class TestComponent {
    public static void main(String[] args) {
        // 下属员工信息
        Employee employee1 = new Worker("Theodore", "软件设计师", 12000);
        Employee employee2 = new Worker("Andy", "网络工程师", 10000);

        // 经理信息
        Manager manager = new Manager("小胖", "研发部经理", 15000);
        
        // 添加经理下属
        manager.addSubordinate(employee1);
        manager.addSubordinate(employee2);
        
        // 显示经理及其下属员工的详细信息
        System.out.println("经理及其下属信息:");
        manager.showDetails();
        
        // 计算并显示经理的薪资总额(包括下属的薪资)
        System.out.println("经理总薪资:" + manager.getSalary());
        
        // 创建一个更高级的经理并添加其下属(包括之前的经理)
        Manager seniorManager = new Manager("大胖", "CEO", 20000);
        seniorManager.addSubordinate(manager);

        // 显示高级经理及其下属(包括原经理)的信息
        System.out.println("\n高级经理及其下属信息:");
        seniorManager.showDetails();

        // 计算并显示高级经理的薪资总额(包括下属的薪资)
        System.out.println("高级经理总薪资:" + seniorManager.getSalary());
    }
}

6.输出示例

经理及其下属信息:
经理姓名:小胖, 职位:研发部经理, 薪资:15000.0
下属:
员工姓名:Theodore, 职位:软件设计师, 薪资:12000.0
员工姓名:Andy, 职位:网络工程师, 薪资:10000.0
经理总薪资:37000.0

高级经理及其下属信息:
经理姓名:大胖, 职位:CEO, 薪资:20000.0
下属:
经理姓名:小胖, 职位:研发部经理, 薪资:15000.0
下属:
员工姓名:Theodore, 职位:软件设计师, 薪资:12000.0
员工姓名:Andy, 职位:网络工程师, 薪资:10000.0
高级经理总薪资:59000.0


六、总结

        组合模式通过允许将单个对象和对象集合统一处理,使得客户端代码可以以一致的方式对待组合对象和单一对象。这个模式非常适合那些需要表示部分-整体层次结构的场景,如组织结构、文件系统等。在本示例中,Worker 作为叶子节点,Manager 作为组合节点,它们通过实现共同的 Employee 接口,实现了层次结构中的统一操作。

        组合模式使得复杂的树形结构能够轻松地进行管理,同时减少了客户端代码的复杂性。

标签:公司员工,17,经理,节点,Employee,组合,薪资,设计模式,下属
From: https://blog.csdn.net/Theodore_1022/article/details/144298004

相关文章

  • 亚马逊ISO17025认证资质检测报告
    各位亚马逊卖家朋友要问的或者说需要办理的不叫ISO17025认证,而是由ISO17025资质认可的实验室,出具的安全检测报告。而这个安全检测报告,需要根据产品类别,产品用途不同,来选择对应的检测标准。所以亚马逊卖家要做的,ISO17025认证,其实是他们产品的安全检测报告。美国亚马逊要求的ISO......
  • 设计模式学习思路二
            设计模式的学习思路_设计模式必须按顺序进行吗-CSDN博客以下是一些方法和思路可以帮助你更清晰地识别使用了哪种设计模式。1.确定模式时的思考步骤        以下是分析代码时,你可以遵循的一些思路和步骤,帮助你识别可能使用的设计模式:a.识别类和对......
  • LM317&LM337可调电源制作教程:一学就会,简单实用!
    目录......
  • 大二上 国际化科研素养实训(计算机科学)人工智能:机器学习在数据分析及自然语言处理中的
    20241206出成绩了,本次考试成绩满分题目如下:单选题(5分)Azoologistworkingatalakewouldliketoestimatetheageofafishinyearsbylookingatthelength,weight,colorandmaximumwidth.WhatMLtaskisthis?(B)AClassificationBRegressionCRecom......
  • 20222417 2024-2025-1 《网络与系统攻防技术》实验八实验报告
    1.实验内容1.1本周学习内容回顾本周学习了关于Web安全基础/前后端的知识,同时还学习了SQL注入攻击的原理以及XSS脚本攻击。1.2实验要求(1)Web前端HTML能正常安装、启停Apache。理解HTML,理解表单,理解GET与POST方法,编写一个含有表单的HTML。(2)Web前端javascipt理解JavaScri......
  • django在线音乐网站-计算机毕业设计源码11764
    摘要本文旨在研究基于Python的Django+MySQL和Vue.js框架的在线音乐网站的设计与实现,旨在提供一个功能完善、用户友好且具有交互性的音乐分享和播放平台。随着互联网技术的不断发展,用户对于多样化音乐的需求也越来越高。传统的音乐分享方式存在版权管理、获取途径有限等问题,需......
  • Java-19 深入浅出 MyBatis - 用到的设计模式 源码剖析 代理设计模式
    点一下关注吧!!!非常感谢!!持续更新!!!大数据篇正在更新!https://blog.csdn.net/w776341482/category_12713819.html目前已经更新到了:MyBatis(正在更新)代理模式概念介绍代理模式(ProxyPattern):给某一个对象提供一个代理,并由代理对象控制对原对象的引用,代理模式的英文名字叫Prox......
  • 痞子衡嵌入式:简析i.MXRT1170 XECC开启及Data Swap功能对于外部RAM的访问性能影响
    大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家分享的是i.MXRT1170XECC开启及DataSwap功能对于外部RAM的访问性能影响。文接上篇《i.MXRT1170XECC功能特点及其保护串行NORFlash和SDRAM之道》,这篇文章里痞子衡给大家介绍了XECC原理及在其使能下操作NORF......
  • 15 设计模式之抽象工厂模式(支付系统案例)
    一、什么是抽象工厂模式        抽象工厂模式(AbstractFactoryPattern)是创建型设计模式之一,用于提供一个接口,用来创建一系列相关或相互依赖的对象,而不需要指定它们具体的类。        抽象工厂模式允许客户端通过工厂接口来创建一系列相关的产品对象,而无需知......
  • XJCO1711 Collaborating with HealthMate
    AssessmentBriefModuletitleProceduralProgrammingModulecodeXJCO1711AssignmenttitleCollaboratingwithHealthMateCIConaStepTrackerDataAnalysisToolAssignmenttypeanddescriptionThisisaprogrammingassignment.Youwilldesignandcreat......