趣解设计模式之《庞大的组织架构带来的烦恼》

〇、小故事

小王在一家创业公司,随着公司业务的发展,团队人数也从之前的十人左右拓展为了几百人的团队。那么,对于几百人的公司,就需要有一套清晰的组织架构了,这样会更便于公司员工的管理,以及跨部门的协同工作(某部门的领导是谁?包含哪些子部门?我这件事儿应该去找哪个部门?等等)这件事情显得愈发迫在眉睫。

老板找到小王跟他述说了自己的需求,小王作为公司的研发总监,毫不犹豫地就答应了老板的需求。回到工位,就开始着手对系统进行设计起来。怎么设计呢?毕竟是用来展示组织架构的系统,那么先列举出公司内的所有职位吧:

公司的高管 】董事长、CTO、COO、CFO......

公司的中层 】技术总监、人事总监、财务总监、行政总监、销售总监......

公司的基层】HR、行政人员、产品经理、研发人员、测试人员、运维人员、运营人员、销售人员......

难道要为每一类型的职员都创建一个类?那这类爆炸了 ...... 而且,如果以后所有的"总监"职位都变为了"部门经理",或者所有的研发人员都裁撤掉采用外包团队,那这些类都要变化,这个可怎么办呢?

这件事情可愁坏了小王,回到家,小王无意间看到了桌子上的优秀员工奖杯,这个是他刚到公司,公司一共10多个人的时候,公司颁给他的。这个不由得让他回忆起了过去。"哎~ 当初的日子,真的有意思,公司一共10多个人,研发团队就3个人,自己就是普通的研发人员,随着公司发展,1年后研发团队变成了20人,分为了3个研发团队,自己晋升为1个研发团队的Leader。第2年,研发团队变成了50人,分为了8个研发小组,自己也晋升为某业务线的研发主管,管理了3个小组,第3年,......"

"哎?等等!"他突然灵光乍现,公司里虽然岗位很多,但是,无论怎么说,组成元素都员工啊!基层员工是员工,高层也是员工啊 ,只不过基层员工不做管理,中高层员工有管理职能而已啊。换句话说,多个基层员工组成一个小组,多个小组组成一个部门,多个部门组成一条业务线,多个业务线组成子公司,多个子公司组成集团公司......

小王的思路打开了,针对员工类组合行为 ,非常完美的完成了整个系统的设计和开发工作,老板也非常的满意,看来,今年公司的优秀员工奖杯,又会是小王的了。故事讲完了,那么小王的灵光乍现就是我们今天要介绍的设计模式------组合模式

一、模式定义

组合模式Composite Pattern

将对象组合成树形结构 以表示"部分-整体 "的层次结构。组合模式使得用户对单个对象组合对象的使用具有一致性

我们采用树形结构,来展示组织架构图,如下所示:

二、模式类图

那么在类的设计中,我们首先创建抽象的员工类 AbstractCorp,在这个类中定义职员信息,比如:姓名,职位,薪水......,然后对于普通职员,我们创建基层员工类 LeafCorp,对于管理者员工 ,我们创建BranchCrop类,这两个类的区别就是,管理者中要包含一个变量corps,用于存储他手下团队的所有员工。具体类图如下所示:

三、代码实现

创建员工类AbstractCorp.java

java 复制代码
@AllArgsConstructor
public abstract class AbstractCorp {

    // 员工姓名
    private String name = "";

    // 员工职位
    private String position = "";

    // 员工薪水
    private int salary = 0;

    // 获得员工信息
    public String getCorpInfo() {
        return String.format("姓名:%s 职位:%s 薪水:%d", name, position, salary);
    }
}

创建管理层员工类(即:非叶子节点职员)BranchCorp.java

java 复制代码
public class BranchCorp extends AbstractCorp {
    private ArrayList<AbstractCorp> corps = Lists.newArrayList();

    public BranchCorp(String name, String position, int salary) {
        super(name, position, salary);
    }

    // 添加员工
    public void addSubCorp(AbstractCorp... corp) {
        corps.addAll(Arrays.asList(corp));
    }

    // 返回手下的员工列表
    public ArrayList<AbstractCorp> getSubCorp() {
        return corps;
    }
}

创建基层员工(即:叶子节点职员)类LeafCorp.java

java 复制代码
public class LeafCorp extends AbstractCorp {
    public LeafCorp(String name, String position, int salary) {
        super(name, position, salary);
    }
}

创建测试类CompositeTest.java

java 复制代码
public class CompositeTest {
    public static void main(String[] args) {
        // 创建公司所有员工
        BranchCorp a = new BranchCorp("A", "董事长", 100000);
        BranchCorp b = new BranchCorp("B", "技术总监", 70000);
        BranchCorp c = new BranchCorp("C", "人事总监", 60000);
        BranchCorp d = new BranchCorp("D", "财务总监", 50000);
        LeafCorp b1 = new LeafCorp("B1", "程序员", 30000);
        LeafCorp b2 = new LeafCorp("B2", "程序员", 20000);
        LeafCorp c1 = new LeafCorp("C1", "HR", 15000);
        LeafCorp d1 = new LeafCorp("D1", "会计", 13000);

        // 根据下属关系,构建树形结构
        a.addSubCorp(b, c, d);
        b.addSubCorp(b1, b2);
        c.addSubCorp(c1);
        d.addSubCorp(d1);

        // 获得下属信息
        System.out.println("-----a的下属-----");
        getSubCorp(a);
        System.out.println("-----b的下属-----");
        getSubCorp(b);
    }

    // 获得branchCorp的下属
    private static void getSubCorp(BranchCorp branchCorp) {
        for (AbstractCorp corp : branchCorp.getSubCorp()) {
            System.out.println("corp = " + corp.getCorpInfo());
            if (corp instanceof BranchCorp) {
                getSubCorp((BranchCorp) corp);
            }
        }
    }
}

执行后的结果

java 复制代码
-----a的下属-----
corp = 姓名:B 职位:技术总监 薪水:70000
corp = 姓名:B1 职位:程序员 薪水:30000
corp = 姓名:B2 职位:程序员 薪水:20000
corp = 姓名:C 职位:人事总监 薪水:60000
corp = 姓名:C1 职位:HR 薪水:15000
corp = 姓名:D 职位:财务总监 薪水:50000
corp = 姓名:D1 职位:会计 薪水:13000
-----b的下属-----
corp = 姓名:B1 职位:程序员 薪水:30000
corp = 姓名:B2 职位:程序员 薪水:20000

Process finished with exit code 0

今天的文章内容就这些了:

写作不易,笔者几个小时甚至数天完成的一篇文章,只愿换来您几秒钟的 点赞 & 分享

更多技术干货,欢迎大家关注公众号"爪哇缪斯" ~ \(^o^)/ ~ 「干货分享,每天更新」

相关推荐
止语Lab2 小时前
好的 DX 不等于少写代码——三种语言的摩擦力设计课
后端
吃饱了得干活2 小时前
别再手动解析 LLM 输出了!LangChain 四种结构化输出方案对比
后端·python·langchain
程序员天天困2 小时前
Arthas trace 命令怎么用?一行定位最慢那行代码
jvm·后端
Huiturn2 小时前
GPT 5.6 连续编码 10 小时,纯 Python 啃下 Word 二进制格式——doc2docx 实现拆解
后端
用户298698530142 小时前
Python 实现 Excel 与 Markdown 互转的实用指南
后端·python·excel
用户77283104908402 小时前
krono-job:零侵入、单二进制交付的分布式任务调度平台(开源)
后端
Conan在掘金2 小时前
鸿蒙报错速查:Function lacks ending return statement,返回路径漏 return 就炸,根因 + 真解法
后端
人间凡尔赛2 小时前
AI-Native 云原生架构:2026 年从容器编排到智能体编排的范式革命
后端·云原生·架构
IT_陈寒3 小时前
Vue的响应式让我加班到凌晨3点,原来问题出在这
前端·人工智能·后端
卷无止境3 小时前
提升 Python 代码健壮性的方法大盘点
后端·python