小当家ISV
互联网高新技术服务商

全球共有10多个国家和地区1000多个平台,20万+商户使用

软件设计不是CRUD(6):低耦合模块设计实战——组织机构模

作者:    陈国庆       发布时间:     2023-12-29          1396      分类专栏: 后端开发

组织机构功能是应用系统中常见的业务功能之一,但是不同性质、不同行业背景、不同使用场景的应用系统对组织机构功能的要求可能完全不一样。所以使用这样的功能对低耦合模块设计进行示例性的讲解是比较具有代表性的。在后续的几篇文章中,我们会首先进行示例的详细讲解,然后再基于这个示例进行理论讲解。

1、组织机构模块需求

目前X公司研发的标准产品中有一个组织机构功能模块,这个模块提供一个最基础的组织机构功能实现:这个组织机构中的每个组织机构节点都有一些基本信息(编号、中文名、排序号、创建时间Q、创建者、修改时间、修改者、国家编码等信息),每个节点除了可以关联用户信息,还可以关联下级组织机构节点。整个组织机构的数据可以组成一棵无限极的树结构,如下图所示:


不止是组织机构对于下级组织机构的关联问题,客户还明确要求由于客户所在企业有许多种不同类型的人员(例如企业领导、普通职工、外聘人员等),所以如果有可能还要求在这个无限极的组织机构树结构中,能够设定不同的组织机构类型可以关联的人员类型。不过这个需求点客户也明确告知,不要求本期迭代中一定包括对此需求的实现,因为客户方本身也没有梳理清楚目前的用户类型怎么划分比较符合自身业务情况。但客户方明确要求研发团队一定把扩展点预留出来,以便确认需求后能够快速加不同类型的组织机构和不同类型用户的关联。这个无限级的树结构在查询的时候还需要支持正向查询和逆向查询。正向查询很好理解,就是给定一个节点,然后查询这个节点直接关联的用户信息Q和直接关联的下级组织机构节点信息;逆向查询的功能是说给定一个(或多个)用户或者一个(或多个)组织机构,查询这些信息直接和间接关联的上级组织机构信息直到根节点,最后反向形成一个完整的树形结构。

 

另外,为了加快查询速度,组织机构的树形结构还支持编码降维处理。例如子公司的编号为51,部门的编号为01,团队编码为06,这样三级组织机构的完整编码为510106。这种编码方式可以进行快速查询,例如查询某个部门下的所有直接和间接关联的下级组织机构,并用列表进行显示。


这样的组织机构功能基本上适应于大部分的业务场景,但是也不能排除将标准产品提供的这个组织机构功能应用到具体项目时,项目的客户对组织机构功能提出新的需求(需求变化诉求):

 

组织机构需要有类型的标识,组织机构不同的类型,字段完全不一样,有的组织机构类型甚至不能包括用户信息。不过组织机构都有业务编号和显示用的中文名。不同的组织机构类型可以关联的下级组织机构类型不一样,例如A类型的组织机构只能关联B、C两种类型的组织机构作为下级组织机构。

 

有的项目团队,需要屏蔽一些不需要使用的组织机构类型。例如标准产品中的这种最基础的组织机构类型,但是这种组织机构类型在一些特定项目中基本不适用,所以需要去掉。

 

有的项目团队,因为有特别的查询要求,所以需要新增组织机构的查询功能。例如有的项目团队自己新增的组织机构类型中,有一个和特定业务相关的属性叫做“出口目的地”的字段,项目团队有需求根据这个字段进行特定组织机构类型的查询(查询结果需要包括直接关联的子级组织机构的信息)。

 

有的项目团队开发的应用系统,由于某种组织机构类型的数据特别多,所以这种组织机构所使用的两位编码不够用,需要将组织机构的编码位数从两位提高到三位甚至四位。

 

还有其它未知的变化——由于项目客户的问题,一些组织机构功能的详细需求变化点还不能确认,但是这些变化点也只会集中在两个方面:对不同组织机构类型的模型字段进行调整,以及对不同组织机构类型的查询功能进行调整。

 

2、一般的设计开发过程

针对以上的组织机构模块的需求,以及目前了解到的项目团队对该模块的变动诉求,我们来看一个可能出现的功能模块设计方案。这个设计方案也是目前绝大多数应用系统在进行功能模块设计时所使用的设计方式。

 

2.1、构建脚手架

为了保证模块开发的顺利进行,开发人员会首先搭建一个开发脚手架,这里我们以普遍使用的Spring Boot + Maven的方式给出示例脚手架(笔者在实际工作中更喜欢使用gradle):


以上是一个读者再熟悉不过的简要的脚手架工程了。我们先不急着讨论这样的脚手架规划有什么问题,但其优点是显而易见的,就是简单、便于理解。其中一些包中的代码本文会在后续的内容中逐渐进行填充。

 

entity:这个包中,我们用来放置数据库对应的持久层模型

mapper:如果开发人员使用MyBatis进行数据持久层的实现,那么推荐专门用一个mapper包放置XML映射信息和持久层接口定义,如果使用JPA则不需要(推荐使用JPA,虽然使用门槛要高一些)。

repository:模块内对数据持久层的功能调用,放置在这个包中。

service:这个包中,我们用来放置专门提供给外部调用者使用的调用功能

po:这个包中,我们用来放置业务模型,由于业务模型和数据模型在复杂功能模块中往往存在差异,所以数据模型和业务模型在这个示例中分开进行设计(实际工作中也推荐模块内不同层面的模型分开设计)。

config:spring-boot的配置信息,环境配置信息等。

其它包的创建和使用,将随着内容的深入逐渐增加。

 

 

所属分类: 后端开发
GPT-5、开源、更强的ChatGPT!
【GoLang】Go语言几种标准库介绍

小当家,帮您把生意越做越大!

小当家ISV,重庆APP开发,小程序开发,软件系统开发 地址:重庆市南岸区南坪万达广场写字楼2栋19-6 联系电话:023-81361879

ICP备案号:渝ICP备15003473-1 增值电信业务许可证: 渝B2-15003473 渝公网安备 50010802005103号

友情链接: APP定制开发  小程序定制开发  MagicShop商城系统  酒类行业解决方案 

重庆小当家互联网信息技术有限公司