这个话题来源于下午和同事们的讨论,背景是这样的:他们在一个小项目上工作,周期是4周,
如何把握系统设计的尺度
。第一周是第0个迭代,主要的工作为写Story,做Spike等。而此后便开始开发,前几天开发的速度比较慢。因为他们经常在写了一些代码后又觉得,恩,结构设计的不够漂亮,中间应该加一层之类的。所以大部分时间都在推翻设计,修改以及添加测试,重构代码,分解依赖,运行Build脚本,提交代码。问题就出现了,敏捷开发强调的是简单设计,Pair拿到一个Story的时候,分析业务需求,简单的讨论设计(大概15-20分钟),然后进行开发。在开发过程中发现有重复代码,进行重构,一切重复代码都得重构,包括测试。最终的结果就是,完成Story的时候,没有重复代码,这就是优良的设计。但是优秀的设计又要求容易扩展,需求变化的时候尽量少的修改。当代码能够很好完成它的功能,它就是有价值的,客户并不关心你的代码是否是低耦合,高内聚,也不关心它是否是多层架构的。花了很多时间做了高扩展的架构,到项目结束也没有要扩展的需求,这是否值得呢?
适当的设计是必要的,过多的设计是浪费,关键是要把握设计的度。怎样才是必要的呢?当你知道某地方以后会变化,该地方就得对扩展开放。举个例子,如果要你实现解析文件,然后把信息存入数据库这样一个功能,当前只要求解析Xml,你可能会毫不犹豫的用XmlDocument。但是,后面的需求是必须支持更多的文件类型,比如Excel,Csv等,你就得考虑需要引入Strategy模式。我觉得这就是适当的设计,为以后的扩展提供支持。如果你不考虑也可以,只是后面的开发过程中会大量的重构,修改测试,花更多时间,别人会说你设计不好。那什么是过多的设计呢?很明显客户只需要支持Sql Server,那我在DAO中就使用SqlConnection等,而不必要引入Provider或者Sql Dialect以支持多数据库的变化。这样的设计就是浪费。
良好设计的不二法则,面向接口编程。接口减少了类和类之间的依赖,提高了可测试性,很方便的引入DI框架。但是如果你看到我们项目的代码会发现,类之间全都是与接口交互,几乎所有类都会抽出接口,尽管它只可能有一种实现。这样做的目的是为了更好的使用Mock工具进行单元测试,当前还做不到Mock具体类而只能Mock接口。大量的接口伴随着唯一的实现,为了测试而设计,也是不小的浪费。我想肯定有更好的办法,比如将某些耦合紧密的类看作一个组合,对它进行单元测试。针对这些问题,我还需要更多的学习。
希望大家都来讨论,你们在开发过程中是如何设计的,如何把握设计的度呢?
评论
#1楼caidehui | 2008-06-10 23:41
这个不是设计的尺度的问题,而是设计能力的问题,
管理资料
《如何把握系统设计的尺度》(https://www.unjs.com)。不管是敏捷也好,非常正规的设计也好都是一样的,要求设计本身是比较准确的。
敏捷的设计,是文档少,直奔主题,讲究快而准,那么就要求我们的设计人员水平要比较高、团队成员的能力要相当、大家心态都比较开放。
设计的最重要的原则还是隔离变化、要分清楚变化,面向接口编程可以换成一句话,叫面向使用编程,没有使用就没有接口了,而使用环境有可能变,所以接口要多多考虑使用的变化,从而在设计中将使用的变化能够容纳进来。
看看你介绍的问题,还有一个致命的问题,就是敏捷设计也需要架构和框架,没有这两个东西,就没有敏捷。将系统构架在一个稳定的基础上是非常关键的。尽管这个基础在项目开发过程中还会发生变化,但这个变化应该是可控的、频率很小的。
有了架构与框架,后面的问题自然就迎刃而解了。
敏捷开发如何设计架构与开发框架,当然要在最开始的迭代里面考虑,要使用1-2天的时间来分析所有的use story,如果没有所有的use story 也要将涉及到的业务讨论清楚,分析将来的扩展情况,分析这样的架构在各种情况下的变化与应对,再花上2-3天时间,实现这个框架,并能够多方验证与证实。
后面的迭代只要做好每次迭代要求的Use story 能够在框架下按时、按量完成,那么基本上就成功了
紫色阴影 | 2008-06-11 02:08
@caidehui
我觉得还是设计尺度的问题,如何把握扩展性,不管从是整体架构来说还是设计。
文档少不是设计的特点,而是开发流程中的特点。你感觉没有文档,但是需要什么东西都可以找得到,所以说敏捷开发并不是不要文档,而只是保证最少最需要的文档,不用文档来驱动
任何开发方法都需要架构和框架的,这些是开发的基础。敏捷开发只是快速开发出原型系统,无需太多考虑。
变化是不可避免的,架构也是随之精化,当项目结束的时候,从整体上来看,也许和最初的时候很相似,但细看往往大不一样。
来自:如何把握设计的尺度