题外话

本来是周更的频率, 因为真实的"小光"真实地逃离了北京, 回了武汉, 回了老家, 处理了一些私人事务. 也就有快一个月时间没有更新了, 抱歉.

年终总结也都没有时间写, 抽空写这么一篇, 提前祝大家新年快乐, 过年回家路上平安顺利.

前情提要

上集讲到, 小光统一了各个分店的制作热干面的流程, 并且引入模板方法在不改变热干面的制作流程基础上可以定制其中某些步骤. 通过这些措施, 小光热干面的品牌性也是更加深入人心, 生意红红火火.

此时的小光, 有了更多的时间去思考公司的前程, 他认为, 一个良好的有序的组织架构是公司发展的必要点. 而此时, 小光也有觉得是时候梳理下公司的组织架构了.

所有示例源码已经上传到Github, 戳这里

组织架构

小光参考了当前很多公司的一些架构方式, 根据分店, 职责简单梳理了下目前小光热干面的架构:

整个就是一个树形结构.

  • 小光热干面总部下面管理着各个分店, 也有其自己的部门.
  • 各个分店也有着自己的部门.

设计一套系统来表达这个组织架构

梳理完组织关系后, 小光觉得有必要设计一套系统来管理这个关系图, 以便后续能方便的查看和管理这个架构, 并能很清晰地讲解给新员工.

简单的开始

一开始, 小光并没有想太多, 按照不同的层级, 分别创建了总公司, 分店, 部门三个类:

// 部门
public class Department {private String name;public Department(String name) {this.name = name;}@Overridepublic String toString() {return "部门:" + name;}
}// 分店
public class BranchOffice {private String name;public BranchOffice(String name) {this.name = name;}private List<Department> departments = new ArrayList<>();public void add(Department sub) {departments.add(sub);}@Overridepublic String toString() {StringBuilder builder = new StringBuilder("分公司:" + name);for (Department dept : departments) {builder.append(" - " + dept.toString());}return builder.toString();}
}// 总公司
public class HeadOffice {private String name;public HeadOffice(String name) {this.name = name;}private List<Department> departments = new ArrayList<>();public void add(Department sub) {departments.add(sub);}private List<BranchOffice> branches = new ArrayList<>();public void add(BranchOffice branchOffice) {branches.add(branchOffice);}public void print() {System.out.println("总公司:" + name);for (BranchOffice branch : branches) {System.out.println(" - " + branch);}for (Department dept : departments) {System.out.println(" - " + dept);}}
}复制代码

利用这些层次的类来组成小光的组织架构:

public class XiaoGuang {public static void main(String[] args) {HeadOffice headOffice = new HeadOffice("小光热干面");Department financeDept = new Department("财务部");Department strategyDept = new Department("策划部");BranchOffice ov = new BranchOffice("光谷分店");ov.add(financeDept);ov.add(strategyDept);BranchOffice huashan = new BranchOffice("花山分店");huashan.add(financeDept);huashan.add(strategyDept);headOffice.add(financeDept);headOffice.add(strategyDept);headOffice.add(ov);headOffice.add(huashan);headOffice.print();}
}复制代码

结果如下, 达到要求:

总公司:小光热干面- 分公司:光谷分店 - 部门:财务部 - 部门:策划部- 分公司:花山分店 - 部门:财务部 - 部门:策划部- 部门:财务部- 部门:策划部复制代码

小光的思考

看着这新鲜出炉的架构程序, 小光总觉得哪儿不对劲儿. 毕竟小光是历经了北上广各种类型公司的人才啊, 回想起上班敲代码的日子, 小光想起了哪儿不妥了. 公司总会发展, 发展过程中总会有一些战略调整, 从而导致公司部门的各种变化.

目前小光设计的组织架构是三层架构, 但是随着公司的发展壮大, 很有可能层级会变得更多. 比如说, 总部的采购部壮大了, 可能会增加下一级的食材采购部和设备采购部. 甚至可能现在的层级还会随着公司的战略调整而升降. 例如, 如果分店开到别的城市了, 可能会在总部和分店之间插入一层"子公司"来分别管理各地的分店. 如下:

那么就出现了一个我们一直在强调的问题: 有些东西可能会一直有变化, 而我们从产品角度肯定会想要拥抱变化, 然而代码层面上我们又不想修改代码(修改原有代码意味着还有对原有逻辑负责).

那应该怎么办呢? 有没有更好的方式来表达这种树形的组织架构关系呢? 以便能够很容易地扩展层次呢?

小光又回想起了自己的码农时代, 回想当年这种问题的解决方案:

既然是因为变化, 扩展而引起的问题, 我们最重要是要先找出系统中可变不可变的部分, 封装不可变(使其修改关闭), 拥抱可变(使其扩展开放).

小光的解决之道

那么具体到这个组织系统架构的问题, 又该怎么做呢?

小光可不想每增加一个层级都要重新为其增加一个类, 然后改变原有系统. 特别是有些情况下, 曾加的类(子公司)中可能会包含分店和自己的部门. 随着类别的增加, 每次增加一个层级将会越来越难.

小光想到着, 突然想到:

每个部门/分店/子公司乃至总公司不都是部门的集合吗?
部门可能有下属部门, 可能没有
分店下有部门
子公司下有分店, 可能还有自己的部门
总公司下有子公司, 分店, 自己的部门

所以说, 所有实体(总公司/子公司/分店/部门)实际上都是由部门组成的. 这些实体也都可以看着是一个部门.

想到做到:

首先定义出基础的部门:

public class Department {private String name;public Department(String name) {this.name = name;}private List<Department> subDepartments = new ArrayList<>();public void add(Department sub) {subDepartments.add(sub);}@Overridepublic String toString() {StringBuilder builder = new StringBuilder(name);for (Department dept : subDepartments) {builder.append("\n");builder.append(" - " + dept.toString());}return builder.toString();}
}复制代码

来看下, 利用Department这一个类别怎么搭建组织:

public class XiaoGuang {public static void main(String[] args) {Department financeDept = new Department("财务部");Department strategyDept = new Department("策划部");Department ovBranchOffice = new Department("光谷分店");ovBranchOffice.add(financeDept);ovBranchOffice.add(strategyDept);Department huashanBranchOffice = new Department("花山分店");huashanBranchOffice.add(financeDept);huashanBranchOffice.add(strategyDept);Department wuhanChildOffice = new Department("武汉子公司");wuhanChildOffice.add(ovBranchOffice);wuhanChildOffice.add(huashanBranchOffice);Department changshaChildOffice = new Department("长沙子公司");Department xiaoguang = new Department("小光热干面");xiaoguang.add(wuhanChildOffice);xiaoguang.add(changshaChildOffice);xiaoguang.add(financeDept);xiaoguang.add(strategyDept);System.out.println(xiaoguang);}
}复制代码

输出如下

小光热干面- 武汉子公司- 光谷分店- 财务部- 策划部- 花山分店- 财务部- 策划部- 长沙子公司- 财务部- 策划部复制代码

输出稍有调整, 以显示直观的层级. 大家可以自行修改下代码, 来给department加入level属性, 以便输出更完美的结构.

到此, 我们算是解决了组织架构的问题了, 以后不管是增加了什么层级, 我们都只需要使用Department来表示即可, 而无需增加一个类了.

故事之后

照例, 我们来缕缕小光设计的这套系统的"类关系":

结构相当简单, 实际上就是一个类, 其中关键的是: 这个类中有一个list属性(subDepartments)包含的是一组该类. 有点递归的感觉.

这个就是我们今天想说的 --- 组合模式

组合模式
又叫部分整体模式,通过组合的方式, 创建一个包含了一组自己的对象组(List)的类(Department). 从而达成了用一个类来递归地表示一个整体.

组合模式通常用来解决树形结构的表达问题, 例如本例中的组织结构.
所谓组合的方式, 就是创建一个包含了一组自己的对象组的类


注: 我们这里实现的相对简单, 旨在说明模式的形式.
实际场景中, Department可能是一个抽象的, 例如有一个抽象方法来执行该部门的职责, 有不同的具体部门实现来实现其职责. 从而有不同的"Department实现"来组合另一个大的Department节点.

扩展阅读一

前面说到, 组合模式通常用来处理树形结构的表达问题. 而我们的用户界面实现通常就是一个UI元素的节点树. 例如HTML中的div中可能有button, 还会有其他div层级, 依次往下; Java SE中的界面实现AWT和Swing包也到处是组合模式的体现; Android中的View体系, View和ViewGroup, Layout层级树也都是组合模式的体现.

在此我们以Android的View体系为例, 简单描述下.
众所周知, Android的界面实际上就是一颗大树, Hierarchy Viewer中展示的就是一个树形结构. 我们来看下Android是怎么利用组合模式实现的.

如下:

  1. ViewGroup就是相当于例子中的Department, 这里面比我们的例子复杂的是, ViewGroup是扩展自View的, View实际上我们可以理解为是叶子节点, 也就是最小的组成单元了, 不再有以下的层级了.
  2. ViewGroup中包含了一组View对象, 因为ViewGroup是View的子类, 故而我们也可以说ViewGroup中包含了一组ViewGroup和/或View. 进入形成了我们之前说的递归, 生成一个树形结构.

关于View的体系, 在此不细述了.


搭建好弹性可扩展的组织架构体系, 小光又开始将眼光转移到市场, 转移到业务了, 准备着新年大展拳脚~

梳理公司的组织架构 --- 组合模式相关推荐

  1. Atittit.研发公司的组织架构与部门架构总结

    Atittit.研发公司的组织架构与部门架构总结 1. archi组织架构与 部门规划2 1.1. 最高五大组织机构2 1.2. 宗教事务部2 1.3. 制度与重大会议委员会2 1.4. 纠纷处理部: ...

  2. [创业-37]:公司的组织架构--所有者与决策机构(股东)

    目录 第1章公司的组织架构 1.1 什么是公司的组织架构 1.2 公司组织架构的类型 第2章 典型的上司公司组织架构 2.1 股东大会 2.2 董事会 2.3 监事会 2.4 总经理 补充:创始人.董 ...

  3. [创业-39]:中小公司的组织架构与公司管理

    作者主页(文火冰糖的硅基工坊):文火冰糖(王文兵)的博客_文火冰糖的硅基工坊_CSDN博客 本文网址:https://blog.csdn.net/HiWangWenBing/article/detai ...

  4. Apple苹果公司组织架构

    Apple苹果公司组织架构 这种模式,自乔布斯回到苹果时,开始实施,一直保留到现在. 今天,苹果大学校长兼副总裁 Joel Podolny 在<哈佛商业评论>上发表了一篇题为<How ...

  5. 98页PPT,看懂阿里、小米、京东、美团的组织架构和战略变迁!

    来自公众号:经纬创投 今天分享的这篇文章,来自方正证券发布的名为 "从组织架构视角出发,回顾四大商业巨头的战略变迁--阿里.小米.京东.美团"的报告. 这份长达98页PPT的报告很 ...

  6. python文件合法模式组合_python设计模式之组合模式

    最开始接触组合设计模式是在大话设计模式这本书中的案例,讲的是让你设计一个公司的组织架构,一个总公司下有人力资源部门,IT部门, 财务部门,还有广州分公司.深圳分公司,在分公司下也有IT部门和财务部门, ...

  7. c#设计12星座速配软件_C#设计模式(12)——组合模式

    阅读目录 1.组合模式 在软件开发中我们经常会遇到处理部分与整体的情况,如我们经常见到的树形菜单,一个菜单项的子节点可以指向具体的内容,也可以是子菜单.类似的情况还有文件夹,文件夹的下级可以是文件夹也 ...

  8. python 设计模式之组合模式Composite Pattern

    #引入一 文件夹对我们来说很熟悉,文件夹里面可以包含文件夹,也可以包含文件. 那么文件夹是个容器,文件夹里面的文件夹也是个容器,文件夹里面的文件是对象. 这是一个树形结构 咱们生活工作中常用的一种结构 ...

  9. 设计模式之禅【组合模式】

    真刀实枪之组合模式 从公司的人事架构谈起吧 公司的组织架构 从上图中可以分析出: 有分支的节点(树枝节点) 无分支的节点(叶子节点) 根节点(无父节点) 有了树状结构图,再看看类图长啥样吧! 这个类图 ...

最新文章

  1. 前后端分离nginx配置,同时解决跨域问题
  2. MapReduce统计排序和HDFS的读写
  3. Java内存管理和客户加载过程_Java内存管理的进一步理解-模拟过程图解
  4. ylbtech-LanguageSamples-Arrays(数组)
  5. CSDN Github Markdown编辑常用功能符号补充
  6. shell介绍 命令历史 命令补全和别名 通配符 输入输出重定向
  7. ssh 协议 java_java代码之SSH协议连接linux
  8. eclipse中ctrl+h默认打开是JavaSearch,怎么设置成默认打开是FileSearch
  9. BZOJ 3053 The Closest M Points
  10. 分析 Python 脚本
  11. 图神经网络:Graph Neural Networks
  12. VUE 下载文件流 文件无法打开,缺失数据
  13. 基于Modelica的船用大功率电推进系统建模仿真
  14. Kinect测量身高
  15. 使用国内的镜像源搭建 kubernetes(k8s)集群
  16. cocos shader 之 黑白滤镜
  17. lua 16进制转10 10转16进制
  18. 多文件断点续传,上传视频自动转MP4和截图,图片格式转换
  19. N多计算机精品免费视频下载
  20. Already included file name #2372

热门文章

  1. [机器学习基础][台大林轩田]机器学习概念
  2. 美团买单与微信分付入局后,蚂蚁花呗和京东白条地位不保了?
  3. 玉柴spn码故障对照表_BOSCH共轨系统EDC7_V47故障码列表_发布(含SPN和FMI).pdf
  4. 批处理一键打开Windows远程桌面
  5. 千巡科技再获千万融资,为何资本看好巡检机器人?
  6. 异常:java.lang.LinkageError: loader constraint violation: when resolving interface method “javax.servl
  7. 笔记本拆c面_继续拆解 C面下方还藏有玄机_神舟 战神GX8 PRO_笔记本评测-中关村在线...
  8. 元宇宙产业委通过央链直播召开第十次新闻通报会:第十一批入会成员名单公布
  9. JavaScript判断浏览器内核
  10. 关于AHB-RAM的一些内容1