一周技术思考(第31期)-高效率不代表高质量

 大家好,这里记录,我每周读到的技术书籍、专栏、文章以及遇到的工作上的技术经历的思考,不见得都对,但开始思考总是好的。 

1、

在一个业务快速发展的企业里面,如果你对自己部门的研发人员做一个调研,问下他们的大部分时间是在开发新功能,还是在修改老功能。

 

我可以肯定地告诉你答案,他们大部分时间都是在开发新功能。

 

开发一个新功能用了什么设计方法呢。

 

我们都知道,“将用户的需求转化为软件代码的过程是软件的分析设计过程”

 

这个过程,我们一般有两种设计方法,一种是ER数据建模法,另外一种是面向对象建模法

 

为了快呢,我们自以为所有的行为最终操作的不都是数据么,然后,理所当然地,采用了ER数据建模法,直接将实体表和表之间的关系设计了出来。

 

而且每当我们的研发人员完成一个或者一些新功能的时候,就会感叹一番,“经过加班加点,总算把这波需求做完了”。但是,这可能不是一个结束,而是一个开始,一个可能的“噩梦”的开始,我们为了赶工期编写出的代码质量到底如何呢

 

有的代码只考虑了当前功能的实现,没有考虑功能的扩展,当需要对现有功能实现扩展时,却发现难以下手。

 

从设计角度看,业务领域中的业务对象是定义业务行为的一种结构;数据表模式是定义业务数据的结构。它们一个注重业务的行为,另一个注重业务的数据,着重点不同,导致设计要求不同,也正是出于不同的设计要求才有对象和数据结构这两种不同的实现方式。通常,数据表结构一旦形成,就不会因为一个特定的应用而进行调整,它必须服务于整个企业,因此,这种结构是许多不同应用之间平衡的选择;而使用“对象或类”这种结构可以针对具体应用进行设计,将业务行为放入“对象或类”中,这样更能精确反映领域概念,保证业务规则的真正逻辑一致地实现,这是面向对象分析和设计(OOAD)的主要优点之一。

 

如果在一个复杂的业务环境下,不考虑真实的业务对象描述,而是直接面对数据,那么我们很可能就会出现这样的情况:一边开发功能,一边产生了债务。

 

2、

技术负债:增加新功能所需要的额外成本。

 

需求很多,实现一个,却不知道在众多的文件中,到底在哪个地方添加,一旦添加进去,转眼一想,好像其它地方也需要加上这段逻辑。

 

BUG很多,修复一个,却引起其它很多地方连锁反应,结果导致整个系统崩溃,如果一个不修复,系统反而能正常运行。

 

以上这样的情况,就是我们常说的代码出现了臭味,这种情况在《敏捷软件开发 原则、模式与实践》这本书中有详细描述,书中阐述了代码的7种臭味,大家可以去翻一翻。

 

这种情况发生,更是软件质量低下的外在表现。

 

有的同学说,等用户提需求的时候,我再进行代码质量提升,用户永远也不会提这样的需求。

 

一个系统应用的软件代码质量,我们的用户是不关心的,因为他们完全感知不到

 

软件的代码质量是透给研发团队内部的人员看的,只有他们,也应该是他们来关心。而恰恰是这样的原因,在一切以用户为中心的团队里,我们总是追逐快速上线,一味满足最终用户的“口味”,当然这样也没有错,一家企业如果不以用户为中心,那最后肯定没有持续的发展潜力。

 

但是呢,一家企业,如若要长期对用户负责,肯定要回过头来,重视代码质量,因为,代码质量才是“长治久安”的法宝。再也不要说,我们的用户都没有提出代码改进的要求,这样的自欺欺人的话了,因为我们的用户,永远不会关心我们的代码,只有我们自己要关心代码质量

 

3、

业务复杂了,代码增多了,代码质量降低的风险就增大了。

 

毫无疑问,一个大型的系统肯定比小型的系统复杂的多,问题空间的复杂性是天然存在的

 

天然的复杂性是无法消除的,这点在上周的文章中也提到。

 

我们在日常的研发中,时常有这样的经历。产品经理提了一个需求,也写了PRD,研发人员当时也一起评审通过了PRD,但是,在后续开发写代码的过程中,却又发现原先的需求描述的有问题。

 

越是需求复杂的环境,这样的情况发生的概率越大。

 

当需求规模比较大时,需求内部之间可能会发生矛盾,有些矛盾隐藏的非常深,可能只能通过代码实践才会发现。

 

但是,这种代价非常高。

 

怎么办。

 

你说,我用上面提到的OOAD进行分析设计可以吗,可以,但是不彻底

 

我们来看下,其实OOAD是两个动作,OOA(面向对象分析)和OOD(面向对象设计),如果分析阶段中形成的成果不能顺利导入设计阶段,同时,在设计的时候又引入了太多的细节而又歪曲了分析的成果,那么分析和设计之间就出现了裂痕

 

为什么会这样呢。

 

其实是它们各自的导向目标不同。

 

分析人员的目标是从需求领域中收集基本概念,是面向需求的,而设计人员则不同,他们负责用代码实现这些概念,因此必须指明能在项目中使用编程工具构建的组件,这些组件必须能够在目标环境(比如Java)中有效执行,并能够正确解决应用程序出现的问题。

 

那么,有没有一种工具式的方法论呢,既能比ER数据建模更加面向业务,又能够弥补OOA和OOD之间的天然裂缝

 

有。

 

DDD是专门解决复杂业务逻辑的方法论。

 

我在亚马逊网站搜索电子书的时候,看到有一位网友,写了下面这个评语,我个人觉得很是贴切。

 

如果你负责的项目经过一期、二期、三期建设,时间跨度超过8年,项目组的人换了一批又一批,部分一期的业务逻辑隐藏在代码之中,没有人能说清楚;每次变更都心惊胆战;应对用户的需求,项目交付周期越来越长;即使经过测试、上线后也经常鸡飞狗跳、项目质量下降,如果你想解决这些问题,推荐学习DDD的设计方法。

 

我觉得用不到8年。

 

关于DDD学习资料的推荐,对于刚开始进行学习的同学,建议优先读国内作者出版的书籍和专栏,比如张逸老师的《解构领域驱动设计》,彭晨阳老师的《领域驱动设计全面解析与实战》,然后再读国外的书籍《实现领域驱动设计》、《领域驱动设计》。

 

4、

领域驱动编程中,建议我们对业务复杂的领域编程的时候采用充血模型设计。

 

这让我又想起了关于面向对象的类和纯数据结构的对比定义。

 

于是,这周搜索资料,想看看过去人们对此有无更清晰的描述,结果,发现了下面关于类与数据结构的描述,感觉很精准。

 

在类里面我们的行为会主动操作数据,是主动的;而数据结构里面,就纯粹是数据,这些数据等待行为来操作,是被动的;

 

另外,下面是Bob大叔之前在《类与数据结构的比较》这篇文章中的阐述,摘抄如下,更多内容大家可以搜索这篇文章。

 

1)类和数据结构是彼此相反的。

2)DTO或数据库表都是一种数据结构。

3)对于类来说,增加一个新的类型很方便,不需要修改原来的类型,但是增加新的函数方法需要修改原来的类,因此需要各种设计模式。

4)对于数据结构来说,增加一个新的函数方法很容易,不需要修改原来的数据结构,但是增加一个新的类型很不方便,需要修改原来的结构。

5)它们与依赖关系有关。类将调用者与重新编译和重新部署隔离开来了,而数据结构将调用者公开给重新编译和重新部署,因此重新编译和部署比较难,特别是需求变化快速、迭代频率增加时,交付效率降低。

 

1)2)理解起来很容易;

3)是说我们的类对象可以继承也可以实现,这样新增一个类的时候是不需要修改原先的类对象的;

4)是从纯数据结构上面来说的,比如数据关系ER图,你要修改一个数据字段类型,就必须要改变原来的结构;

5)其实是从贫血和充血模型上的角度来考虑的,关于这些,大家可以看上一周的文章。

 

5、

总结下,处理复杂业务场景的三个方法。

 

1、抽象

2、分合

3、转化

 

如何理解呢。

 

抽象

 

抽象是面向对象的基础,使用抽象能够精简问题空间,而且问题越小越容易理解。比如,我要去北京环球影城,就可以理解为我要通过使用交通工具前往,但不必考究,我是做地铁,公交还是自驾。

 

分合

先说分。

 

把问题空间分割为规模更小且易于处理的若干子问题。分割后的问题需要足够小,以便一个人单枪匹马就能够解决他们;

 

再说合。

 

其次,必须考虑如何将分割后的各个部分装配为整体。分割得越合理越易于理解,在装配成整体时,所需跟踪的细节也就越少。即更容易设计各部分的协作方式。

 

评判是否分合得好,即看高内聚低耦合。内聚是为了分,耦合是讲分了之后要低耦合

 

转化

 

就是,将我们所学到的知识应用到上面得抽象和分合过程中,比如DDD就是一种工具方法论,我们利用DDD将我们生产实际中的问题进行抽象和分合。

 

 

6、

本周翻阅《李诞脱口秀工作手册》这本书,看到下面一段话,将其摘抄如下,大家根据各自的履历经验来判断所阐述的观点。

 

“工作的本质是交易,我们在用自己的时间和才能,通过一家公司,与市场交换金钱。”

 

为什么是交易呢。

 

根据诺贝尔经济学奖得主科斯的著名理论,公司会产生的原因,就是人们自己直接与市场交易成本太高,公司会给大家省点劲。那也就是说,当你跟公司交易,比你直接跟市场交易还费劲时,你就可以离开这家公司过更好的生活了。

 

 

恭喜你,又完成一次思考。

 

参考资料:

彭晨阳. 复杂软件设计之道:领域驱动设计全面解析与实战

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值