侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

码农,你对自己开发项目了解多少?

人生(杂谈)  /  管理员 发布于 3年前   871

对于一个程序开发人员来说,对项目的熟悉程度意味着你对工作内容的掌握程度。那么你是否可以问一下自己,你对你的项目了解吗?

为什么了解

当然,了解是一个模糊的概念。同样,对于不同职责的人员来说,判断这个概念的准则是不一样的。而对于不同类型的系统来说,这个概念也有所不同。如果你是一位一线的代码工作人员的话,你可能对接的就是单独的几个领域服务的项目,那么了解他们的调用和库表关系可能就算了解了,你甚至能熟悉到哪个bug是在哪次版本迭代之后产生的;而对于一位团队的管理人员来说,尽管他可能对代码中的所有分界实现并不了解,但是他却能对业务的发展迭代了如指掌,比如那个功能特性依托于几个服务而来的。

抛开了边界,就无法做出回答,所以本文给出了这样一个定义,用来描述你对项目的了解程度这一概念:

拥有足够支撑对若干个具有互相依赖关系的项目进行重构的熟悉程度。

显然,这个对于一线开发来说可能较为苛责,却又并不是管理人员依靠单纯的业务跟踪就能了解的。所以我觉得,对项目的了解是需要从业务层面和coding层面两方面了解的。

怎么了解

只是有一个定义,对概念的支撑仍然略显单薄。但是换一个角度来说,如果定义是足够支撑重构的话,那么显然需要掌握以下几个东西:

1. 对原有业务足够了解;

2. 对原有代码足够了解;

3. 对原有项目的下游支撑足够了解;

4. 对业务的上游影响足够了解;

业务是本身非工程性质的,而上下游和代码本身则将你的项目包裹起来,我们划分了边界,先保证不会有东西遗漏。但尽管进行了目标拆分,它仍然是一个抽象的过程。因此我们需要一个Check List,从而确保当我们完成了这个列表之后原则上有能力可以守护住这些边界。

那么我们的Check List如下:

1. 用例视图

2. 领域模型

3. 数据库设计

4. 接口、代码数量、代码库

5. 微服务和领域划分

6. 微服务拓扑

你可以看到,上面的内容是基本涵盖了业务,以及代码的上下游(库表)的依赖关系。当然,如果你并不是一个后端项目、或者并不是一个微服务项目,那么这些Check List可以根据你的实际情况进行调整。

尝试了解

大家的项目细节可能不同,本文仅以其中一个角度进行分享,用于提供思虑。对于已经明确了的Check List我们下一步要进行的就是梳理工作了。

用例视图

用例视图的目的是对业务的一种收敛,以当前时间维度的角度,对过往的若干需求进行重新评估。除了和已有功能需求相对应的用例外,经常出现的是两种额外状况:

发现某个功能已经没有用例了。

发现两个功能的用例是一样的。

对于前者来说说明这个功能因为无法匹配用例,说明他是无效的了,那么如果重构的话,这部分的功能是可以不予理会的。对于后者来说,用例相同的情况下,说明两个功能其实是可以进行抽象的,通过调整参数,或者进行底层复用,两个功能合并成一个功能(不过要确保两个的用例确实一样)。

同时,用例图可以辅助梳理用户们的实际需求,进而描述了业务。

领域模型

领域模型的构建,主要是通过模型将复杂的领域逻辑以模型的概念和模型元素的形式清晰地表达出来。在项目长时间的进行开发和迭代的时候,不可避免地出现很多意外的情况。而重新梳理领域模型的目的,就可以从长时间迭代的(已经腐化的)代码中重新构建模型的关系。

举例而言,当我们在第一版本的时候随意地开发了一个短信发送需求,功能开发完毕了之后可能设计了一个短信模版表。而后来又有了新的需求,要对用户进行手机的push推动功能,再后来就可能是内部人员的钉钉或者飞书通知功能。那么对于以上的需求,我们发现可以抽象出来一个新的领域模型。

通过对领域模型的重新确定我们可以用新的模型去检验项目内部中的实体抽象、功能复用的情况是否理想,从而确定对于该项目是否需要写。

数据库设计

经过领域模型的梳理后,我们可以确认数据库的库表设计是否和领域实体一致。如果不一致则可以考虑进行调整或者重新设计(但是要考虑双写成本)。和领域模型一样,由于业务的发展,很多时候我们在进行数据库设计的时候 都无法预知到后续的业务方向变化,没有足够恰当的抽象的情况下,其结果可能就是会产生不那么优雅的解决方案:

对一些数据库通过添加字段的形式完成需求

通过对相类似的表的copy的形式来实现需求(xxx_order,zzz_order)

无论哪种原因,都会导致数据库中的实体内容不纯粹,导致后续扩展性降低,或者业务开发工作量变大。

数据库设计也可以从最底层的角度上看到业务的边界,因为最底层的支持数据是通过数据库完成的,如果数据库不包含其中的数据,则说明在业务中产生的数据是通过非本系统持久化的方式获得的,可以一定程度上认为是中间数据。同时数据库上的引用分析也可以暴露出领域服务是否干净,是否有直接使用非自己领域的实体表数据。

接口、代码数量、代码库

接口一般可以从api的分组上体现用例的关系。同时每一次接口的调用可以视为一次数据流传(cosmic功能规模度量方法),可以通过接口数量的规模对软件开发工作量进行评估。与此同时,代码行数则可以直观地表示出项目的大小,也是评估工作量的体现。而代码库则可以根据软件迭代总时长,和commit的次数,判断出项目的腐化程度,和业务耦合难度。

微服务和领域划分

如果你的项目里有微服务的话,那就要确认一下微服务之间和领域模型之间是划分明确。同样的,划分不明确的问题经常会出现在持续迭代的过程里,例如当新添加的一个功能由于某些不可抗原因被添加到了错误的服务里,而后续依赖这个功能的服务直接引用了后,这个功能就再也分不开了。另一种情况是,微服务之间的领域关系一开始是明确的,但是由于业务的转型,在逐渐地迭代工程中,会有一些模棱两可的功能被添加到了看起来所属的服务中,但当后续的业务转型完毕后,新的服务划分出来,但是老的功能却留在了那里。

但不论怎样,当我们分析出微服务和领域模型的划分关系后,我们就知道了哪些看起来位置不对的功能到底应该放到哪里了。

微服务拓扑

当我们分析完了所有服务向下依赖后,我们就能得到一张所有服务间的依赖关系拓扑图(DAG图)。那么,这种拓扑图中是否存在环结构就是关键了。如果你发现所有服务间调用的关系是一个完整原型,那么恭喜你,你需要好好地设计一下了。但如果仅仅是简单一个环,那说明只有少数服务存在循环依赖问题,我们可以针对这部分依赖进行拆分,为循环依赖部分寻找一下新的归属,或者直接将其拆解成一个新的服务。

最后

完成了CheckList的梳理,我猜你会惊叹于自己原先的设计是多么完美,又或者想吐槽原来的开发人员是多么不守规矩。

但不过无论是哪种情况,梳理完毕的你我猜已经对你的项目有了一个大概,即便无法进行项目的重构,至少在别人再问起你为什么开发要这么长时间的时候,你就可以很硬气的怼回去“这项目我了解,就是要这么长时间啊!”。


  • 上一条:
    为什么你不能安逸?国内996为什么没有国外955香?
    下一条:
    为什么php还没死?PHP正在干掉Python,来自csdn的一篇译文
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • 欧盟关于强迫劳动的规定的官方举报渠道及官方举报网站(0个评论)
    • 学历:一种延缓就业设计,生活需求下的权衡之选(2个评论)
    • 戒毒的程序员Andreas Kling,全职开发操作系统6年后,决定转战浏览器(0个评论)
    • Gap Year:中国环境下的优缺点及建议(0个评论)
    • 翻墙与VPN软件的合理使用:劝告与建议(0个评论)
    • 近期文章
    • 在go中实现一个常用的先进先出的缓存淘汰算法示例代码(0个评论)
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 欧盟关于强迫劳动的规定的官方举报渠道及官方举报网站(0个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf文件功能(0个评论)
    • Laravel从Accel获得5700万美元A轮融资(0个评论)
    • 在go + gin中gorm实现指定搜索/区间搜索分页列表功能接口实例(0个评论)
    • 在go语言中实现IP/CIDR的ip和netmask互转及IP段形式互转及ip是否存在IP/CIDR(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2016-10
    • 2016-11
    • 2017-06
    • 2017-08
    • 2020-03
    • 2020-04
    • 2020-06
    • 2020-08
    • 2021-04
    • 2021-05
    • 2021-06
    • 2021-07
    • 2021-08
    • 2021-09
    • 2021-10
    • 2021-11
    • 2021-12
    • 2022-01
    • 2022-02
    • 2022-03
    • 2022-04
    • 2022-05
    • 2022-06
    • 2022-07
    • 2022-08
    • 2022-09
    • 2022-10
    • 2022-11
    • 2022-12
    • 2023-01
    • 2023-02
    • 2023-03
    • 2023-04
    • 2023-05
    • 2023-07
    • 2023-08
    • 2023-09
    • 2023-10
    • 2023-11
    • 2024-02
    • 2024-04
    • 2024-05
    • 2024-06
    • 2025-01
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客