最近一阵子比较清闲,所以又温习了一下《敏捷软件开发:原则,模式与实践》这本经典的著作,并且结合了前一个项目的流程,对号入座,反思了一下我们的不足和有待改进的地方。我发现在真正项目开发的过程中,敏捷的许多过程,我们在使用的过程中是有很多实际困难的,比如严格的TDD开发,结对编程,客户(Customer/Client,有时指的是客户代表)参与,开放的环境等等。而且在这个项目中,与其说我们使用了敏捷开发的过程,倒不如说我们的过程更像是RUP(统一过程)的敏捷版本。经过认真的反思和总结,我发现开发中有几个问题是值得思考的:

1、架构是演化而来的,那么基础架构(架构的起点)需要提前选定么?

这个是一个容易让人困惑的问题,问题来源于敏捷开发与RUP开发的不同主张。前者主张根据用例分析软件的核心模型,然后直接编写代码并通过不断测试与重构,逐步演化获得核心架构;而后者讲究的水到渠成,通过用例分析,得到分析模型(核心模型),然后选择架构和框架,再实施编码。两者我都实践过,这里我只说说我的体会。敏捷强调重构到模式和架构,起点要求不是太苛刻的,但是按照这么一直走下去,我发现开发的过程中,代码可以很干净,但是架构的走向比较混乱,走着走着有时就偏离了方向,需要设计和开发者具有高超的重构和抽象功力;RUP过程比较自然,分析模型确定以后,直接选择架构和框架,然后编码,方向明确,目的性比较强,但是一旦后期某些需求(可能是功能上的,也可能是重构的需求)导致选择的架构需要扩充的时候,所做的工作可能就会比较多。

当我屡屡在这个问题上苦苦纠缠,难以抉择,不断翻书思索的时候?我突然看到一本软件工程书上的一个词:“裁剪”,瞬间,我释然了。敏捷软件开发,RUP开发不都是成熟的开发思想吗?思想不同于准则,具体的执行步骤不是严格按照书上规定的走的,这个实践的过程是需要对过程进行修剪和重组,乃至融合的。就像设计模式,思路是相同的,但是同一个模式实现起来的结果可能是大不相同的。想到这里,我真的觉得以前太过执着,太过追求模仿、追全完美,最终是本末倒置,丢了西瓜,捡了芝麻!

2、TDD的粒度问题,如何写好测试?

伟大的哲学家王守仁一生提倡知行合一,从这个层面上说,TDD是一个卓越的思想,也是一次伟大的实践,至少我是这么认为的。TDD是敏捷开发的绝佳组合,更是单元测试最忠诚的伙伴(TDD并不等同于单元测试的)。TDD带来了设计上的低耦合性和可测试性,保证了架构的灵活性和扩展性,也从而保证了产品的质量;而且,测试文件和测试结果也成为了最好的功能说明书和验收文档。

当TDD带来这么多好处的同时,不可否认的是,它也为开发过程引入了很多复杂的因素:大量的Mock/Stub对象充斥在代码中,而且无法保证Mock对象与真正的对象实现上是可替换的;通常为了达到Mock对象与代码对象可以互换,Mock对象需要实现很多负责的模仿行为;很多的测试就是为了单纯的测试,不在是从代码的使用角度真正的去测试代码;通常测试的过程与真正编写对象的过程是一致的,这无疑造成了一些浪费;测试本身也是代码,也是有Bug的,这个该如何保证呢?关于测试代码的粒度选取上,每个人认识并不一致,这也造成了测试代码比较难以掌控;很多的数据访问组件都是有成熟的技术的,比如Linq,Hibernate, EF,这些如何去测试...

真正实践TDD的时候,我才发觉这个真的是太难了,也许是经验不足的原因,很多的时候,我只是在关键的业务规则部分使用TDD。大家呢?

3、组件是从上而下自然构造的,还是从下而上分析得到的?

这个又是一个敏捷与RUP互相对立的地方。

敏捷的实践一般是从类开始,即是从用例中分析核心模型,得到核心的对象,编写测试代码并实现对象,通过不断的迭代逐步构造完整的系统;等到需要分包的时候再根据分包的粒度原则(发布重用原则,共同重用原则,共同封闭原则)和依赖性原则(无环状依赖,稳定抽象原则,稳定依赖原则)来分配对象到不同的组件中,得到最终的软件层次架构。

而RUP的过程则是在需求和功能分析设计后,从选择基点架构开始,比如常见MVC架构以及各种变体,多层架构以及各种变体,管道架构,分布式架构,一些新的如REST架构等等。选定架构以后,不同的组或者人员分配不同的部分,设计并完成各自的功能。通过不断的迭代和重构,完成各个版本和发布,最终得到软件的层次和架构。

这里,组件的形成过程其实与架构的形成过程是息息相关的,从上面两种截然相反的过程中,我们又有哪些感悟呢?这个只能说是仁者见仁,智者见智了。我比较认同的观点是:这取决于项目的类型,大小。小型的项目用敏捷是不错的,合作愉快,你好我也好,真的是大家好才是真的好。对于大型的项目,通常是要选定多种过程融合执行(比如RUP+敏捷),一般是应该选定基础的架构,分好模块,初步定义接口结构,然后再不断重构和迭代。

4、分解开发的规模,独立运行的模块,真的降低了软件变质的风险?

很多人赞同一个观点:问题以及解决这个问题的人员规模,是导致软件开发架构逐渐变质的直接因素。所以他们认为缩小问题的规模(通常是拆分解决方案),提炼独立运行的模块是相当不错的一种方案。

独立运行的模块,固然是短小精悍,维护难度大为降低,但是这个过程中,复用的程度似乎是不高的。而且对于很多公用的组件,为了达到让多个进程使用并且不会干涉互相的正常运行,常常是需要将这个模块部署到GAC中,或者是拷贝多个版本,放到各自的运行目录中。在开发的过程中,部署到GAC似乎不是可取的方式;连微软都搞出来一套延迟签名的机制,显然Release之前部署组件到GAC是不好的。那么拷贝多个版本到不同的目录中呢?缺点也很明显,每次组件的更新,都需要更新每个调用的程序目录,当独立程序的数量大幅上升的时候,这个过程变的相当脆弱,容易出错,毕竟这个时候你是无法使用FAR(Find All Reference)来找到所有使用的地方的,当然了,使用Windows的查找功能也许还是可行的,但是这样还是比较麻烦的,最后连脚本都会被用上,用于简单的替换任务。那么如何是好呢?大家有什么好的做法呢?

我曾经的经历是这样的:支持团队代码开发的是源码管理工具。代码分支(Branch)是经常采用的手段。不同的组工作在不同的Branch上,等到集成的时候,由集成工程师或类似的角色完成整合工作。这样不同分工的团队就可以工作在不同的分支上互不干扰,等集成完成以后,各自就能获得多其他组最新的程序。这个工作是有一个前提的,就是各个组之间,更深一步说,是各个组负责的模块之间,通信必须是畅通无阻或者是通信无关的;或者说通信必须是提前约定好的。这样解决方案的规模其实没有缩小,只是出现很多分支,而且有专门的人负责这方面相关的工作,比如集成和编译程序。这种做法说不上是好是坏,而且实施成本比较高,但是对我们来说效果还是有一点的。

郑重声明:以上只是个人的感慨与总结,并不是每个问题的标准答案,更不是推荐给大家的成功经验和知识。限于能力,每个想法总是有对与错,如果观众们有不同的意见或者是自己的看法,那也是很正常,大家姑且当个故事,看看罢了!偶尔想到相关的问题,批判的瞅瞅,如果能产生自己的想法,那就更好了!

转载于:https://www.cnblogs.com/dxy1982/archive/2011/08/20/2135319.html

软件设计:“度”、“裁剪”与“变通”相关推荐

  1. 软件设计原则:内聚、耦合有哪几种类型?内聚度、耦合度如何比较?

    文章目录 前言 一.何为内聚? 1.1.7 种内聚类型及其描述 二.何为耦合? 2.1.7 种耦合类型及其描述 总结 前言 高内聚.低耦合是我们在软件设计过程中必须遵循的一个重要原则,在整个软件工程中 ...

  2. 领域驱动设计 软件核心复杂性应对之道_DDD - 领域驱动设计对软件复杂度的应对(上)...

    不管是因为规模与结构制造的理解力障碍,还是因为变化带来的预测能力问题,最终的决定因素还是因为需求.Eric Evans 认为"很多应用程序最主要的复杂性并不在技术上,而是来自领域本身.用户的 ...

  3. 读张逸的领域驱动设计之应对软件复杂度笔记

    2019独角兽企业重金招聘Python工程师标准>>> 张逸的<领域驱动战略设计实战>地址,付费的,价格¥59,还能接受. Eric Evans认为"很多应用程 ...

  4. 基于Android的3G手机网络摄像机客户端软件设计

    深入研究了MJPEG视频压缩算法,阐述了算法实现过程,并设计出基于Android操作系统的3G手机网络摄像机客户端软件.本系统通过实地安装与测试达到了预期效果,突破了传统网络摄像机客户端固定地域的限制 ...

  5. 车牌自动生成器软件设计与实现

    目  录 摘要 Abstract 1. 绪论 1.1 研究背景与意义 1.2 国内外研究现状 1.3 本文主要工作 1.4 论文组织结构 2. 相关技术 2.1 车牌生成流程概述 2.2 国内车牌相关 ...

  6. 多核片上系统(SoC)架构的嵌入式DSP软件设计

    多核片上系统(SoC)架构的嵌入式DSP软件设计 Multicore a System-on-a-Chip (SoC) Architecture SoCs的软件开发涉及到基于最强大的计算模型在各种处理 ...

  7. 概要设计实例_多核片上系统(SoC)架构的嵌入式DSP软件设计

    多核片上系统(SoC)架构的嵌入式DSP软件设计 Multicore a System-on-a-Chip (SoC) Architecture SoCs的软件开发涉及到基于最强大的计算模型在各种处理 ...

  8. 高并发软件设计的几种方式

    本文就高并发软件设计中可以考虑使用的一些方法做如下总结: 1)多线程有利于提高CPU占用率,因为软件本身的线程越多,在和系统上其他线程争夺CPU资源时就能分配到更多执行资源,同时也能提高业务处理的并发 ...

  9. 第五次作业——软件设计

    第五次作业--软件设计 在开始软件设计之前,首先确定软件设计中的各个模块需要考虑的任务,绘制概要图如下: 下面根据上述各个模块,逐层进行软件设计: 一.概要设计 首先,概要设计的目的是确定软件的结构以 ...

  10. [置顶] 软件设计之道_读书纪要.doc

    本系列的文档都是我读书后的个人纪要,如想了解更多相关内容,请购买正版物.对应的图书可以从我的个人图书列表里找寻:个人毕业后图书列表 1.  每个写代码的人都是设计师,团队里每个人都有责任保证自己的代码 ...

最新文章

  1. C#中DateTime.Now.Ticks的用法和说明
  2. python解复杂方程组_sympy计算方程组的复杂表达式怎么获得数值解?
  3. 直线电机原理动画_最新的3D动画演示:同步电机原理及技术,一般人看不懂
  4. 【C、C++基础】什么时候用 “.” 什么时候用“->”(3个实例搞懂)
  5. Win11系统如何调节字体大小
  6. 关于arp.exe的一点应用
  7. QStardict移植到i.MX-287开发板
  8. 关于linux下anaconda的pip包及其他包的本地更新方法
  9. 【java学习】多线程之高并发编程
  10. jmeter 参数为邮箱@出现%40解决办法
  11. java.lang.String_不兼容的类型:java.lang.String无法转换为Str...
  12. 【图像融合】基于多尺度引导实现图像融合附matlab代码
  13. 如何安装英文版linux系统,如何安装Linux系统(示例代码)
  14. 计算机网络重要知识点总结(期末复习笔记)
  15. get这3种方式 轻松发送邮件超大附件
  16. 关于手持设备PDA的开发
  17. 威尔·史密斯[Will Smith]
  18. 成功解决tensorflow.python.framework.errors_impl.InvalidArgumentError: slice index 1 of dimension 0 out o
  19. SSL证书为什么会有有效期 如何有效避免SSL证书过期
  20. MATLAB | 19a到22a之间都更新了哪些绘图新特性?

热门文章

  1. 【数量技术宅|量化投资策略系列分享】成熟交易者期货持仓跟随策略
  2. JAVA垃圾分类管理系统-含论文基于SSM【数据库设计、毕业设计、源码、开题报告】
  3. “褶子”使花朵美丽起来
  4. 唯一约束判断 细微差mysql别_50道MySQL面试题,查漏补缺看你掌握多少?(附答案解析)...
  5. python自学-class20-爬取东方财富网股票数据(爬虫)
  6. 使用AFN上传图片 下载图片
  7. Android源代码编译原理与前期准备
  8. 一、JQuery选择器
  9. CSS学习笔记——精灵图(sprite)
  10. 比尔盖茨夫妇现身贫民窟