领域驱动设计——柔性设计

一、柔性设计

谈到柔性设计,那么什么是柔性设计?柔的反义词就是硬。记得在早年看国内报道说德国生产技术厉害,有柔性生产线。柔,就是柔软,硬,就是坚硬。那么意思就来了,柔性,就意味可以在一定的范围内随便改变形状;反之,硬性就不行。一用力,不是断了就是永久变形无法再次使用。而生产线上,机器的设计一般都是针对具体的生产工艺和产品定制的,也就是趋于硬性。而所谓柔性生产线就是把一些有较小范围调整的机器组合在一起,通过计算机管理形成一种较大范围的可调整的生产线。这样说,可能不好理解,说的直白一些,就是原来只生产一两种零件的生产线改成柔性生产线后,可以生产一两类零件。这样,就大大增强了机器设备的重用和生产线的重复利用,提高生产效率,降低生产成本。
顺延,领域驱动设计中的柔性设计类似。“为了使项目能够随着开发工作的进行加速前进,而不会由于它自己的老化停滞不前,设计必须要让人们乐于使用,而且易于修改,这就是柔性设计(supple design)”。柔性设计其实就是增加软件的弹性和可扩展性的一种设计方式。当然再柔性的设计也是有其范围的,所以一定不要为了柔性设计而设计,始终在大脑里要防范着过度设计。

二、相关方法策略

那么,柔性设计有这么多的好处,怎么才能够做好一个柔性设计呢?有没有一些好的方法或者策略。答案一定有。主要有以下几种模式设计可以实现:
1、释义接口(Intetion-Revealing Interfaces)
这个怎么翻译都可以,但得明白它的意思。所以Intetion-Revealing Interfaces其实是编程界一直提倡的源码自说明。也就是说,看到这个接口,从字面上就应该知道他是干什么的,有什么作用。这个确实很难,真的。一个两个接口,一个两个程序可能做得很好。但推广开来后,软件开发人员的参差不齐,对技术理解和对接口开发本身都不明白的开发人员,如何定义一个自说明的接口,这简直就是一个无法逾越的高峰。
这个想法不错,但实现有很大的困难。特别在国内,一味追求速度和结果的氛围下,这个就更为难能可贵了。

2、无副作用函数(Side-Effect-Free Function)
这个其实也就是平常经常遇到的职责单一原则的一种实现形式。函数的实现一定要功能单一,不能把更改动作和显示动作的功能实现在一个函数内,不能让函数的运行在不同的参数下可能产生不同的效果。尽量不返回内部的领域数据并且实现幂等。而确实有可能产生副作用的函数要封装到Value Object中去。
这个无副作用函数其实就是要求函数功能简单、单一、幂等并且没有复杂的返回值。

3、断言(Assertion)这三个模式
断言这个词明显就是一个测试用的,它其实是要求对前两个进行测试保证其目的能够正确达到。其实就是对规则和条件的判定结果,如果无法编写就得上测试。它除了强调数据上的正确还包含有逻辑上的正确。

4、概念轮廓(Conceptual Contour)
软件设计的一个基本要求是高内聚,低耦合。那么事情来了,到底怎么样才算是高内聚、低耦合。是按函数还是按类还是按功能来划分?要知道软件设计的场景是千差万别,应用的实际过程也是不断演进和变化的。这映射到设计人员,排除过程的认知偏差和沟通误差,仍然需要一个不断重构的过程。而这其实也是一个职责单一的设计过程,也即一个粒度划分的问题,掌握好一个粒度的大小的度的问题,既不能过粗更不能过细。

5、单一类(Standalone Class)
单一类重点是降低耦合的。在实际的开发中,如果一个模块需要反复调用多个模块,而多个模块间又需要互相调用,一旦有问题,解决的难度可想而知。而假如一个模块只调用另外一个模块的接口一两个接口,出现错误相对来说就非常容易找到问题的所在。可现实世界和理想世界总是存在差距的。一方面软件要求实现强大的功能,另一方面设计又要求功能间尽量隔离。这本身就是一个悖论。
那么如何解决这个问题呢?其实就是一个根据实际情况进行互相妥协的结果。在某些基础的软件上尽量低耦合,在一些变化丰富的上层应用中可以适当降低一些耦合度。具体的把握就需要设计和开发人员的经验和理论知识了。在前面提到过的Module和Aggregate就是为此服务的。

6、闭合操作(Closure Of Operation)
闭合操作,也可以理解成闭包。其实就是一种低耦合的控制方式。在设计过程中,如果把一种行为控制在一个抽象类型之中,换句话说,行为的动作不会引起依赖的动作发生。正如两个整数相加仍然是整数一样。

很多人可能看上述的模式和策略头脑一片雾水,这就对了。这就和学计算机开始学各种原理一样,没有实际的东西的对比,很难有一个形象上的认知。而形象上的认知往往是绝大多数人认知的一个最基本的前提。所以学习设计,学习原则,学习各种模式、策略,要有一个前提,就是编码量。换句话说,编码量越大,就越容易理解这些设计的手段。正如前面所讲设计是从哪里来,就是从编程的实践中总结、抽象而来的。

三、声明式设计

声明式设计有不同的理解方式,但是一般指一种编程方式:
把程序或程序的一部分写成一种可执行的 规格(specification)。使用声明式设计时,软件实际上是由一些非常精确的属 性描述来控制的。声明式设计有多种实现方式,
声明式实现比较觉的实现方式有反射,学过Java、Go等语言的同学应该立刻就清楚了。而在c++和C中可以通过宏机制在编译期动态生成控制代码,这个在MFC中就大量使用了。
相比于上面的断言判断和命令式的方式,声明式设计更灵活并大量减少重复性的操作。
但是这不代表声明式设计就完美无缺,一般来说,声明式设计的的可扩展性和代码可重利用大大降低,而且对声明设计不熟悉的往往或引入较多的副作用的效果,这些都需要在实际应用中高度重视。

四、实际中的应用

在实际中的应用,其实有各种手段,每个开发人员的水平和方向都有千差万别,所以这里不强调必须如何,而是应该按照自己的实际情况来引入。
在闭合操作中,c++中可以使用闭包函数,其它一些语言如Scala等可以使用函数式(链式)编程。单一类可以使用库或者模块,函数上的设计就更简单了,没最简单只有更简单就是实现原则。
而正如前面的提到 反射、宏定制、模板等等,都是解决问题的实际手段,是这些原则的灵活应用,至于能否用得好,就看具体的设计开发人员的能力大小了。
尽信书,不如无书。

五、总结

软件设计的目的是什么?一定是为了更好的进行软件开发,一定是为了更好的服务于开发人员并最终服务于所有的使用人员,这个目的一定不能偏离。有很多的开发人员或者架构师在实际的软件设计开发中,一味的强调技术的先进度和复杂性,甚至一味的追求新、难的技术。这也是网络上语言歧视链的产生的根源即他们已经放弃了软件的开发的初衷,而为了技术去学习和应用技术。
用一句高大上的话来说,“不忘初心,牢记使命”。这才能真正的学好软件技术。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值