2009年6月17日星期三

面向对象设计背后的数据库设计(摘自"The Object Primer")

  1. 把对象映射到关系数据库

首先,类的属性将会映射成关系数据库中的0列或多列(最好使用相似的命名规范)。

对象的有些属性本身就是对象,它真实地反映了两个类之间的关联。

并非所有的属性都是持久的,有一些被用来进行临时计算。

  1. 影子信息

影子信息(shadow information)是除了普通领域数据之外,对象需要维护的任何用于将它们自己持久化的数据。

一般如主键信息,特别是没有业务含义的代理主键。并发控制标记、时间戳、增量计数器。

  1. 映射继承结构

将继承映射进关系数据库中,有3种主要的方法:

  1. 把整个类层次映射到单张表中。
  2. 把每个具体类映射成自己的表。
  3. 把每个类映射成自己的表。

3种技术的对比

技术

优点

缺点

单表

  1. 方法简单
  2. 容易增加新的类:仅需要对额外的数据增加新列
  3. 通过简单改变行的类型来支持对象多态
  4. 数据访问是快速的,因为数据在一张表中
  5. 特殊报表是非常容易的,因为所有的数据都可以在一张表中找到
  1. 类层次的耦合增加了,因为所有的类都直接耦合到同一张表中。类中的变化可以影响表,这样就影响了层次结构中的其他的类以及他们的相关映射
  2. 数据库中潜在的空间资源的浪费,因为许多行将会是空行
  3. 当类型之间有严重的重叠式,表明类型变得复杂
  4. 对于大型层次结构,表增长得很快

每个具体类一张表

  1. 访问单张表中的数据时好的性能
  2. 生成特殊报表简单,因为一个类的所有数据都仅存处在一张表中
  1. 对类的修改需要我们修改他的表,及其任何子类的表。
  2. 无论何时对象改变了他的角色,就需要把数据拷贝到相应的表中。
  3. 支持多行信息,还要维护数据完整性,这很困难。

每个类一张表

  1. 映射简单,因为他是一对一的
  2. 容易支持对象多态,因为我们只在每种类型相应的表中有记录
  3. 修改父类和增加新子类非常容易,我们仅需要修改/增加一张表
  4. 数据大小的增长与对象数目的增长成正比
  1. 数据库中有多张表,每个类一张表(加上维护他们之间关系的表)
  2. 潜在的要花更多的阅读和读取数据的时间,因为我们需要访问多张表
  3. 特殊报表是困难的,除非我们增加视图来仿真待处理的表
  1. 映射关系

对象模式中的关系是通过对象引用和操作的组合来实现的。而在RDB中,他们通过外键来维护。

映射关系的方式依赖于他的多重性:

  1. 一对一关系

如果每个类都有一张表对应,那么这两张表之一需要实现一个外键。

第二种策略是简单的在单张表中存储两个类的数据。

  1. 一对多关系

它的实现方式是在关系中的那方面使用Hashset等集合,在的这方面使用对象引用。

在数据库中,他是在关系中多的一方通过外键来实现。

  1. 多对多关系

两个类之间的多对多的关系被映射成数据库内的关联表。

  1. 迭代关系

也称为自反关系,它是指关系的两侧都是相同的实体。

我们可以使用非迭代关系相同的方式来映射它们。

功能驱动与用例驱动(关于用例、用户故事和特征的解释)

软件开发过程中,描述并分析需求会同时采用不同的角度和方式。例如功能分析和场景分析。

其中功能分析是指描述系统所应该具有的功能。场景分析是指在特定场景中用户的操作步骤以及系统给出的相应的反应。

功能分析文档所列出的清单一般会叫做“软件需求”或者“系统特征”。

场景分析文档所列出的内容一般就是“用例文档”

由此可见,RUP中所使用的用例驱动开发,XP中所使用的用户故事驱动开发以及特征驱动开发,表面上看起来是以其分割粒度的不同进行排列下来的。其实我们可以看出,用户故事和特征都是从功能分析的角度对系统的需求进行的描述。其与RUP所说的用例驱动完全使用了不同的分析方法。

这样我们就可以更好的理解XX驱动开发之间的区别在那里。

下面是功能驱动与用例驱动之间的对比表格:

功能驱动

用例驱动

  1. 当你有许多未密切相关的不同功能时,工作会进行得比较好。
  2. 让你可以较快想客户展示可运作的程序代码
  3. 是非常功能性驱动的。采用此方式,你不会忘记任何功能。
  4. 对具有许多未连接功能性片段的系统,进行的特别好。
  1. 当你的应用程序有许多流程与场景,而不是个别的功能性片段时,进行得比较好。
  2. 让你在每个开发阶段可以向客户展示较大的功能性片段。
  3. 是非常以用户为中心的。采用此方式,你将为用户使用此系统的所有方式编写程序代码。
  4. 对交易式系统(系统以冗长、复杂的流程定义而成),进行的特别好。

在实际需求分析的过程中,两种分析方式相辅相成,都有其独到的贡献,最好能够结合使用。

我理解,互联网类型的项目更适合功能驱动开发,而企业业务系统类型的项目更适合用例驱动的开发。

2009年5月18日星期一

芜湖项目现场需求调研阶段总结

芜湖项目现场需求调研阶段,工作效率高,工作成果的质量也很好,现在总结如下:

  1. 需求分析团队人员要尽量少,减少沟通成本。尽量只允许业务核心人员参与,这样能够以最快速度对业务流程进行确认。
    反观现在大平台的项目,需求分析阶段有30多个人参加,包括了国家局的人员和各省市的人员。分成了6个分析小组。诸多问题无法现场进行确认,因为参加的人多,因此大家都不作结论,只能会后通过EMAIL来回来去。由于分组很多,因此涉及到很多跨小组的问题进一步增加了沟通成本。
  2. 需求讨论会议现场形成文档,由于文档形式上是共同创作完成,因此可以省略客户确认文档的过程。
    反观现在大平台的项目,会议之后,需求分析人员晚上加班形成需求访谈报告,需要客户确认,然后再形成需求规格说明书,再要求客户确认,这样效率非常差。
  3. 关于需求分析的团队构成,建议如下:
    - 客户业务人员
    - 客户IT人员
    - 主力业务分析人员:主要负责需求分析工作,引导大家使用正确的方式和正确的方向进行需求分析工作。
    - 业务分析助理:主要使用合适的工具,现场进行文档撰写工作。也可以提出自己的建议。因此该人员也需要有一定的需求分析能力和文档撰写经验。
    - 项目助理:负责对会议中的各种未定事项以及决议进行跟踪,并且进行其他的一些辅助性工作。
    - 解决方案顾问团队:辅助角色,可以离线支持。主要对相关业务领域或者IT技术领域进行咨询工作。
    - 开发组组长以及主要设计人员
    - 系统实施负责人
  4. 使用的工具建议如下:
    - 业务流程分析工具,以便团队成员能够在早期对业务流程有全貌的认识,如BPMN, EPC图等等
    - 快速互动原型工具,以便快速形成可以进行互动的动态系统原型,给客户良好的感受。推荐serena prototype composer或者axure rp等。
    - Sparx Enterprise architect,全面的项目模型管理,在此阶段主要使用到:用例分析,领域模型,需求条目管理等等。(在用例中需要填写senario条目,并且需要与需求条目进行关联)
    - Balsamiq Mockups,对操作页面进行设计。
  5. 对目前的大平台,现在能想到的建议如下:
    - 分组尽量少,1~2各组,人员尽量少,减少沟通成本。
    - 现场形成文档。
    - 在早期需要有总体业务流程分析过程,然后在进入细节系统需求分析过程。
    - 使用上述的工具
    - 使用上述的团队组织结构

综上,发现上述经验并不太符合敏捷过程,反而与《人月神话》中的理论非常相似。起码,可以总结出来两点:1.架构(需求分析)是贵族专有的工作内容。2.需要组成外科手术型的团队结构。

2009年5月17日星期日

芜湖出差,巡回取货项目的一些心得

五一之后到芜湖,客串巡回取货项目的项目经理,负责需求调研工作。整两周的时间,有如下一些心得体会:
出差两周,其中需求调研工作大约占用了6个工作日的时间。另外有2个工作日大约是各种各样的汇报。
工作进行的比较顺利。体验也很好,主要是可以按照自己比较推荐的方法来进行项目工作,大家都比较轻松,工作效率也很高。客户方也反映工作效率很高,工作很有成效。
开始的几天,使用serena prototype composer工具,项目组成员在同一个会议室中,主要讨论工作流程(与系统无关)。然后同样使用这个工具,讨论大致的系统操作流程,同时画出初步的系统界面。这个阶段成果效果非常好:大家对系统的总体概念已经形成,基本确认了系统范围。并且形成了可以进行互动的系统界面原型。
然后开始使用EA和Balsamiq Mockups配合进行用例分析与界面设计。在EA中复制了serena prototype composer中的工作流程,然后进行用例分析,在用例中进行场景senario步骤描述。针对每一个用例,至少使用Mockups软件绘制一张界面设计图。另外在EA中进行领域模型的设计。
综上,提供出一份真正对开发有帮助的需求文档。
经估算,这两周的需求分析工作定义出的系统需求大约需要5人团队开发3个月的时间的工作量。开起来也非常符合比例。当然这仅仅是估算的合理值,估计和客户方面进行协商之后,时间上又会变得非常不合理。

客户非常高兴的从我这里拿到了上述的三款设计工具。不过,真正重要的是需要会使用这些工具啊。

在出差期间,抽时间学习“Head First OOAD”,有如下收获:
终于对需求和用例明确的区分开了。需求大约总是以“系统应该可以xxx”这样的格式描述,主要描述系统所具有的功能和能力。用例侧重于描述某某场景senario下面的操作步骤。因此大约会是包括正常路径/可选路径/替代路径等等。

不过,在出差期间,本计划使用类似极限编程方式的增量开发,结果未遂。最终变成了类似ICONIX方式的过程。

另外,意外的发现,原公司上班时,结识的MOTO客户,现在正在作为甲方折磨着现在我的客户。现在我的客户天天折磨我们,同时他们也在被MOTO客户折磨着。……

2009年4月2日星期四

软件开发过程DRY

依据RAILS框架所倡导的DRY (Don't Repeat Yourself)的思想,可以大大提高编程时的工作效率。如果能够由此推广开来,发现软件开发过程中有哪些工作内容是重复而浪费了,并能够有针对性的改善的话,是不是可以提高工作效率呢?
我们的现实情况是:需要满足客户以及老板和项目管理中心所谓正规软件工程所需要的标准过程,还有标准过程所要求的文档。所以,通常来讲,我们会按照这样的过程进行工作:

考虑以下一些方法:
  1. 利用用例分析或者用户故事,来讲需求分析与需求传递和培训两个过程合并。
  2. 考虑需求文档中的用例分析部分可以是主力需求分析人员带领开发团队共同完成。
  3. 需求文档的工作量很大,并且变更之后的维护也是问题。因此考虑需求文档与测试用例进行结合,减少需求文档中的内容。
  4. 使用某种形式的工具来自动生成规范格式的需求说明书。
  5. 概要设计说明书中仅包含系统架构层面的设计工作。
  6. 系统设计过程与测试案例编写过程融合(参考XP过程)。
  7. 实用工具(例如javadoc)来自动由编码生成详细设计文档。
  8. 现实存在详细设计过程,但是并不正规,仅仅产生一些中间产物文档,如界面草图、UML顺序图等等。

2009年3月30日星期一

关于敏捷软件开发新的理解

前两天,在一次聊天中,我问了问未来开发组的组长:眼看设计过程就要结束了,项目启动到现在进行了3个月的时间,想一想,前一阶段我们所做的工作中,有百 分之多少是对后面的工作有意义的?开发组长无奈的苦笑了一下。显然大家心里面都有数,这个比例很不理想。尤其是设计文档中的模块设计部分,大量的工作量, 完全是为了设计文档能够评审通过。

对于敏捷软件开发,目前理解期最重要的目的是识别软件过程中没有必要的任务或者是性能低下的任务,然后去除之或者改进之。基于这个出发点回顾一下目前的情况:
  1. 需求分析。唯一不变的就是变化。项目的早期集中时间进行需求分析然后确认基线,再等到真正动手开发某一模块的时候可能已经过去了一段时间,并且需求已经发生了变化。这样还需要对新的需求进行再次分析。在这样的情况下,前后的需求分析则存在工作量的浪费。
    1. 敏捷过程则是需求分析存在与整个项目的始终。细节的需求分析工作尽在真正开始代码之前才进行。虽然以后仍然有可能发生变化,但起码针对上面的情况做了优化。
  2. 软件设计。目前的项目,设计阶段需要的交付物有:架构设计,概要设计,详细设计,物理模型设计,接口设计等等。设计的目的当然是为了能够知道开发。这一部分工作显然是必须的,但是能否优化呢?敏捷过程典型的对策是1.仅仅做足够的设计;2.测试驱动开发。
    1. 系统的架构设计是需要的。但是针对某一功能来讲,仅仅在开发之前才做相应的详细设计。设计仅仅做到能够指导开发的程度,对文档的格式要求比较宽松。
    2. 传 统的UML设计包括类图、顺序图、协作图、活动图、状态图等等。这个敏捷过程一般没有强制要求。XP过程中推荐以TDD和CRC分析来代替。其中CRC分 析基本上是UML协作图的替代物,但是更加强调团队共同完成。而TDD则是在保证了测试自动化的同时还能够对软件设计进行指导,做一件事达到两个效果,体 现其高效率。
  3. 界面原型。我前面说过,希望能够在需求分析阶段就能够对系统的界面进行确认,还找了一些专业做页面原 型的辅助工具。现在看来,其实也存在浪费。其实更高效的做法是以最快的速度拿出开发出的成品或者半成品让用户进行确认(这样一来,唯一的问题是你能有多 快?;-) )。界面草图有的时候是需要的,但是它变成了非常不正式的中间产物,不必要进行存档。
  4. 重构。仔细想想,其实重构的工作对于任何一个项目来讲都是必须的。而现实是,如果没有采取全面的自动化测试的话,传统的软件开发项目没有能力也不敢进行深度的重构。而相反基于TDD的XP团队则更有勇气对软件进行彻底重构。
  5. 集成。集成的工作量无法节省。敏捷过程的做法是持续集成——将工作量分散到整个软件生命周期。这样能够及时发现问题,并从感受上减少工作量。
我有一个朋友,看他上网打桥牌的时候,经常发现他的搭档在抱怨他发生了失误。而实际的情况是怎么样的呢?我的朋友是全国顶级桥牌赛事的前四名获得者。那些被抱怨失误的牌都是由于他的搭档的水平不够,对于他的精妙招数无法理解。
在软件开发领域,其实我们也正在处于我的朋友的搭档的水平。经历的项目越多,越会发现业内大师的很多理论的精妙之处。很多情况是:如果大师们的理论你认为有很大问题的话,其实是因为你的层次还不够。

2009年3月15日星期日

现实很残酷

现在手头是这样的一个项目:
  1. 为期7个月
  2. 工作量分析的结果,项目团队需要60个人或者更多
  3. 项目组中只有包括我在内的3个人有相关行业经验
  4. 开发团队中有大约20多个人是刚刚招聘到位的
  5. 对于所使用的技术,除了JAVA开发之外,JAVA开发框架、BPM/BRM引擎、B2B网管、字符终端开发等等都是项目组第一次使用
  6. 项目组中几乎没有人有面向对象的设计和开发经验
  7. 客户方面政治斗争严重
这是我所经历过的第二个死亡之旅项目。

2009年2月5日星期四

考虑使用UberNote代替Google Notebook

刚刚发现一款新的Web应用:Ubernote
  • 展现方式同Google Notebook非常相似
  • 采用了不分层的Tag方式进行管理
  • 可以对Note进行所见即所得的富文本编辑
  • 可以多人合作共享Note
  • 有浏览器插件,可以直接抓取网页。而且插件很丰富:Toolbar, Clip, Bookmark, Snap
  • 居然能够直接从Atom导入现有的Google Notebook内容。
  • 缺点是对于每一个Note不能折叠显示。
所以真的可以考虑切换过去?

另一个可选的替代方案是:TiddlyWiki + Clipmarks,只是Clipmarks的速度比较慢。

2009年2月4日星期三

Google Notebook的备选替代品

Google Notebook停止开发了。虽然现在还能够使用,但是还是需要准备一些备选产品了。另外,Google Notebook的功能一切都好,唯一的问题是,不能存储网页篇幅很大的文章。
替代品列表:
  1. Office OneNote 2007:非常好的产品,文字编辑非常灵活方便,支持表格。分类清晰,功能强大,能够直接抓取网页。不能支持在线同步,但是只需要配合Dropbox就可以完美解决。唯一的问题是商业产品,需要收费。另外只能基于Windows平台。
  2. Evernote:也是业界很出名的产品。Tag方式的管理,支持全文搜索,能够直接抓取网页。有在线同步功能,同时还有桌面客户端。
    缺点是:体积庞大,免费版本每月有数据量的限制。并且不支持表格,编辑功能稍弱,不够灵活。
  3. TiddlyWiki:体积小巧,功能灵活。基于Tag方式管理,可以安装第三方插件。开源。支持UBB方式的自定义格式,非常方便。配合Dropbox可以实现在线同步。单一的HTML文件,所以跨平台。
    缺点是:不支持直接抓取网页。
现在看,TiddlyWiki的方式很好。所以正在寻找能够直接抓取网页并能够在线同步的工具进行配合使用。

对面向对象以及极限编程新的理解

传统的面向过程的开发是自顶向下逐步细化的过程。这是非常符合人们习惯的思维方式的。所以自然由需求分析->概要设计->详细设计->编码->测试->发布的瀑布模式成为了最规范的软件过程。
面向对象的开发是自底向上的过程。在这样的过程中,往往是先实现已经了解的局部。逐渐的随着过程的推进,系统的全貌浮出水面。而基于面向对象开发的特点,在这个过程中,前面的工作成果往往能够很好的进行复用,重构的成本也很低。自然而然的,开发的过程会形成多次的迭代。但是,在这个过程中,最重要的是需要按照面向对象的思维方式进行设计与开发。

基于上面的认识,在回顾XP的各项原则会发现,以前认为不现实的内容其实都是顺理成章的事情了。唯一的问题仅仅是现场客户的问题,不过这个在一定的程度上 面也能够克服。由此可见,当深入了解了面向对象的开发的精髓之后,XP的各项原则实际上都是面向对象过程的一些内在的需求而已。

极限编程的12个原则:
  1. 计划的制定
  2. 小版本
  3. 简单设计
  4. 测试驱动
  5. 持续整合
  6. 重构
  7. 配对编程
  8. 代码共享
  9. 每周只工作40小时
  10. 现场客户
  11. 隐喻
  12. 编码标准

2009年1月22日星期四

关于OOD的一点点总结

很多成熟的设计过程摆在面前:用例驱动、XP用户故事、特征驱动FDD、模型驱动MDD、敏捷模型驱动、领域驱动、测试驱动等等等等……到底应该怎么设计呢?
简单的讲,过程内容会分为需求分析和设计。
需求驱动是最根本的,所以在需求阶段,所谓的各种驱动方法其实都是对需求的功能分解,以便日后进行分治的设计以及管理跟踪。
由Use Case -> User Story -> Feature其实是由粗到细对需求分解的不同粒度。
有了需求条目之后,针对每一个条目可以继续进行设计工作。
设计过程的目标其实很简单:
  • 类的识别
  • 类的结构(例如:继承、关联、聚合、依赖等等)
  • 类的属性
  • 类的方法
  • 系统运行是类之间的消息传递关系。
前三项是在整个设计过程中不断进行更新的,是个逐步细化的过程。分析的早期就可以识别大部分实体类,而在模拟需求条目的场景的过程中,逐步识别边界类(主要来自于页面流程分析)和控制类。主要的工具就是UML类图。
后两项则是通过模拟每一个需求条目所描述的场景来设计类之间的消息传递关系。在这个过程中,自然的完成对类分配方法。主要使用的工具如顺序图、协作图或者CRC分析。

对于MDD, AMDD以及DDD来讲,感觉上是针对非常熟悉的业务需求或者非常有经验的分析设计人员,因此采用了更新颖的设计路径。

而TDD应该理解为一种辅助设计手段。

2009年1月21日星期三

在Iconix过程中使用协作图

ICONIX过程步骤如下
  1. 系统界面原型,初步的领域分析(识别实体类,分析类之间关系,但不添加属性和方法),用例分析(仅关注用例内部的主干流程与分支流程,而忽略诸如前置条件、后置条件等细节)。
  2. 健壮性分析(分析用户与系统类之间的关系,在此期间识别边界类与控制类),更新用例,更新领域模型(添加部分类属性)。
  3. 详细设计(根据健壮性分析图而细化成顺序图,在此过程中给类分配方法),细化领域模型成为类图(静态模型)。
查阅了一些资料之后,有一个想法:
可以尝试使用UML协作图来代替顺序图。
因为协作图的样子本来就与健壮性分析图非常相似。这样,第2、3步仍然保留,但是产出物可以合并,即直接在健壮性分析图上面进行更新而成为协作图。
协作图中主要表现的是在一个场景中对象所拥有的职责(即所用到的对象的方法)以及对象之间的关联。这样看来,协作图所起到的作用与XP过程中所推荐的CRC分析是完全吻合的
另外,对于普通的业务系统来讲,系统对时间的敏感程度并不高,这就增加的忽略顺序图的可能性。

如上,系统分析与设计的产物则为:
  • 页面流程图与页面布局原型
  • 用例分析
  • UML类图
  • UML协作图
  • 部署图与组件图(可选)

2009年1月20日星期二

在哪一个阶段画出操作界面

今天上午项目组内部开了一个会议,讨论需求文档的模板。大部分内容大家都比较一致,比如分成功能性需求和非功能性需求。功能性需求中主要以用例分析为主线,辅助以各个层次的工作流程图以及系统流程图。另外加入业务实体的各种信息等等。
但是在一个问题上面,项目组成员与我的引导无法达成一致:多数项目组成员认为系统操作界面不是需求阶段的产物。而应该是系统概要设计甚至详细设计阶段的产品。理由如下:需求的主要内容应该集中于业务分析,而系统界面更接近于设计的工作。而且在需求阶段需要画出页面的话,需求文档的工作量过大,需求评审阶段如果包括界面的话,那么需求阶段的时间会过长。
我无法说服大家的固有习惯,甚至无法说服大家仅仅写一些重要业务的操作界面。最终只能以大家的多数意见为准了。

这种情况显然是项目组内部对当前的OOAD技术缺乏经验所导致的。我的观点与大家相反,确认操作页面的工作越早越好!
  • 需求分析需要分为三个层次:战略目标需求(高层访谈),业务逻辑需求(中层访谈)以及操作需求(一线操作层访谈)。
  • 操作页面的确认工作应该是在需求访谈过程中同步进行的,而不是项目组内部闭门想出界面,然后拿给客户进行评审。
  • 画界面的工作不会因为推后而减少。
  • 需求访谈中对界面的访谈与分析有可能比用例分析还要早一步。示意图方式的界面会很大的消除需求的歧义。会给用户最直观的感受,是我们认识系统的第一个门户。
  • 更早的对操作页面进行确认会减少项目的风险。如果在概要设计评审的时候发现有一些界面设计的不合适,然后发现修改这些页面居然还会导致上一阶段的需求分析结果进行改动的话,这样的返工成本就要大很多了。时间压力也会更大。

现在公司的项目管理方式

由于手头的项目非常庞大(基本上是50人的团队,1500万的合同),对公司有战略意义,又是新老板来了之后的第一个大项目,因此,管理层对项目非常重视,老板会亲自关注细节。因此,该项目需要做的非常“规范”!当然,如何规范是针对现有公司的标准来讲的。具体特征表现在:
  1. 严格按照需求->概要设计->详细设计->编码->测试->发布的模式对项目进行计划。
    (听起来是严格的瀑布模式,呵呵,连一次迭代也没有。不过对于现在的公司来讲,能做到已经不错了。以前是基本没有设计阶段的,而且这次也会基本忽略测试阶段。)
  2. 设计过程要求严格,例如一定要先搞出来物理模型并进行评审。然后再对各个模块的输入输出进行严格的定义。
    (典型的面向过程的设计方式。我了解了一下,公司的整个软件部门似乎没有几个人使用过UML进行系统分析与设计,更不用说更加激进的CRC分析之类的了。所以,理所当然,技术人员多数觉得JAVA框架中的ORM一层基本没有什么作用。当你告诉他们OOAD的过程中,物理模型有可能是最后一步时,很多人难以接受。)
    (我想主要的原因很可能是:现在公司的管理层和技术骨干主要都是在90年代末期参加工作的,那时候国内正是面向过程的流行时期。所以大家都已经习惯于这样的设计方式。然后就是这样一代一代的延续下来……)
  3. 对文档的要求非常严格:包括在项目的第一周就需要提交细化到半年后的某一天的详细项目计划。而且各种文档名目繁多。
    (大家都听说过滚动式规划,但是做起事来还是如此。最后都变成了交差。)
  4. 项目计划的全部意义就是那个*.MPP文档。而且一般需要维护1000~2000行吧。
    (既然老板是这样认为的,所以也就没有人敢质疑该如何维护2000行的project文档。)
  5. 项目管理制度中规定:项目组内部沟通以正式的书面沟通为主,口头沟通作为辅助。
    (学过PMP或者对敏捷开发有兴趣的人会很吃惊是吧?)
  6. 加班将作为项目组工作的一种常态。加班的目的是为了营造紧张的项目组内部的气氛。
    (为了加班而加班!当然也有一部分原因是客户造成的。客户是国家机构,嘴里高喊“深入实践科学发展观”,做起事儿来完全“人有多大胆,地有多大产”。)
  7. 项目经理每天会忙于收发EMAIL,制定各种管理制度,以及制作各种报告等等。
不过似乎也不是一无是处,例如:
  1. 公司里面有一些强人自己包装了SPRING,开发了很好用的MDA框架。
  2. 老板亲自拍板,调集了公司最强的开发资源进入项目组。
  3. 暂时不用考虑项目成本问题。

2009年1月18日星期日

当面临的问题是生存时,任何承诺都是骗人的。

Google宣布:停止Notebook应用的开发,并停止其接纳新用户。
这让我想起了上一次的互联网泡沫破裂时的情况:263的老板在前一天还在信誓旦旦说要保留免费服务,转天就开始全面收费。
那一次事件之后,我对国内互联网服务提供商的信用彻底失望,虽然我不是受害者。从那以后我尽量会选用国外的服务提供商。
现在,在全球金融危机的影响下,大若Google都要出现类似的问题了。只不过,比起263,Google采用了很道德的方式。可以理解,当公司面临的问题是生存时,很可能别无选择。
我其实是非常依赖网络服务的:
  • Gmail
  • Google Bookmark
  • Google Docs
  • Google Reader
  • Google Site
  • Google Calendar
  • Google Notebook
  • Clipperz
  • Dropbox
  • Meebo
  • 等等
这一次,我可有些害怕了。正在考虑一些desktop替代品。例如:
MS OneNote, Firefox, Keepass, Pidgin等等。还是自己的硬盘上的东东可靠啊。

项目才刚刚开始,就收获了不少教训!

CNPL项目才刚刚开始第一周,就收获了不少教训。
上周一的时候项目刚刚启动,PMO的人找我谈话,希望我能配合工作。我当然满口答应。
周二的时候,收到PMO发来的邮件,让我周四就需要提交:人力资源管理计划以及项目实施方案两个文档。这两个文档我在之前都没有听说过,仔细看了看PMO发过来的例子,才发现项目实施方案其实就相当于PMP中所说的完整的项目管理计划了。
于是加班加点写了所有能写的内容,周四的时候发了出去。其实这个时候需求访谈才刚刚开始,项目组内所有的人全都整天在客户方进行需求访谈。所以现在只能有需求访谈计划。我在发出去的邮件中还详细的注明了所有无法填写的内容的说明。
很快PMO就回了邮件,找出了很多问题。而且最郁闷的是,老板也回了邮件,针对我所注明的无法填写的内容一一批驳。话里话外好像是在说我的工作态度有问题。
于是我在周五的时候找我的二老板抱怨了一下。看来是传到老板耳朵里了,老板马上打电话过来安抚。而且,我看了一下老板批驳的邮件,还好,仅仅是发送给了我和二老板,并没有发送给PMO。所以心里也还好过了些。
由此事件,得出了以下一些教训:
  1. 我本来真的很重视PMO的工作,因为我有8年项目管理经验,我是PMP,而且我也曾经是上一个公司的PMO部门经理。但是,现在在这一家公司,PMO的需求的优先级并不高,是很有协调余地的。前几个月我还在感慨这个公司对项目管理不重视,PMO的人地位也很低。现在看,可怜之人必有可恨之处啊。只给我两天的时间让我完成庞大文档,而且时机也很是不对,这让我不可能保证质量完成工作。
  2. 我犯了一个错误:在项目初期就应该非常重视如何将工作分配到下属手中。
  3. 我犯了另一个错误,在分析干系人需求时,非常重视客户方面的满意度,反而忽视了老板的需求。我本不该犯这样的低级错误的,可能是因为在这个公司当前的管理能力下,我对自己的管理经验过分自信了,以后一定需要注意。
  4. 现在的客户的习惯是,一旦项目启动,就会立刻需要所有相关的文档。现在的公司也受其影响,老板养成相同的习惯。所以为了应对这样的特殊情况,需要在项目早期就写出非常详细的项目计划(甚至需要计划到9个月之后的某以前需要干什么)。当然,这样的文档没有任何实际意义,仅仅为了交差。而随着需求访谈的进行,项目范围渐渐明确了之后,才需要真正用功编写能够实际应用的项目管理计划。
  5. 现在的环境下,项目经理管理工作还有更多的内容,甚至包括长期出差人员的住宿问题、办公场地的桌椅等等细节问题。这些在书本上是找不到的。

2008年12月16日星期二

关于软件过程的比较



关于软件管理过程,目前敏捷过程最为热门。主要的敏捷过程有以下几种:XP 极限编程, SCRUM, FDD 特征驱动开发, DDD 领域建模驱动开发, ICONIX, ASD 自适应, CRYSTAL 水晶, DSDM, TDD 测试驱动开发, AMDD 敏捷建模。再加上“传统”的RUP。
浏览这些过程会发现这些敏捷过程所涉及的领域还是有所区别的。简单来讲,可以粗略的划分为管理过程设计过程。例如:
  • SCRUM:很明显是管理过程。在实践框架中提供了一些可以明确执行的实践指南。而其中对于设计方法或者过程基本没有什么要求。
  • FDD:应该属于管理过程。其中明确了对项目的进行如何规划。而对设计方法所述比较少。
  • ASD, CRYSTAL:属于管理过程,其中重点讨论对人的管理理念。管理框架具有很大的灵活性。
  • DDD:属于设计过程,重点描述如何从业务需求导出到系统设计编码的过程。
  • AMDD:属于设计过程。
  • XP:比较特殊,不是完整的管理体系。而对设计过程也很少描述,仅仅提供了一些最佳实践。由于其要求非常明确,所以我觉得更接近与设计过程。
  • TDD:应该不算是过程,仅仅是一种辅助设计的方法。所以经常被其它敏捷过程所引用。
  • ICONIX:对管理过程与设计过程都有所涉及。不过更加接近于设计过程。
  • DSDM:不太了解,无法分类。
基于此原因,所以经常可以看到将两种或者以上的敏捷过程组合进行应用的现象。如:SCRUM+XP, FDD+DDD等等。而AMDD和TDD更是经常被其他过程所引用。
不过这也侧面说明,这些敏捷过程往往内容都不够完整,或者说是针对性比较强。

现 在看来,敏捷过程的宣传者针对的往往是一些传统的重型过程,如CMM, ISO等等。而由于RUP内容比较复杂,所以往往也被算进来。这其实是由于对RUP的误解造成的。RUP被设计为统一过程,所以必然包罗万象,以便适应于 更多类型的项目。这就造成了RUP的复杂性,其实也说明了RUP内容的丰富。但是,当具体到某一个项目的时候,必然会根据项目特点或者企业环境因素对 RUP过程进行裁剪,以形成特色的过程。所以针对小型项目,RUP完全可能变成为非常“敏捷”的过程。
不过这也属于一个矛盾:1. 对于小型项目的项目经理来讲基本没有精力或者经验对整个RUP体系进行完整的研究。2. 如果缺乏对RUP体系的研究,就不可能对RUP体系进行恰当的裁剪。
基于这个矛盾,出现了很多伪RUP过程实践。
这样的现象是因为RUP中缺乏对一些比较典型的项目类型的具体指导和模版,来使项目经理可以快速的对RUP开始实践。而在这方面敏捷过程往往做得更好。例如XP过程,提出了明确的原则和实践指南,使得人可以非常简单清晰的学习和实践练习。
基于此,例如XP这样的过程就在程序员中很受欢迎,因为程序员多数项目管理经验不够充足,所有如果有简单而明确的实践规则的话,当然更容易付诸实施。
但 反过来讲,这些敏捷过程对项目类型的要求往往非常严格,例如,XP过程就会要求:项目组规模、办公地点、用户现场、合同类型等等。所以当人们将它应用与不 同的领域时又不得不对它进行改良或者采用其它的软件过程。在这方面RUP就会好很多,深入研究RUP可以使你用一种软件过程应对更多类型的项目
ICONIX是所以受欢迎,就是因为它延续了RUP的思路而有提供了可明确参考的工作步骤。

当然反过来,对敏捷过程的误解也是存在的,例如:RUP的支持者往往认为XP过程没有设计。实际情况是XP过程也是相当重视设计的,只不过方式不同。XP过程不建议进行预先设计,而是使用其它的一些辅助手段保证软件设计的优化,例如TDD、重构等等。

再看看思维方式。新兴的敏捷过程往往宣传自己基于小型迭代,并以此来对应变更,使项目满足客户业务需求。但所谓迭代一词应该更加细分成:“增量开发”与“迭代开发”,之间的区别如图所示。

由此看来,如XP, SCRUM, FDD等过程其实都属于增量开发。而RUP和ICONIX过程属于迭代开发。所以,对此概念模糊的人就会误解RUP更像瀑布模式。
其实增量与迭代无所谓优劣,仅仅是思维方式的不同。

2008年12月8日星期一

关于系统设计的文章摘抄

模型(Model)代表应用程序的数据(data)和用于控制访问和修改这些数据的业务规则(business rule)。通常模型被用来作为对现实世界中一个处理过程的软件近似。
视图(View)被用来组织模型的内容,它从模型那里获得数据并指定这些数据如何表现。
控制器(Controller)定义了应用程序的行为;它负责对来自视图的用户要求进行解释,并把这些要求映射成相应的行为,这些行为由模型负责实现。

有人提到
MVC模式时说MVC代表了模型层、视图层、控制层,我觉得这是不对的。在经典的J2EE三层架构中,三层是分为Web层、业务层、持久化层;这个经典分层是基于分布式应用(EJB)的,也就说,Web层物理上是在Web服务器中, 业务层和持久化层物理上是在应用服务器中。在这种情况下,MVC只是属于Web层这一层的,而不是分为三层。在这种分布式应用中,视图就是JSP(如果采用的话),控制器就是Servlet(如果采用的话),而模型就是就是调用业务层的在Web层中的桩子。假如我们采用轻量级的SSH技术架构,视图还是JSP,控制器是Struts,而模型就是SpringHibernate这里最难理解的就是模型的概念。我觉得模型是有状态和行为的,那么Struts中的Action调用的Servcie方法就是模型的行为,而返回给JSPDTODO)就是模型的状态。

对于一个页面请求,总要有个地方负责处理和页面跳转的地方,这个地方就是页面控制器。页面控制器有两种,一种是如
Servlet的脚本文件,一种是如JSP的服务器页面。对于Java来说,JSP就是只应该用来显示动态的或静态的信息,而不是用来负责处理RequestRedirect页面,否则Servlet就要失业了。尽管一个Web程序可以全由JSP文件组成,但将控制甚至业务脚本杂乱的穿插在Tag中真的是太糟糕的实践了。

贫血模型:是指领域对象里只有get和set方法,或者包含少量的CRUD方法,所有的业务逻辑都不包含在内而是放在Business Logic层。
优点是系统的层次结构清楚,各层之间单向依赖,Client->(Business Facade)->Business Logic->Data Access(ADO.NET)。当然Business Logic是依赖Domain Object的。似乎现在流行的架构就是这样,当然层次还可以细分。
该模型的缺点是不够面向对象,领域对象只是作为保存状态或者传递状态使用,所以就说只有数据没有行为的对象不是真正的对象。在Business Logic里面处理所有的业务逻辑,在POEAA(企业应用架构模式)一书中被称为Transaction Script模式

充血模型:层次结构和上面的差不多,不过大多业务逻辑和持久化放在Domain Object里面,Business Logic只是简单封装部分业务逻辑以及控制事务、权限等,这样层次结构就变成Client->(Business Facade)->Business Logic->Domain Object->Data Access。
它的优点是面向对象,Business Logic符合单一职责,不像在贫血模型里面那样包含所有的业务逻辑太过沉重。
缺点是如何划分业务逻辑,什么样的逻辑应该放在Domain Object中,什么样的业务逻辑应该放在Business Logic中,这是很含糊的。即使划分好了业务逻辑,由于分散在Business Logic和Domain Object层中,不能更好的分模块开发。熟悉业务逻辑的开发人员需要渗透到Domain Logic中去,而在Domian Logic又包含了持久化,对于开发者来说这十分混乱。 其次,因为Business Logic要控制事务并且为上层提供一个统一的服务调用入口点,它就必须把在Domain Logic里实现的业务逻辑全部重新包装一遍,完全属于重复劳动。

贫血模型是对OO的 非常经典的诠释!数据交给s/g,业务全部交给业务对象来完成。耦合度很低,逻辑清晰,重构空间大!而且在业务逻辑上事务控制的关注点也小!但是也很明 显,业务对象做的事情实在太多了,在领域对象上这个叫做超职责。s/g和业务对象分工虽然明确但工作量截然不同, 也就是说这个对象的职责过于复杂,在一定程度上背离了细力度的OO模型原则。

网友: 对某一个实体信息的管理维护,是分出增加、删除、修改还是只看作一个维护用例?
UMLchina_潘加宇:关键是要找出CRUD背后可能隐藏的业务。

网友: 到底要画哪些图?序列图是必须的吗?
UMLchina_潘加宇:
如果不是面向对象开发,只有用例文档是必须的,然后直接编代码都可以。如果是面向对象开发,需要用类图描述结构,顺序图分配责任。


Martin: 关于这些项目中不写文档的说法是荒诞的。文档和计划当然要做,不过他们不再是过程的一部分,而是过程中的一个任务。在敏捷项目中,会有很多任务,有些任务会包含文档化、项目计划等这些管理团队需要做的规范操作。但它们不再是过程的一部分,这句话的意思是说,它们的秩序不是固定的,我们不是一定要先写文档,也不是一定最后写文档,我们在写文档这个工作变得重要的时候来做它,它会和其它任务一样在日程中进行安排。

Martin: 对.NET开发者而言,在学习敏捷开发的过程中最大的挑战就是测试驱动开发。敏捷开发对单元测试和自动化接受测试的要求很高。TDD现在已经被全行业所接受了,就算你是微软,也是一样的。


那么测试代码是否可以完全取代自然语言形式的设计文档呢?我看还不行,原因有三:
其一,测试代码虽然比源代码容易理解,但它仍然是代码,不是所有人都能理解的;
其二,测试代码的宏观表达能力还是不如自然语言或图表;
其三,很多人习惯看文字而不是看代码,彻底改变人的习惯很难。
所以在TDD开发过程中,比较好的形式是自然语言的文档和测试代码相结合,用自然语言的文档做一个够用的设计就行了,这个设计只要详细到模块关系这一级别就足够了,各个模块的详细设计就由测试代码充当。

Q: 单元测试怎么能反映/代替需求 ?

A: 单元测试未必能直接反映宏观上的需求, 但

  1. 功能测试和集成测试能够反映宏观需求.

  2. 单元测试能够反映系统的其它部分对当前单元的需求.

而从文本的角度, 测试用例的名字就是需求的描述. 换句话说, 你从传统的需求文档中把描述抠出来, 放到测试代码中作为测试用例的名字, 你便拥有了可执行的需求文档


当你试图测试一个单元时, 却发现需要创建大量的其它对象, 而且按照你脑海中的实现, 有些对象是在单元内部创建的, 根本无法在测试环境中假冒它们. 这时候, 你即使只是为了减少测试的难度, 也会逼迫自己思考:

  1. 这个单元是否做了太多的事, 承担了额外的职责, 违反了单一职责原则?

  2. 是否应该把依赖让外界设置进来, 而不是自己在内部创建, 这样测试时就能把依赖设置为假冒的实现?

是的, 单元测试警示你思考一下自己的设计


2008年11月24日星期一

业务流程建模与软件项目需求


在软件开发的阶段定义中,以前一直不太分得清需求阶段内部的子阶段划分。
在以前的项目中,我们仅仅出具软件功能需求文档,并且认为这份文档就是全部的项目需求文档。文档的内容主要包括:功能性需求的用例分析,用例内部的流程图(活动图),用例内部的系统原型,如果需要的话,还要加入模块以及的流程图和系统的WHOLE PICTURE,其他内容(包括:非功能性需求,项目业务目标,名词解释,设计人员等等)。

到新的公司之后,刚刚进入了物流项目组大约一个月,发现软件需求中的业务需求和功能需求还是有所区别。
在项目的早期,我们需要对客户的应用系统所涉及的业务逻辑和业务流程进行分析,并形成业务需求文档。这一份文档的目的是能够是项目组的相关成员对客户的业务有更好的理解,或者是新进入项目组的成员能够对项目的业务背景有一个比较完整的认识。准确的定义客户的业务需求对后面的软件需求分析具有指导性的意义。在这份文档中,将主要使用业务流程建模工具,如数据流图、工作流程图、UML活动图等等。
在分析的业务需求之后,进入到软件功能需求阶段。在这个阶段,将根据将来的系统建设需要对业务需求中所涉及到的功能进行重新的拆分组合排序,并进行一些补充。使之更加贴近设计人员的需要。在这个阶段的产物软件功能需求文档中,将会更多的将用户业务的语言翻译成为软件开发专业的业务描述。这份文档的目的是直接作为系统设计的输入,并能够指导开发工作,所以其还需要能够比较容易的进行任务分解。在这份文档中,将会更多的使用用例分析和业务领域分析、原型设计等工具。

目前新公司的物流项目正处于早期的业务调研阶段。在这一段时间内,我目前正在了解有关业务流程建模的工具。以前一直是在使用UML的活动图,但是总觉的其表现力还是不够丰富,所以也经常在使用跨职能的流程图进行辅助。最近查阅了相关的资料发现,UML在业务流程建模领域的确是弱项。在这个领域现在有很多成熟的工具和理论。最典型的是BPMN和EPC
BPMN图是官方组织发布的专门用于业务流程建模的规范。目前的版本大约是2.0。图例非常丰富——不下50多个。也有很多专门的绘图工具,其中包括免费的产品BizAgi Process Modeler和很多基于Visio的图例插件。不过,对于如何规范的规制业务模型的资料,网上却少得可怜。
EPC图不是行业标准或者规范。但是由于能够绘制EPC图的软件ARIS被内嵌在了者名的SAP软件中,所以EPC图基本上是事实上的行业标准。EPC图例并不复杂,但却能组合起来清晰的表现业务流程。
所以在现在的项目中,我尝试的使用EPC图的方式进行了一些业务流程的说明。当然,在使用的过程中,我对EPC的图例进行了微小的扩展。
下面是我做的一个EPC图的例子。

2008年11月17日星期一

关于业务模型分析的绘图需求

在业务模型分析过程中,发现有以下的一些绘图需求:
  • 需要能够表达工作流程。
  • 需要能够表达系统的功能。
  • 需要能够表达工作流程中的动作。其中最好能够区分关联到系统功能的动作和系统外部的动作。
  • (系统功能和流程中的动作或许可以等同对待)
  • 需要能够表达系统功能的输入和输出,可能是:纸质的单据,电子数据或者业务对象。
  • 需要能够表达操作系统功能的系统角色以及其所属的组织结构。
  • 需要能够表示出发系统功能的事件。或者系统功能完成之后的流程状态。
  • 需要能够表达流程分支的情况,例如:and, or, xor,并行等等。
  • 需要能够对某一个系统功能或者动作进行扩展。例如某一个系统功能中可能会有其子流程。
  • 需要能够对上述的业务对象以及系统角色进行“引用”方式的绘图,以便统一管理。
  • 可以对业务对象进行详细设计(类图)。
  • 最好能够附带对某一节点关联系统页面原型的设计功能。

目前正在参考以下一些工具,但似乎都不能完全满足需求。当然也有可能是没有完全发掘以下一些工具的全部功能。
  • UML活动图+UML类图
  • EPC图(Event-drive Process Chain)
  • Serena Prototype Composer工具