为什么选择DSL(中)

好的代码

要说清楚DSL能带来什么,先要理解需要什么。一份好的代码,应该满足下述属性(重要程度递减) :

1.正确

它需要实现当前所需的功能,可以正常工作。

2.可扩展

对于新的需求,代码应该容易扩展,它的变动成本应该尽量小:这个成本应该包括设计、编码、测试、故障修复等全流程的成本;

可以想象后端的成本往往比前端要大,特别是缺乏良好设计的情况下。一般资源前移,投入更多的资源在设计、编码上,是合适的策略。特别是对于注定的大型项目更是如此。但对于前端的投入需要有明确的实施或评判标准。

3.可读

可读和可扩展看似会有冲突。想要维护高度抽象、有良好分层结构的代码一定需要付出相应的学习成本。它不会那么”好读”。即便冲突,也应该首先保证扩展性。

保证扩展性的情况下,代码结构应该良好的组织结构,命名应该更加准确,以便于理解。长远的看可扩展性和可读性并不冲突,缺乏抽象的代码既不会好读更不会容易扩展。

4.没有多余的部分

不要实现那些还没有发生的需求。

如果通过对领域知识的了解,你已经知道某些变化方向一定会发生,只是这几天或者这个版本还不需要实现这些功能。那么就需要提前考虑这些变化方向,避免后续推倒重写。特别是,对于架构师来说,决不可能也不应该对系统的变动和演进一无所知。

这一点描述的实际上是应该避免过度设计。相对来说重要性较低。一个事实是,缺乏设计的代码比比皆是,过度设计的代码在实际工作中比较少见。

有时正确性被视为外部质量,扩展性、可读性和没有多余部分被视为内部质量,衡量内部质量的标准是变动成本,评价外部质量可以用客户需求的满足度来看,有些时候也可以用故障率来描述。内部、外部质量从长远看,是一致的。不易扩展的代码,它不可能长期正确。我们需要时刻牢记“变化”是客户对软件最核心的需求,没有之一。


软件设计落地遇到的问题

软件设计的核心目的是提高系统的可扩展性。具体的方法很多,高内聚/低耦合;XP;SOLID原则;设计模式;clean code + refactoring;TDD;DDD….这个药方还可以开很长。都非常有道理。但实际落地的过程中,会面临一些问题,包括:

1.软件设计原则和方法难以有效的大范围推广

SOLID\CC\设计模式\TDD等莫不如是。究其原因:

a)难学。是对代码设计有追求的人其实并不多;包括喜欢coding的人,也往往对设计没有兴趣(实现功能和以良好的扩展性实现,本来就是不同的事情);工作中,公司\项目更是未必会给员工大量相关的培训机会;何况也未必有合适的老师;

b)难用。良好设计带来的是长远的好处,而且需要长期的坚持,眼前就要给予相当的投入总不是特别令人愉悦的事。原则的理解,模式的选择非常依赖个人的能力,缺乏非常具体标准和具有一定强制力的手段。类似代码走查,结对编程这种方法,道理上有用,但对于大型项目(数百人)能成功坚持的罕见。代码走查,对保证业务逻辑可能有用,但对提升设计很难说有用。一言以蔽之,没有标准。单一职责,开放封闭都只能是理想。还可以用一些强制手段,比如用自动检查工具,度量函数行数,和圈复杂度,甚至检查一定程度的重复代码。从结果进行约束可以倒逼设计,但既不能逼出良好的设计,同时整个系统在逻辑上仍然会缺乏一致性;

既难学,且难用,不能形成正向反馈,成功推广自然是缘木求鱼。

2. 对人员能力不同要求难以拆分到角色

对于某些系统(比如通信系统),我们希望程序员有下列技能,业务能力、软件设计能力、高性能编程能力(对芯片和内存系统的亲和性)、组织协调能力。哪一点做透到都很难,何况都懂(顺便说一句,别随便就说自己精通c/c++/Java)。

人类自工业化以来,亚当斯密指出的分工带来效率,无数次的被证明有效,分工合作是正途。可以尝试去建立学习文化,学习型组织,软件设计落地寄希望于此就有些一厢情愿了。

如果不能有效的将不能能力需求拆分到角色,一定会有某些能力(价值被放弃)。而这些要求要求中,看起来软件设计能力是最容易被放弃的。

但如何有效分解,实际上并不容易。可以考虑建立不同的角色,架构师,业务分析,软件设计,开发等。但他们之间的工作边界并不容易厘清,前一级的工作内容很难有效的传递到后一级。须知,文档从来都是不靠谱的。

分解对人员能力的要求,带来的另一个好处是,抵御人员流动,这也是非常现实的问题。

下一部分讲如何以DSL为突破点,并采用相应的方法族实现有效良质的软件设计,并且据此分解对人员能力要求,并有效传递不同分工间的工作成果。

一个预警: DSL不是银弹,不是一种能独立发挥巨大作用的技术。它需要丰富友好的其它设计方法配合,比如包括抽象领域概念建立领域的视图,分层,模块化(意味着清晰的边界),以及通过各种方式对系统进行有效的拆分和组合。它只是众多工具/方法中的一种,但它有希望成为改善软件设计的突破点。

你可能感兴趣的:(为什么选择DSL(中))