<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>温室小花.技术.博客 --纯粹的unix技术博客 &#187; 系统架构</title>
	<atom:link href="http://www.evanjiang.net.cn/archives/category/technical_management/systems_architecture/feed" rel="self" type="application/rss+xml" />
	<link>http://www.evanjiang.net.cn</link>
	<description>红颜弹指老，刹那芳华，与其天涯思君，恋恋不舍，莫若相忘于江湖！</description>
	<lastBuildDate>Sun, 05 Sep 2010 14:51:18 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>系统架构师的修炼</title>
		<link>http://www.evanjiang.net.cn/archives/1361.html</link>
		<comments>http://www.evanjiang.net.cn/archives/1361.html#comments</comments>
		<pubDate>Wed, 25 Nov 2009 02:06:47 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[系统架构]]></category>

		<guid isPermaLink="false">http://www.evanjiang.net.cn/?p=1361</guid>
		<description><![CDATA[<p>


 <p>最近应聘系统架构师，面试回答一些问题，加上之前做的一些功课，搜索到一些文章，感觉有必要总结一下，到底如何做一个成功的系统架构师呢？
首先，何谓系统架构师？
 IBM工程师的说明是：
  架构师的主要责任是提供开发人员和项目经理之间的共用沟通媒体。他们负责让业务规则及需求与工程实践及限制相适应，以确保成功
 中文Wiki上的说明是：
  系统架构师负责设计系统整体架构，从需求到设计的每个细节都要考虑到，把握整个项目，使设计的项目尽量效率高，开发容易，维护方便，升级简单
 这两个解释，加起来基本说明系统架构师的定义。</p>
<p>JAVA系统架构师应该看的几本书
Thinking in Java
Effective Java
UML基础、案例与应用
UML入门提高
软件工匠
设计模式——可复用面向对象软件的基础
重构-改善既有代码的设计
敏捷软件开发-原则、模式、实践
企业应用架构模式
Expert One-on-One J2EE Development without EJB
 
软件工程——实践者的研究方法
软件领导－－成功开发软件的指导准则
后面的两本书，其实已经有点属于项目经理的范畴，不过还不是很深入，看看对做成功的系统架构师是很有好处。
企业应用的系统架构师应该关注的几个方面
数据持久层的设计
 在Spring和Hibernate，ibatis出来以前，几乎每家公司都有自己的一套方法和架构，而架构师的50％的精力也会集中到这上面，EJB只是增加架构师的负担。在Spring出来以后，基本上，大多数的架构师都从重复设计这个轮子的无用功中解脱出来。Rod的轮子太好用，基本上，大家只要套上去就行，或者，剩下最重要的事情，是选择一个合适的数据库连接池的开源项目吧
MVC架构的具体设计
 MVC只是个概要的概念，具体如何实现的具体技术很多，根据项目设计最恰当的架构
大并发性访问
 使用缓存，在数据量达到一定程度时，使用集群技术，优先考虑利用服务器的集群，其次是硬件集群，最后才是应用本身加入集群功能
超大数据量返回结果
 尽量使用分页，优化SQL语句，循环处理数据时尽可能共用对象，只保留关键数据，及时释放内存占用
超大文件的读取和生成
 尽可能快的读取大文件，并进行分析。写入大文件时，如何及时释放内存。学会适当利用操作系统的命令行资源来更快完成任务。</p>
<p>多线程的应用和管理
 线程池的管理和监控，线程的启动（包括定时启动），结束，回收，线程资源的释放</p>
<p>用户界面可用性设计
 平衡速度和可用性，恰当的使用异步和同步技术，展现关键数据为重点
分布式的数据交流和集成
 选择恰当的数据交互方式，从最泛滥低效的Web Service到最实用的文件共享
群集系统的管理
 如何确保缓存的同步？如何确保对象唯一性？如何保证各台机器的同步？
 是否采用EJB?如何利用J2EE的特性（例如JNDI)
复杂的业务规则
 规则引擎和工作流引擎场景和应用</p>
<p>其实，作为一个真正的系统架构师，不应该局限于企业应用的系统，这种系统往往有数据库的局限性，有时候，应该考虑是否可以横向跨越，直接对其它系统做一些架构考虑，在没有丰富的实战经验的前提下，而只是看其它人的系统和代码，就能够给出有效的设计指导。
例如对于一个下载软件，可以有如下考虑：
 1. 未明和非法url的检验，已经下载失败的容许，信息记录
 2. 多线程下载一个文件,文件的切分和拼合，部分切片丢失的拼合可能性
 3. 下载线程管理
 4. 服务器或者P2P的机器之间的通讯协议
 5. 速度监控和限制
 6. 下载进度的监控和显示
作为一个在线播放软件,可以做如下考虑
 1. 播放速度的保证
   机器的问题基本不存在，关键是网络问题。如何在检测网络速度，根据影片的质量，并缓冲足够多的内容，保证播放一直尽可能顺利的完成。
 2. 播放质量的保证
   如何利用DirectX等技术,最快的进行渲染,是自己写底层,还是利用已有的API
由于没做过类似的项目，可以写的东西还是少很多。
系统架构师应该有的素质：
1、 实际的编程经验
  最少2年吧，多就不说，其实从大学就开始钻研的话，
2、 [...]]]></description>
			<content:encoded><![CDATA[<p style="float: left;margin: 4px;"><script type="text/javascript"><!--
google_ad_client = "pub-8438729971248494";
/* 160x600, 创建于 10-2-7 */
google_ad_slot = "8970910006";
google_ad_width = 160;
google_ad_height = 600;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></p> <p>最近应聘系统架构师，面试回答一些问题，加上之前做的一些功课，搜索到一些文章，感觉有必要总结一下，到底如何做一个成功的系统架构师呢？<br />
首先，何谓系统架构师？<br />
 IBM工程师的说明是：<br />
  架构师的主要责任是提供开发人员和项目经理之间的共用沟通媒体。他们负责让业务规则及需求与工程实践及限制相适应，以确保成功<br />
 中文Wiki上的说明是：<br />
  系统架构师负责设计系统整体架构，从需求到设计的每个细节都要考虑到，把握整个项目，使设计的项目尽量效率高，开发容易，维护方便，升级简单<br />
 这两个解释，加起来基本说明系统架构师的定义。</p>
<p>JAVA系统架构师应该看的几本书<br />
Thinking in Java<br />
Effective Java<br />
UML基础、案例与应用<br />
UML入门提高<br />
软件工匠<br />
设计模式——可复用面向对象软件的基础<br />
重构-改善既有代码的设计<br />
敏捷软件开发-原则、模式、实践<br />
企业应用架构模式<br />
Expert One-on-One J2EE Development without EJB<br />
 <span id="more-1361"></span><br />
软件工程——实践者的研究方法<br />
软件领导－－成功开发软件的指导准则<br />
后面的两本书，其实已经有点属于项目经理的范畴，不过还不是很深入，看看对做成功的系统架构师是很有好处。<br />
企业应用的系统架构师应该关注的几个方面<br />
数据持久层的设计<br />
 在Spring和Hibernate，ibatis出来以前，几乎每家公司都有自己的一套方法和架构，而架构师的50％的精力也会集中到这上面，EJB只是增加架构师的负担。在Spring出来以后，基本上，大多数的架构师都从重复设计这个轮子的无用功中解脱出来。Rod的轮子太好用，基本上，大家只要套上去就行，或者，剩下最重要的事情，是选择一个合适的数据库连接池的开源项目吧<br />
MVC架构的具体设计<br />
 MVC只是个概要的概念，具体如何实现的具体技术很多，根据项目设计最恰当的架构<br />
大并发性访问<br />
 使用缓存，在数据量达到一定程度时，使用集群技术，优先考虑利用服务器的集群，其次是硬件集群，最后才是应用本身加入集群功能<br />
超大数据量返回结果<br />
 尽量使用分页，优化SQL语句，循环处理数据时尽可能共用对象，只保留关键数据，及时释放内存占用<br />
超大文件的读取和生成<br />
 尽可能快的读取大文件，并进行分析。写入大文件时，如何及时释放内存。学会适当利用操作系统的命令行资源来更快完成任务。</p>
<p>多线程的应用和管理<br />
 线程池的管理和监控，线程的启动（包括定时启动），结束，回收，线程资源的释放</p>
<p>用户界面可用性设计<br />
 平衡速度和可用性，恰当的使用异步和同步技术，展现关键数据为重点<br />
分布式的数据交流和集成<br />
 选择恰当的数据交互方式，从最泛滥低效的Web Service到最实用的文件共享<br />
群集系统的管理<br />
 如何确保缓存的同步？如何确保对象唯一性？如何保证各台机器的同步？<br />
 是否采用EJB?如何利用J2EE的特性（例如JNDI)<br />
复杂的业务规则<br />
 规则引擎和工作流引擎场景和应用</p>
<p>其实，作为一个真正的系统架构师，不应该局限于企业应用的系统，这种系统往往有数据库的局限性，有时候，应该考虑是否可以横向跨越，直接对其它系统做一些架构考虑，在没有丰富的实战经验的前提下，而只是看其它人的系统和代码，就能够给出有效的设计指导。<br />
例如对于一个下载软件，可以有如下考虑：<br />
 1. 未明和非法url的检验，已经下载失败的容许，信息记录<br />
 2. 多线程下载一个文件,文件的切分和拼合，部分切片丢失的拼合可能性<br />
 3. 下载线程管理<br />
 4. 服务器或者P2P的机器之间的通讯协议<br />
 5. 速度监控和限制<br />
 6. 下载进度的监控和显示<br />
作为一个在线播放软件,可以做如下考虑<br />
 1. 播放速度的保证<br />
   机器的问题基本不存在，关键是网络问题。如何在检测网络速度，根据影片的质量，并缓冲足够多的内容，保证播放一直尽可能顺利的完成。<br />
 2. 播放质量的保证<br />
   如何利用DirectX等技术,最快的进行渲染,是自己写底层,还是利用已有的API<br />
由于没做过类似的项目，可以写的东西还是少很多。<br />
系统架构师应该有的素质：<br />
1、 实际的编程经验<br />
  最少2年吧，多就不说，其实从大学就开始钻研的话，<br />
2、 书面表达能力和口头交流能力<br />
   综合利用架构图，UML图，文字和代码片断，表达自己设计思想，至于是Word还是ppt，应该通吃<br />
  在开发人员中发现架构师的最有价值标准是有效的沟通。您需要技术娴熟、经验丰富的开发人员，这样的人员需要有就项目中的业务相关问题进行沟通的经历。架构师经常必须对理解方面的差距进行预计，然后才能有所贡献。他们必须愿意克服困难来确保技术和业务观点的融合。他们并不必对意见交换工作进行计划和协调;这仍然主要是项目经理的工作。他们的任务是确定表述系统设计时的最佳工具和构件，以促进有效的意见交换。他们必须能够判断当前方法显得不足而需要采用新方法的情况。写作技能也非常重要，还需要具有制作草图的技能或使用制图软件的能力。<br />
 3、 自觉主动;积极解决设计问题<br />
  架构师的日常工作目标经常并不明确。很多开发人员直接参考功能规范来列出任务清单。架构师通常则是向这些开发人员提供所需结构的人员，以便尽可能提高工作效率。好的候选者不仅进行沟通方面的工作，而且也会预计各种设计问题并加以解决——通常在没有任何具体指示的情况下自觉进行。无论所分配的职责如何，积极参与项目的开发人员都有机会从一起工作的人员中脱颖而出。<br />
4、 抽象思维能力和总结能力<br />
  架构师，顾名思义，在系统未搭建好之前，就要能够有一个草图在心。而如果是对现有系统的改造，那么能在看过系统的文档（如果有的话）和代码后，就能总结出系统的架构特点。<br />
  架构师必须能够理解表述模糊的概念并将其变成相关各方能够理解的项目构件。他们必须能够理解抽象概念，并以具体的语言对其进行沟通。开发人员中好的候选者经常要求或自己主动解释开发生命周期中容易混淆的问题。他们能迅速评估各种想法并将其纳入后续工作的操作建议中。<br />
  开发人员经常具有很强的数学能力，而好的架构师则倾向于表现出更强的口头表达能力。管理人员经常说开发人员具有“工程意识”，而这是一个用于评估架构师的非常有意义的方面。架构师应该具有很强的解决技术问题的能力，但还必须能够准确获知更为全面的人员如何与技术交互的信息。这要求具有某种形式的抽象思维(而不再是代码的细节)，这种思维能力可能较难形成。<br />
5、 全面的技术资讯吸收能力和选择鉴别能力<br />
  作为开发人员出身，对于某一个具体问题的研究能力（虽然很多人总结为google能力），已经相当具备。但是对技术资讯的全面接受和选择性深入解能力，并且做出正确的判断，那些技术无非是厂家的噱头，而那些技术是真正可以用到项目，提高项目质量的好技术，这种能力确实至关重要的。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanjiang.net.cn/archives/1361.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>解密微软的架构师之路</title>
		<link>http://www.evanjiang.net.cn/archives/1307.html</link>
		<comments>http://www.evanjiang.net.cn/archives/1307.html#comments</comments>
		<pubDate>Tue, 29 Sep 2009 07:44:05 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[系统架构]]></category>

		<guid isPermaLink="false">http://www.evanjiang.net.cn/?p=1307</guid>
		<description><![CDATA[<p style="float: right;margin: 4px;">


</p> <p>  若是说起架构师，几乎所有的开发人员都知道的一个伟大架构师来自微软，他就是比尔·盖茨。这个20世纪最伟大的技术天才有太多的传奇。对于架构师这个群体，他同样产生了非同小可的作用。作为一个企业的大老板，他是第一个给自己冠之以“首席架构师”头衔的人。也正因如此，整个IT领域才开始不断涌现出架构师这个并不算新的职业。为了追寻微软的架构师文化，我们采访了微软Windows HPC Server架构师徐明强博士，邀请他为我们解密微软的架构师之路。
    微软架构师定义
    对微软内部的架构师的定义，Windows HPC Server架构师徐明强博士是这么描述的：“微架构师的职责定义主要在两个方面。一是要负责整个项目中技术活动和工程过程，进行领导和协调。二是要负责理解系统本身的业务需求，并且创建合理完善的一个系统体系架构。进一步的细化则可以展开来谈。”
    “通常架构师要确立每一个构架视图的整体架构，比如说视图的详细结构、元素的分组以及实现主要分组之间的接口描述。因此和其他角色对比，架构设计师的见解是用在广度，不是在深度，这样才能确保架构师在技术活动中起到领导的作用。第二方面，对于业务需求来说，架构师要负责通过软件架构来决定主要的技术选型。典型的工作包括系统需求设计，实现和部署的视图以及测试等等。”
    三种架构师
    这种通用的解释如果难于理解，那么是不是会有更具体的实施方法？像微软这样庞大的软件开发组织结构里，架构师会根据产品团队，工作职能进行进一步划分。随后，徐明强开始介绍微软架构师的分类。
    “如果要理解微软的架构师职能划分，就需要先了解微软的产品部门划分。通常在微软内部的产品组，有三个更小一级的分组，一是项目经理组，二是开发组，三则是测试组。”
    “项目经理组主要是负责业务的需求定义，产品规格书撰写。而开发组则主要负责软件的实现，以满足项目经理所定义的需求规格书。测试团队的主要任务则是确保软件产品交付的质量。不同的分组，有不同的职能划分。因此，我们看做是有项目经理架构师，开发架构师和测试架构师几种基本类型。”

    “不同的架构师职能大相径庭，比如项目经理架构师，更侧重于业务上的需要。从这个意义上看，你就会发现不同架构师的区别。由于项目经理主要是看用户的需求，对整个系统性能提出要求，对工作品质提出要求，同时还要确认在用户应用场景，产品是否可以有效地被系统支撑，因此它具备了非常不同的职能。”
    “而开发组的架构师比较侧重于技术，尽管某些问题上会与项目经理架构师重叠，但更多时候分工还是非常明确的。技术架构师的一大职能是技术选型，比如在产品中选择使用什么技术，比如数据库要采用哪种规格的SQL server， 比如数据库的模式（schema）应该怎么样设计。当然，这里也包括.NET组件的选择等，这些是开发组架构师所关注的。
    “从测试方面看，测试架构师则关注测试系统对架构的设计的帮助，包括如何自动化测试，或更有效的手工测试等。比如说HPC Server 测试组的架构师的工作，由于涉及到很复杂的分布式的系统，就需要做可扩展性测试，计算资源分配的测试，包括测试方法的设计等。”
 [...]]]></description>
			<content:encoded><![CDATA[<p>  若是说起架构师，几乎所有的开发人员都知道的一个伟大架构师来自微软，他就是比尔·盖茨。这个20世纪最伟大的技术天才有太多的传奇。对于架构师这个群体，他同样产生了非同小可的作用。作为一个企业的大老板，他是第一个给自己冠之以“首席架构师”头衔的人。也正因如此，整个IT领域才开始不断涌现出架构师这个并不算新的职业。为了追寻微软的架构师文化，我们采访了微软Windows HPC Server架构师徐明强博士，邀请他为我们解密微软的架构师之路。<br />
    微软架构师定义<br />
    对微软内部的架构师的定义，Windows HPC Server架构师徐明强博士是这么描述的：“微架构师的职责定义主要在两个方面。一是要负责整个项目中技术活动和工程过程，进行领导和协调。二是要负责理解系统本身的业务需求，并且创建合理完善的一个系统体系架构。进一步的细化则可以展开来谈。”<br />
    “通常架构师要确立每一个构架视图的整体架构，比如说视图的详细结构、元素的分组以及实现主要分组之间的接口描述。因此和其他角色对比，架构设计师的见解是用在广度，不是在深度，这样才能确保架构师在技术活动中起到领导的作用。第二方面，对于业务需求来说，架构师要负责通过软件架构来决定主要的技术选型。典型的工作包括系统需求设计，实现和部署的视图以及测试等等。”<br />
    三种架构师<br />
    这种通用的解释如果难于理解，那么是不是会有更具体的实施方法？像微软这样庞大的软件开发组织结构里，架构师会根据产品团队，工作职能进行进一步划分。随后，徐明强开始介绍微软架构师的分类。<br />
    “如果要理解微软的架构师职能划分，就需要先了解微软的产品部门划分。通常在微软内部的产品组，有三个更小一级的分组，一是项目经理组，二是开发组，三则是测试组。”<br />
    “项目经理组主要是负责业务的需求定义，产品规格书撰写。而开发组则主要负责软件的实现，以满足项目经理所定义的需求规格书。测试团队的主要任务则是确保软件产品交付的质量。不同的分组，有不同的职能划分。因此，我们看做是有项目经理架构师，开发架构师和测试架构师几种基本类型。”<br />
<span id="more-1307"></span><br />
    “不同的架构师职能大相径庭，比如项目经理架构师，更侧重于业务上的需要。从这个意义上看，你就会发现不同架构师的区别。由于项目经理主要是看用户的需求，对整个系统性能提出要求，对工作品质提出要求，同时还要确认在用户应用场景，产品是否可以有效地被系统支撑，因此它具备了非常不同的职能。”<br />
    “而开发组的架构师比较侧重于技术，尽管某些问题上会与项目经理架构师重叠，但更多时候分工还是非常明确的。技术架构师的一大职能是技术选型，比如在产品中选择使用什么技术，比如数据库要采用哪种规格的SQL server， 比如数据库的模式（schema）应该怎么样设计。当然，这里也包括.NET组件的选择等，这些是开发组架构师所关注的。<br />
    “从测试方面看，测试架构师则关注测试系统对架构的设计的帮助，包括如何自动化测试，或更有效的手工测试等。比如说HPC Server 测试组的架构师的工作，由于涉及到很复杂的分布式的系统，就需要做可扩展性测试，计算资源分配的测试，包括测试方法的设计等。”<br />
    协同工作，准确分工<br />
    这么多不同的架构师，如何协调工作，这是很多人马上会想到的问题。尤其是在面临冲突的时候如何解决，关系到每一项工作是否能顺利推进。关于这个问题，徐博士给我们举了个例子。<br />
    “比如我负责HPC Server 产品的规格说明书，那么开发组就会强调是否有充裕时间实现各个组件，而测试组将会根据规格说明书来考虑，这个组件所实现的功能是否严格满足规格要求。开发组会有很好的意愿来完成产品开发，但如何衡量是否完成却是一个问题。从我们的角度看，首先就是应用的场景。例如在一份需求说明文档中，如果你能描述为什么有这个需求，且写得非常清楚，那么开发就能准确地知道他们需要做的工作是什么。如果有一套非常清楚的目录，告诉用户如何使用产品，那么当这个系统做出来以后，每一步都应该考虑到用户在每一个阶段有什么样的知识背景能够完成下去。只要应用场景的故事清楚，文档自然也能够清楚。”<br />
    “当然，不同的工作也会有不同的优先级。这同样是项目经理架构师需要定义清楚的。技术架构师的主要精力，会放在具体选择哪个组件实现。这对于技术架构师来说，是非常有把握的。因此我们可以看到，产品需求定义得越细、需求的优先级定义得越好，说明项目经理架构师很好地完成了自己的工作，对于开发架构师的衡量，则是采用什么技术以及何种组件/架构提高了开发效率。”<br />
    “另外一方面是测试，项目经理的架构师同样需要与测试架构师协同工作。功能的每一个方面在需求中表现得越细致，各方面的系统指标越清晰，就越可以帮助测试架构师更好地完成其工作。牵涉到可扩展性、可延时等细节性能的指标，是测试架构师的优势，他们知道怎样才能处理好这些事情，但它们希望看到明确的指标。”<br />
    团队成长<br />
    多数公司里，架构师都是宝贝。而很多程序员，也确实梦想自己能成为一名软件架构师。但架构师的数量总是有限，多少人可以成为架构师？架构师的团队是如何成长起来的？徐博士用亲身经历讲述了HPC团队的发展历程。<br />
    “根据产品开发周期，不同的团队会有不同的配置。我在HPC产品组经历了两个多，近三个版本，所以有一点体会。在HPC第一版的时候，基本上我们的产品会分三个主要的组件，每个主要组件会有一个小团队。当时包括作业调度系统、管理系统和消息传递界面(MPI)，基本上每个组件都有一个架构师。尽管有的一开始没有架构师的头衔。 当时大概是一个架构师和三个开发人员和三个测试人员协同战。”<br />
    “主要原因在于项目一开始，团队并没有考虑如何定义架构，这里包括技术选型等，很多时候架构师会考虑这些事情，此时不会严格按照前面说的不同角色分工。到了后期的版本，产品问世，用户需求喷涌而出的时候，项目管理架构师角色就开始明晰化了。尽管主要的工作是在第一个版本上增加功能，但各个部门都会开始聘用更多的开发人员和测试人员，同时管理人员也会增多。”<br />
    架构师的核心能力<br />
    为了让开发者逐渐成为架构师，基础的能力还是需要具备的。“我觉得架构师必须学会的第一件事情就懂得如何进行权衡。因为我们面对的都是相互矛盾的一些设计要素和限制，但事实却要求你在这些相互矛盾的要素限制和约束条件之间取得非常巧妙的平衡。”徐博士感叹道。<br />
    “架构师必须足够成熟。因为他们往往需要在无法获得完整信息的情况下，迅速领会问题，根据经验做出审慎判断。其实微软内部有能力要求，能把一张比较模糊的图片清晰化。这里我想归纳四个方面。首先是在专题领域的经验和对微软软件开发工程的经验。第二个就是判断力、决定能力和领导力，推动各个团队的技术进展，并且能在压力下作出关键性的决策，然后将开发贯彻到底，而且要提高效率。架构师有权在技术上作出决定，在大家意见不一致的时候，他要能给出自己的一个意见。第三则是善于沟通。这其中首先就是赢得他人的信任。只有这样，才可以对他们进行说服，而后进行指导。微软架构师跟其他的合作的人没有直接的上下级关系，所以不能靠命令进行指导，所以必须要靠赢得其他人的赞同。第四点，是通常说的抽象思维和分析的能力。具体思维的人可能比较注重细节，但往往也会将问题复杂化，使头绪增多而无法收敛。 抽象思维可以帮架构师地从大量信息、系统文件中，看出一些规律来，而且找出与之相关的方面，归纳关键问题，表述模糊的概念并将其变成相关各方能够理解的项目构件。”<br />
    “最后，我认为无论是什么样的架构师都要具备一定的商业头脑，业务的知识要充分把握，因为对业务把握能够带来一个拥抱变化的能力，而且可以在设计的时候留出一点扩展的余地，适应将来可能来临的需求变化。”</p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanjiang.net.cn/archives/1307.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Freebsd 安装php/java bridge 方法与日志</title>
		<link>http://www.evanjiang.net.cn/archives/1010.html</link>
		<comments>http://www.evanjiang.net.cn/archives/1010.html#comments</comments>
		<pubDate>Fri, 08 May 2009 15:48:49 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[freebsd unix]]></category>
		<category><![CDATA[jboss]]></category>
		<category><![CDATA[resin]]></category>
		<category><![CDATA[系统架构]]></category>
		<category><![CDATA[php java bridge]]></category>
		<category><![CDATA[添加新标签]]></category>

		<guid isPermaLink="false">http://www.evanjiang.net.cn/?p=1010</guid>
		<description><![CDATA[<p>Freebsd 安装php/java bridge 方法与日志
Evan.Jiang
一、	安装Freebsd
安装freebsd的过程可参考其它文档，在这里可略
二、	安装JDK/JRE
1、下载由freebsd开发团队编译好的jdk/jre 1.5版本。
2、安装jdk/jre 1.5版本</p>
<p>1、安装jdk/jre
#pkg_add diablo-jdk-freebsd6-1.5.0.06.00.tbz
#pkg_add diablo-jre-freebsd6-1.5.0.06.00.tbz
2、	安装javavmwrapper
# cd /usr/ports/java/javavmwrapper
# make install clean </p>
<p>三、	下载php/java bridge
1、	下载php/java bridge
在下面网址下载php/java bridge 的源代码版本与字节版本</p>
<p>http://sourceforge.net/project/showfiles.php?group_id=117793</p>
<p>四、	上传php/java bridge
1、用cuteftp或leapftp等工具上传到服务器.</p>
<p>五、	解压php/java bridge
# tar zxvf php-java-bridge_3.1.8rc2.tar.bz2
# unzip –x php-java-bridge_3.1.8rc2_j2ee.zip
六、	安装php/javabridge
进入php/javabridge 解压目录.
1、# phpize &#038;&#038; ./configure &#8211;disable-backend &#8211;with-java= /usr/local/diablo-jdk1.5.0,/usr/local/diablo-jre1.5.0 &#038;&#038; /usr/local/bin/gmake
2、#sh install.sh
3、#make  install

七、	设置php.ini文件
#  vi /usr/local/Zend/etc/php.ini
在最后加入以下内容：
[java]
java.hosts = 127.0.0.1:8080
java.servlet = On
八、	安装resin等back-end
1 、# cd /usr/ports/www/resin3
2、# make WITH_APACHE2=yes install clean
3、编辑httpd.conf 在后面加入以下内容：

   [...]]]></description>
			<content:encoded><![CDATA[<p>Freebsd 安装php/java bridge 方法与日志<br />
Evan.Jiang<br />
一、	安装Freebsd<br />
安装freebsd的过程可参考其它文档，在这里可略<br />
二、	安装JDK/JRE<br />
1、下载由freebsd开发团队编译好的jdk/jre 1.5版本。<br />
2、安装jdk/jre 1.5版本</p>
<p>1、安装jdk/jre<br />
#pkg_add diablo-jdk-freebsd6-1.5.0.06.00.tbz<br />
#pkg_add diablo-jre-freebsd6-1.5.0.06.00.tbz<br />
2、	安装javavmwrapper<br />
# cd /usr/ports/java/javavmwrapper<br />
# make install clean </p>
<p>三、	下载php/java bridge<br />
1、	下载php/java bridge<br />
在下面网址下载php/java bridge 的源代码版本与字节版本</p>
<p>http://sourceforge.net/project/showfiles.php?group_id=117793</p>
<p>四、	上传php/java bridge<br />
1、用cuteftp或leapftp等工具上传到服务器.</p>
<p>五、	解压php/java bridge<br />
# tar zxvf php-java-bridge_3.1.8rc2.tar.bz2<br />
# unzip –x php-java-bridge_3.1.8rc2_j2ee.zip<br />
六、	安装php/javabridge<br />
进入php/javabridge 解压目录.<br />
1、# phpize &#038;&#038; ./configure &#8211;disable-backend &#8211;with-java= /usr/local/diablo-jdk1.5.0,/usr/local/diablo-jre1.5.0 &#038;&#038; /usr/local/bin/gmake<br />
2、#sh install.sh<br />
3、#make  install<br />
<span id="more-1010"></span><br />
七、	设置php.ini文件<br />
#  vi /usr/local/Zend/etc/php.ini<br />
在最后加入以下内容：<br />
[java]<br />
java.hosts = 127.0.0.1:8080<br />
java.servlet = On<br />
八、	安装resin等back-end<br />
1 、# cd /usr/ports/www/resin3<br />
2、# make WITH_APACHE2=yes install clean<br />
3、编辑httpd.conf 在后面加入以下内容：<br />
<IfModule mod_caucho.c><br />
    ResinConfigServer localhost 6802<br />
</IfModule><br />

<!-- Begin alimama Adserver code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8438729971248494";
/* 728x90, ������ 10-2-7 */
google_ad_slot = "4752526529";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Alimama Adserver code -->
<br />
4、	设置resin3随机启动<br />
5、	echo ‘resin3_enable=&#8221;YES&#8221; ‘ >> /etc/rc.conf<br />
6、	手动启动resin3<br />
#/usr/local/etc/rc.d/resin3.sh start<br />
7、<br />
九、	在resin的webapps建相应目录。<br />
 #cd /usr/local/resin/webapps<br />
#mkdir JavaBridge<br />
进入php-java-bridge_3.1.8rc2_j2ee的解压目录<br />
将JavaBridge .war 复制resin的webapps下的JavaBridge目录解压。<br />
# cp JavaBridge.war /usr/local/resin3/webapps/JavaBridge/<br />
#cd /usr/local/resin3/webapps/JavaBridge/<br />
# tar zxvf JavaBridge.war<br />
赋于 /usr/local/resin3/webapps/JavaBridge/权限<br />
# cd /usr/local/resin3/webapps/<br />
#chmod –R 777 JavaBridge/<br />
重启服务器<br />

<!-- Begin alimama Adserver code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8438729971248494";
/* 728x90, ������ 10-2-7 */
google_ad_slot = "4752526529";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Alimama Adserver code -->
<br />
十、	测试php/java bridge<br />
在网站根目录建一个test.php ，内容如下：<br />
<?php</p>
<p>// get instance of Java class java.lang.System in PHP<br />
$system = new Java('java.lang.System');</p>
<p>// demonstrate property access<br />
echo 'Java version=' . $system->getProperty(&#8216;java.version&#8217;) . &#8216;<br />&#8216;;<br />
echo &#8216;Java vendor=&#8217; . $system->getProperty(&#8216;java.vendor&#8217;) . &#8216;<br />&#8216;;<br />
echo &#8216;Java classpath=&#8217; . $system->getProperty(&#8216;java.classpath&#8217;) . &#8216;<br />&#8216;;<br />
echo &#8216;Java home=&#8217; . $system->getProperty(&#8216;java.java_home&#8217;) . &#8216;<br />&#8216;;<br />
echo &#8216;OS=&#8217; . $system->getProperty(&#8216;os.name&#8217;) . &#8216; &#8216; .<br />
$system->getProperty(&#8216;os.version&#8217;) . &#8216; on &#8216; .<br />
$system->getProperty(&#8216;os.arch&#8217;) . &#8216; <br />&#8216;;</p>
<p>// java.util.Date example<br />
$formatter = new Java(&#8216;java.text.SimpleDateFormat&#8217;,<br />
&#8220;EEEE, MMMM dd, yyyy &#8216;at&#8217; h:mm:ss a zzzz&#8221;);</p>
<p>echo $formatter->format(new Java(&#8216;java.util.Date&#8217;));</p>
<p>?></p>
<p>打开浏览器 输入 http://ip/test.php<br />
见到以下内容就可确定php/java bridge 安装正确<br />
Java version=1.5.0<br />
Java vendor=Sun Microsystems Inc.<br />
Java classpath=<br />
Java home=<br />
OS=FreeBSD 6.0-RELEASE on i386<br />
[o(String):"Friday, September 08, 2006 at 10:54:13 AM China Standard Time"]<br />
十一、	</p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanjiang.net.cn/archives/1010.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>软件工程师的灯下黑：重知识轻技术</title>
		<link>http://www.evanjiang.net.cn/archives/836.html</link>
		<comments>http://www.evanjiang.net.cn/archives/836.html#comments</comments>
		<pubDate>Fri, 20 Mar 2009 14:49:18 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[系统架构]]></category>
		<category><![CDATA[项目管理]]></category>
		<category><![CDATA[灯下黑]]></category>

		<guid isPermaLink="false">http://www.evanjiang.net.cn/?p=836</guid>
		<description><![CDATA[<p>电视《雍正王朝》讲这么一个故事：大将军年羹尧奉命到青海平叛，清军因路途遥远，军耗巨大，因此力求速战速决。但叛军避开锋芒，东躲西藏，年羹尧没有办法找到叛军决战。这时，朝廷内外压力越来越大，年羹尧陷入困境。这是一位谋士对年说：我知道叛军在那里。年大喜。这位谋士指出，敌人就在不远处的一座皇封寺庙里。年不信，谋士不慌不忙地说：这就是灯下黑，离自己越近就越不可能意识到，但却是最可能的地方。果然，大军一出，大获全胜。</p>
<p>我想讲一些关于程序员对自身认识的故事，这些故事都和灯下黑有关。只要正确认识自己，道理非常简单，但是，到处都可以看到灯下黑的故事。</p>
<p>某程序员，有一天接到一个任务：公司的有一个产品的文件太大，要求采用压缩算法，减少尺寸，最好能压缩20%。</p>
<p>程序员兴高采烈地接受任务：以前没玩过压缩算法，这下可以学习新东西！研究几个月后，他觉得差不多，就交给项目经理。项目经理正等着呢，高兴坏，拿着演示文件就去找产品经理。产品经理开始挺高兴，看完脸就拉下来。打开文件，把所有的文件尺寸一算，很淡淡的说：“才压缩10%，有什么用啊！”</p>
<p>程序员愣住，“不会吧！我看过的，压缩 20%！”</p>
<p>产品经理指着文件列表说：“你看，某文件是压缩20%，可你的压缩算法增加一个动态库文件，尺寸还不小，总共加起来，不就只减少10%吗？”</p>
<p>
各位看官，这是不是软件公司里经常发生的情形？</p>
<p>这种失败的成因当然是复杂的，有沟通管理方面的问题，也有程序员能力的问题。我今天想要说的是程序员认识方面的问题。</p>
<p>继续故事：</p>
<p>项目经理很没面子，回去就和程序员找原因。项目经理是老程序员，直话直说；终于弄清楚的事情的本质：</p>
<p>第一，这位程序员一个的时间读很多关于压缩算法的书，会不少算法。可是从来没比较过算法的优劣。这老兄觉得研究算法很有趣，乐此不彼，写好几个实现。</p>
<p>第二，这位老兄在最后几天才想起来20%的目标，也没太放在心上，看看差不多就拿出来。







</p>
<p>这是典型的程序员的认识问题，重知识而轻技术。</p>
<p>先从是么是知识，什么是技术说起。</p>
<p>知识就是知道，你知道某件事是怎么回事，就是有知识。</p>
<p>技术就是你能做出来，做得好叫技术好，做的不好叫技术差。</p>
<p>怎么写操作系统？看完操作系统原理，再苦读完源代码，这叫有知识。如果有本事把任务调度、内存管理、IO什么的都写出来，还能写得稳定，快速，可扩展，那是有技术。有知识和有技术可差远。早年我在工厂实习，要挫一个圆孔，拿着内锉刀干一天，只挫一个椭圆；师父来，三分钟，比冲床冲出来还圆！我是个好学徒，使用锉刀的知识全记住的，可以写一篇内圆挫使用大全。知识是有，可没这个技术。</p>
<p>程序员也一样。什么C++，Java，.net，什么STL，Struts，Spring，就是门门都满分，这也就是有知识。算不算技术好呢？差远。软件工程师界就专门出这种不会写程序的“高手”。我遇到一位老兄，精通Java知识，从虚拟机到各类框架，概念，无所不同，谈起Java来，没人说的过他。可是他的代码永远Bug最多，而且都是最简单的Bug，什么逻辑不对啊，功能没实现啊，UI不对啊。他的领导只有又好气又好笑。问下去，发现这老兄写几个程序文件以后，就不感兴趣，因为所用的技术没什么不知道的。所以马马虎虎交差。</p>
<p>说到底，写程序是个手艺活，就和古代的匠人一样，是要讲工艺的。比如一个玉匠，能打造栩栩如生的玉孔雀，那得打的好！要是一个玉匠说，这些手艺我都知道，重复做东西没劲，将就着给客人做出来吧！那他还不吃西北风！</p>
<p>可是，十几年来，程序员界有的是这样的人，还引发大规模争论。象什么C++和Java之争啦，J2EE和.Net之争啦。你看里边的帖子，不停有人赌这个阵营那个阵营，有发誓一辈子做C++的，有发誓打倒.Net。我还奇怪，专门没人效忠机器码的，那不是最难最有“学问”吗？这都是在争论什么知识最重要。可是啊，很少有人谈谈怎么做好产品的。</p>
<p>现在程序员最大的问题就是太看重知识，拼命追逐新玩意，而忽略身边的够得着东西。好，什么C++，Window API都知道，东西也弄出来，可是三天两头崩溃，还找不到原因？为什么？有没有看看代码，看看是不是某函数写2000行，自己都看不懂？是不是全局变量乱用？是不是没考虑前后兼容性？没考虑冗余和故障恢复？</p>
<p>末再回到开头的故事：</p>
<p>项目经理回去和程序员再重新设计，又多花一个月，终于达到目标。但因为这个部分是一个大项目的一部分，整个项目不得不延迟一个月。</p>
<p>年底考评的时候，项目经理给程序员打一个及格；程序员不服，告到总经理那里。总经理说：“你知足吧，给你打及格已经看在你干的很辛苦的份上，因为你没有按时完成，整个项目延迟一个月，这帐都没找你算呢。”程序员颓然。</p>
]]></description>
			<content:encoded><![CDATA[<p>电视《雍正王朝》讲这么一个故事：大将军年羹尧奉命到青海平叛，清军因路途遥远，军耗巨大，因此力求速战速决。但叛军避开锋芒，东躲西藏，年羹尧没有办法找到叛军决战。这时，朝廷内外压力越来越大，年羹尧陷入困境。这是一位谋士对年说：我知道叛军在那里。年大喜。这位谋士指出，敌人就在不远处的一座皇封寺庙里。年不信，谋士不慌不忙地说：这就是灯下黑，离自己越近就越不可能意识到，但却是最可能的地方。果然，大军一出，大获全胜。</p>
<p>我想讲一些关于程序员对自身认识的故事，这些故事都和灯下黑有关。只要正确认识自己，道理非常简单，但是，到处都可以看到灯下黑的故事。</p>
<p>某程序员，有一天接到一个任务：公司的有一个产品的文件太大，要求采用压缩算法，减少尺寸，最好能压缩20%。</p>
<p>程序员兴高采烈地接受任务：以前没玩过压缩算法，这下可以学习新东西！研究几个月后，他觉得差不多，就交给项目经理。项目经理正等着呢，高兴坏，拿着演示文件就去找产品经理。产品经理开始挺高兴，看完脸就拉下来。打开文件，把所有的文件尺寸一算，很淡淡的说：“才压缩10%，有什么用啊！”</p>
<p>程序员愣住，“不会吧！我看过的，压缩 20%！”</p>
<p>产品经理指着文件列表说：“你看，某文件是压缩20%，可你的压缩算法增加一个动态库文件，尺寸还不小，总共加起来，不就只减少10%吗？”</p>
<p><span id="more-836"></span><br />
各位看官，这是不是软件公司里经常发生的情形？</p>
<p>这种失败的成因当然是复杂的，有沟通管理方面的问题，也有程序员能力的问题。我今天想要说的是程序员认识方面的问题。</p>
<p>继续故事：</p>
<p>项目经理很没面子，回去就和程序员找原因。项目经理是老程序员，直话直说；终于弄清楚的事情的本质：</p>
<p>第一，这位程序员一个的时间读很多关于压缩算法的书，会不少算法。可是从来没比较过算法的优劣。这老兄觉得研究算法很有趣，乐此不彼，写好几个实现。</p>
<p>第二，这位老兄在最后几天才想起来20%的目标，也没太放在心上，看看差不多就拿出来。<br />

<!-- Begin alimama Adserver code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8438729971248494";
/* 728x90, ������ 10-2-7 */
google_ad_slot = "4752526529";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Alimama Adserver code -->
</p>
<p>这是典型的程序员的认识问题，重知识而轻技术。</p>
<p>先从是么是知识，什么是技术说起。</p>
<p>知识就是知道，你知道某件事是怎么回事，就是有知识。</p>
<p>技术就是你能做出来，做得好叫技术好，做的不好叫技术差。</p>
<p>怎么写操作系统？看完操作系统原理，再苦读完源代码，这叫有知识。如果有本事把任务调度、内存管理、IO什么的都写出来，还能写得稳定，快速，可扩展，那是有技术。有知识和有技术可差远。早年我在工厂实习，要挫一个圆孔，拿着内锉刀干一天，只挫一个椭圆；师父来，三分钟，比冲床冲出来还圆！我是个好学徒，使用锉刀的知识全记住的，可以写一篇内圆挫使用大全。知识是有，可没这个技术。</p>
<p>程序员也一样。什么C++，Java，.net，什么STL，Struts，Spring，就是门门都满分，这也就是有知识。算不算技术好呢？差远。软件工程师界就专门出这种不会写程序的“高手”。我遇到一位老兄，精通Java知识，从虚拟机到各类框架，概念，无所不同，谈起Java来，没人说的过他。可是他的代码永远Bug最多，而且都是最简单的Bug，什么逻辑不对啊，功能没实现啊，UI不对啊。他的领导只有又好气又好笑。问下去，发现这老兄写几个程序文件以后，就不感兴趣，因为所用的技术没什么不知道的。所以马马虎虎交差。</p>
<p>说到底，写程序是个手艺活，就和古代的匠人一样，是要讲工艺的。比如一个玉匠，能打造栩栩如生的玉孔雀，那得打的好！要是一个玉匠说，这些手艺我都知道，重复做东西没劲，将就着给客人做出来吧！那他还不吃西北风！</p>
<p>可是，十几年来，程序员界有的是这样的人，还引发大规模争论。象什么C++和Java之争啦，J2EE和.Net之争啦。你看里边的帖子，不停有人赌这个阵营那个阵营，有发誓一辈子做C++的，有发誓打倒.Net。我还奇怪，专门没人效忠机器码的，那不是最难最有“学问”吗？这都是在争论什么知识最重要。可是啊，很少有人谈谈怎么做好产品的。</p>
<p>现在程序员最大的问题就是太看重知识，拼命追逐新玩意，而忽略身边的够得着东西。好，什么C++，Window API都知道，东西也弄出来，可是三天两头崩溃，还找不到原因？为什么？有没有看看代码，看看是不是某函数写2000行，自己都看不懂？是不是全局变量乱用？是不是没考虑前后兼容性？没考虑冗余和故障恢复？</p>
<p>末再回到开头的故事：</p>
<p>项目经理回去和程序员再重新设计，又多花一个月，终于达到目标。但因为这个部分是一个大项目的一部分，整个项目不得不延迟一个月。</p>
<p>年底考评的时候，项目经理给程序员打一个及格；程序员不服，告到总经理那里。总经理说：“你知足吧，给你打及格已经看在你干的很辛苦的份上，因为你没有按时完成，整个项目延迟一个月，这帐都没找你算呢。”程序员颓然。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanjiang.net.cn/archives/836.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>练就软件开发真功夫</title>
		<link>http://www.evanjiang.net.cn/archives/826.html</link>
		<comments>http://www.evanjiang.net.cn/archives/826.html#comments</comments>
		<pubDate>Wed, 18 Mar 2009 14:22:40 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[系统架构]]></category>
		<category><![CDATA[练就 软件开发 真功夫]]></category>

		<guid isPermaLink="false">http://www.evanjiang.net.cn/?p=826</guid>
		<description><![CDATA[<p>软件是一种非常特殊的人工制品,但它本质上与其它工程产品并没有什么不同。我们完全可以将传统的工程学方法应用于软件的开发上;而将工程方法运用于解决软件开发的问题,便是软件工程。</p>
<p>软件的精确性、模糊性、复杂性、关联性、不一致性、多样性、不可视性、主观性、易变性与不确定性特性决定了软件的开发是一项非常富有挑战性的工作。
当前软件的规模越来越庞大,面对的问题也越来越复杂多样,人们不可能再像起初那样,直接进行编码,一次性地构造出最终软件交付。前述做法中,程序员同时要考虑用户如何操作软件来解决业务问题,如何组织大量代码的结构,要编写哪些具体代码来实现功能等,最终交付质量很难被保证。
为此,前辈们借用传统工程“中间工作产品”的概念,划分出软件需求、设计、代码、测试案例等中间制品,使得开发者能够分步去完成这些性质相对单一的制品,以避免同时关注性质各异甚至完全相反的内容。
然而,软件庞大的规模,使得既便是单一中间制品,其涵盖的信息量也仍然超出人类思维能力的极限,于是前辈们又借鉴传统工程“分而治之”的根本策略,将软件划分为较小的模块来分别构造,这样就大幅减少了开发者同时要处理的信息量。另外,软件交付的质量,将可以通过控制各个中间制品的质量,以及各个模块的质量,来得以保证,这样质量控制工作也变得更为容易了。
除此之外,软件还存在不可视性、主观性、易变性(可塑性)与不确定性等问题,传统工程学方法尚不能很好地解决它们;当代软件工程的大师们经过不懈的努力,终于给出了有效的药方。

图1 软件开发中间制品关系示意图</p>
<p>“中间工作产品”(见图1),例如需求,其开发的过程依然很复杂,需要开发者具备非常专业的技能;而“分而治之”的策略也不是任何人都能够运用自如;以架构为中心、迭代增量式开发,更是只有那些技术管理经验极为丰富的人,才有能力在项目中加以推行。换句话说,我们不可能培养出软件通才,能够掌握软件工程中涉及的所有方法与技能。这样,我们还必须借用传统工程“分工协作”的做法,组织具备不同知识与技能的成员,去分别从事不同性质的软件开发活动(见图2)。</p>
<p>图2 软件开发角色示意图</p>
<p>将软件开发的“中间工作产品”到底是划分为需求规格文档、概要设计文档等,还是划分为业务模型、用例模型、用例规约,以及架构文档等,这些都不是普通软件工程师在短时间内所能总结和确定的。
实际上,软件是人类迄今为止所面对的最复杂事物,其对应的软件工程方法,较之其它工程方法要复杂得多。
如果闭门造车,完全从头来设计一种软件工程方法,其工作量将极其庞大,而且它第一次在实际项目中实践成功的概率是零。我们只能参照业界成熟的标准,并结合以往大量实践的总结,在新的项目中采用被验证过的软件工程方法。
软件过程
为了方便项目组在新的项目中重复被验证过的方法与经验,需要将如何组织开发活动、分配人员职责等进行明确的定义。
所谓“软件过程software process”是指将涉众(客户、用户等)的需要转化为软件系统交付的所有活动集合。它定义了软件开发活动的序列,即按照什么顺序,在何时When、由何人Who、在何处Where做什么What(产出的制品)、怎么做How(使用什么工具Tool,应用什么技术等)才能达成目标Goal,以及为什么这么做Why等。
如图3所示,软件项目的上下文是客户及其业务(或者是某个领域问题);为了支持业务的运作、实现客户的要求,必须设立一个软件项目,以组织相关的人员,将涉众的需要最终转化为软件交付。</p>
<p>图3 软件开发项目构成示意图</p>
<p>软件项目中包含了拥有不同技能的人才,他们将使用合适的工具,运用相关的技术,执行各类活动来完成项目。项目组采用的软件过程事先定义了如何组织这些人才,怎样使用工具,和按什么顺序执行相应的活动。项目组实际执行这个软件过程,从而实施了整个项目。
当前软件行业最为急迫的任务,就是研究与设计这些适用于不同类型软件、并适合不同状况开发团队来应用的软件过程与方法。
这些过程方法与传统的工程学方法一样,必须是在经济上切实可行的;也就是说,它们能够解决项目问题、普通素质的团队能较快地学习和掌握、执行的成本可以被接受、执行的过程可以被控制等。
一个有效的软件过程应当具备如下属性:
◇保证交付产品质量
◇能够迅速减少项目(需求、技术等)风险
◇保证项目(进度、成本等因素)可预测性与可控性
◇能够获得和提供最佳实践方法,并让团队较快地学习和掌握
◇促进涉众在软件开发领域内的达成共识和相互理解








软件过程的表述
为了设计软件过程,并让项目组学习和在实际项目中应用,必须使用适当的形式来表述它,以方便人们进行交流。
与软件过程比较相似的是企业的业务流程,实际上我们也可以将软件开发的过程看作是软件机构的业务流程。业界描述业务流程的主流途径是业务建模。
OMG组织较早便通过扩展UML语言来描述企业的业务流程,即UML在业务建模上的侧面扩展Profile。因为软件过程与之类似,OMG组织近几年又参考前者专门定义了表达软件过程的标准——SPEM(Software Process Engineering Metamodel软件过程工程元模型)。
软件过程异常复杂,包含了多种性质各异的活动,例如需求的开发、项目管理、质量保证等;这些活动交织在一起,人们很难理解与把握;为了简化表达结构,UP统一软件过程借用“分而治之”的思想,将这些不同性质的活动,及其关联的角色、工件等,组织为不同的科目discipline。而每个科目中的相关活动需要相互协同,体现了一种执行顺序关系,UP使用工作流workflow来精确地定义这种执行序列。
软件过程中每种活动的执行,都具有类似的行为结构:这项活动被对应的人员(角色Role)所执行,在执行过程中,具体人员将参照指南、工具指导等,使用工具并利用模板,来创建或修改工件Artifact;为了确保工件的质量,还要对照检查点来进行复核。这些属于工作流的基本要素,在工作流细节中将会采用这种统一的模式来描述对应活动的具体内容。
此外,软件过程本身是动态的,科目中的各项活动最终要在时间轴上对应展开,这些关系将在生命周期模型中被表述。








基本组成要素
软件过程虽然复杂,但它的基本行为结构却是一致的,我们可以将这些要素抽象出,并利用这些要素来描述过程本身。
活动Activity——指具体人员在工作流中充当某种角色所执行的有形工作单元,其完成将为项目提供符合要求的结果(工件)。活动存在明确的目的,并有明确定义的输入(一组工件),和产生明确定义的输出(另一组工件),例如模型、代码或文档等。
一个活动一般延续几小时到几天,它通常由一类角色来承担,并影响一个或少数几个工件。有时可能会对同一工件重复多次活动,例如同一用例规约可能在多次迭代中被修改。
◇工作单元Work Unit—在项目计划中,当把任务(活动)分配到具体的人员时,就产生了一个被清晰界定的工作单元。
◇角色Role—指对开发过程中承担相似职责的一类岗位的抽象。每个角色都具有一系列在对应活动中所要担负的职责。
◇工件Artifact—由相关角色在执行活动的过程中,创建、修改和使用的最终或中间产物。工件由某个或多个角色负责;它们通常要被置于配置管理之下。</p>
<p>◇指南Guideline—是相关活动的规则、建议和启示,用于帮助项目人员开展活动,例如建模和编码的指南等。
◇工具指导Tool Mentor—阐述如何使用特定工具来执行一项活动或活动中的一个步骤,例如使用Rational Rose来绘制设计模型等。
◇模板Template—是一种预定义的工件母板,它确定了工件的格式和内容框架,项目人员可以直接用来创建实际的工件。
◇检查点Checkpoints—列出用于验收一种工件质量的核实标准,通过判断是否通过这些检查点,来复核工件质量是否满足要求。
◇报告Report—为了便于阅读交流,经常需要将相关的工件内容,转换为报告的形式。</p>
<p>软件过程科目discipline
科目是关于特定关注领域的一组相关活动,它描述了基于一类技能的关联角色、活动与工件,及其之间关系。每个科目下都对应有相应的工作流程。
科目是软件开发活动的一种大粒度划分,每个科目都有一组特定的目标,以解决软件开发中的某类重大问题,包括产出相关的工件、或支持其它科目的活动等。
而软件过程中的诸多工件,也以科目的形式组织在一起,组成工件集合。例如,业务建模科目的目标是描述客户的业务上下文,通过探索业务自动化来识别软件需求;而相关的产出是包含业务用例模型、业务词汇表、业务规则等的业务建模工件集。软件过程中的诸多角色,虽然不像工件那样直接与科目一一对应,但是它仍然与科目有密切的关联。例如,分析人员角色主要参与业务建模和需求科目的活动,而测试人员角色只是参与测试科目的活动。</p>
<p>科目下的工作流workflow
将属于某个科目下的各种开发活动按顺序组织在一起,就形成了一个工作流。它定义了一组生成特定工件集而可能要经历的所有活动序列,并从逻辑上把相关工作角色与活动相对应,以描述软件过程的流程结构。
软件开发的工作流workflow与普通问题解决步骤的流程并无本质差别,但其复杂程度则高得多。从图中我们还可以看到管理需求变更,与分析问题等活动是并行执行的。</p>
<p>工作流明细workflow details
工作流workflow中只是列出了相关的活动名称,而与活动相关的角色Role、工件Artifact、工具指南等还需要在工作流细节中加以描述。
系统分析师要执行开发前景文档Develop Vision、获取通用词汇表Capture a Common Vocabulary、识别执行者与用例Find Actors and Use Cases等活动;这些活动涉及相关工件,例如在识别执行者与用例活动中,前景文档是输入,用例模型是输出。
活动、角色、工件等本身还要进一步被详细地定义,将在相应的文档中加以描述。在活动的细节说明中,常常还会附上相关的指南和工具指导的链接;而工件的细节说明中,则会附上相关的模板和检查点。</p>
]]></description>
			<content:encoded><![CDATA[<p>软件是一种非常特殊的人工制品,但它本质上与其它工程产品并没有什么不同。我们完全可以将传统的工程学方法应用于软件的开发上;而将工程方法运用于解决软件开发的问题,便是软件工程。</p>
<p>软件的精确性、模糊性、复杂性、关联性、不一致性、多样性、不可视性、主观性、易变性与不确定性特性决定了软件的开发是一项非常富有挑战性的工作。<br />
当前软件的规模越来越庞大,面对的问题也越来越复杂多样,人们不可能再像起初那样,直接进行编码,一次性地构造出最终软件交付。前述做法中,程序员同时要考虑用户如何操作软件来解决业务问题,如何组织大量代码的结构,要编写哪些具体代码来实现功能等,最终交付质量很难被保证。<br />
为此,前辈们借用传统工程“中间工作产品”的概念,划分出软件需求、设计、代码、测试案例等中间制品,使得开发者能够分步去完成这些性质相对单一的制品,以避免同时关注性质各异甚至完全相反的内容。<br />
然而,软件庞大的规模,使得既便是单一中间制品,其涵盖的信息量也仍然超出人类思维能力的极限,于是前辈们又借鉴传统工程“分而治之”的根本策略,将软件划分为较小的模块来分别构造,这样就大幅减少了开发者同时要处理的信息量。另外,软件交付的质量,将可以通过控制各个中间制品的质量,以及各个模块的质量,来得以保证,这样质量控制工作也变得更为容易了。<br />
除此之外,软件还存在不可视性、主观性、易变性(可塑性)与不确定性等问题,传统工程学方法尚不能很好地解决它们;当代软件工程的大师们经过不懈的努力,终于给出了有效的药方。<br />
<span id="more-826"></span><br />
图1 软件开发中间制品关系示意图</p>
<p>“中间工作产品”(见图1),例如需求,其开发的过程依然很复杂,需要开发者具备非常专业的技能;而“分而治之”的策略也不是任何人都能够运用自如;以架构为中心、迭代增量式开发,更是只有那些技术管理经验极为丰富的人,才有能力在项目中加以推行。换句话说,我们不可能培养出软件通才,能够掌握软件工程中涉及的所有方法与技能。这样,我们还必须借用传统工程“分工协作”的做法,组织具备不同知识与技能的成员,去分别从事不同性质的软件开发活动(见图2)。</p>
<p>图2 软件开发角色示意图</p>
<p>将软件开发的“中间工作产品”到底是划分为需求规格文档、概要设计文档等,还是划分为业务模型、用例模型、用例规约,以及架构文档等,这些都不是普通软件工程师在短时间内所能总结和确定的。<br />
实际上,软件是人类迄今为止所面对的最复杂事物,其对应的软件工程方法,较之其它工程方法要复杂得多。<br />
如果闭门造车,完全从头来设计一种软件工程方法,其工作量将极其庞大,而且它第一次在实际项目中实践成功的概率是零。我们只能参照业界成熟的标准,并结合以往大量实践的总结,在新的项目中采用被验证过的软件工程方法。<br />
软件过程<br />
为了方便项目组在新的项目中重复被验证过的方法与经验,需要将如何组织开发活动、分配人员职责等进行明确的定义。<br />
所谓“软件过程software process”是指将涉众(客户、用户等)的需要转化为软件系统交付的所有活动集合。它定义了软件开发活动的序列,即按照什么顺序,在何时When、由何人Who、在何处Where做什么What(产出的制品)、怎么做How(使用什么工具Tool,应用什么技术等)才能达成目标Goal,以及为什么这么做Why等。<br />
如图3所示,软件项目的上下文是客户及其业务(或者是某个领域问题);为了支持业务的运作、实现客户的要求,必须设立一个软件项目,以组织相关的人员,将涉众的需要最终转化为软件交付。</p>
<p>图3 软件开发项目构成示意图</p>
<p>软件项目中包含了拥有不同技能的人才,他们将使用合适的工具,运用相关的技术,执行各类活动来完成项目。项目组采用的软件过程事先定义了如何组织这些人才,怎样使用工具,和按什么顺序执行相应的活动。项目组实际执行这个软件过程,从而实施了整个项目。<br />
当前软件行业最为急迫的任务,就是研究与设计这些适用于不同类型软件、并适合不同状况开发团队来应用的软件过程与方法。<br />
这些过程方法与传统的工程学方法一样,必须是在经济上切实可行的;也就是说,它们能够解决项目问题、普通素质的团队能较快地学习和掌握、执行的成本可以被接受、执行的过程可以被控制等。<br />
一个有效的软件过程应当具备如下属性:<br />
◇保证交付产品质量<br />
◇能够迅速减少项目(需求、技术等)风险<br />
◇保证项目(进度、成本等因素)可预测性与可控性<br />
◇能够获得和提供最佳实践方法,并让团队较快地学习和掌握<br />
◇促进涉众在软件开发领域内的达成共识和相互理解<br />

<!-- Begin alimama Adserver code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8438729971248494";
/* 728x90, ������ 10-2-7 */
google_ad_slot = "4752526529";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Alimama Adserver code -->
<br />
软件过程的表述<br />
为了设计软件过程,并让项目组学习和在实际项目中应用,必须使用适当的形式来表述它,以方便人们进行交流。<br />
与软件过程比较相似的是企业的业务流程,实际上我们也可以将软件开发的过程看作是软件机构的业务流程。业界描述业务流程的主流途径是业务建模。<br />
OMG组织较早便通过扩展UML语言来描述企业的业务流程,即UML在业务建模上的侧面扩展Profile。因为软件过程与之类似,OMG组织近几年又参考前者专门定义了表达软件过程的标准——SPEM(Software Process Engineering Metamodel软件过程工程元模型)。<br />
软件过程异常复杂,包含了多种性质各异的活动,例如需求的开发、项目管理、质量保证等;这些活动交织在一起,人们很难理解与把握;为了简化表达结构,UP统一软件过程借用“分而治之”的思想,将这些不同性质的活动,及其关联的角色、工件等,组织为不同的科目discipline。而每个科目中的相关活动需要相互协同,体现了一种执行顺序关系,UP使用工作流workflow来精确地定义这种执行序列。<br />
软件过程中每种活动的执行,都具有类似的行为结构:这项活动被对应的人员(角色Role)所执行,在执行过程中,具体人员将参照指南、工具指导等,使用工具并利用模板,来创建或修改工件Artifact;为了确保工件的质量,还要对照检查点来进行复核。这些属于工作流的基本要素,在工作流细节中将会采用这种统一的模式来描述对应活动的具体内容。<br />
此外,软件过程本身是动态的,科目中的各项活动最终要在时间轴上对应展开,这些关系将在生命周期模型中被表述。<br />

<!-- Begin alimama Adserver code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8438729971248494";
/* 728x90, ������ 10-2-7 */
google_ad_slot = "4752526529";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Alimama Adserver code -->
<br />
基本组成要素<br />
软件过程虽然复杂,但它的基本行为结构却是一致的,我们可以将这些要素抽象出,并利用这些要素来描述过程本身。<br />
活动Activity——指具体人员在工作流中充当某种角色所执行的有形工作单元,其完成将为项目提供符合要求的结果(工件)。活动存在明确的目的,并有明确定义的输入(一组工件),和产生明确定义的输出(另一组工件),例如模型、代码或文档等。<br />
一个活动一般延续几小时到几天,它通常由一类角色来承担,并影响一个或少数几个工件。有时可能会对同一工件重复多次活动,例如同一用例规约可能在多次迭代中被修改。<br />
◇工作单元Work Unit—在项目计划中,当把任务(活动)分配到具体的人员时,就产生了一个被清晰界定的工作单元。<br />
◇角色Role—指对开发过程中承担相似职责的一类岗位的抽象。每个角色都具有一系列在对应活动中所要担负的职责。<br />
◇工件Artifact—由相关角色在执行活动的过程中,创建、修改和使用的最终或中间产物。工件由某个或多个角色负责;它们通常要被置于配置管理之下。</p>
<p>◇指南Guideline—是相关活动的规则、建议和启示,用于帮助项目人员开展活动,例如建模和编码的指南等。<br />
◇工具指导Tool Mentor—阐述如何使用特定工具来执行一项活动或活动中的一个步骤,例如使用Rational Rose来绘制设计模型等。<br />
◇模板Template—是一种预定义的工件母板,它确定了工件的格式和内容框架,项目人员可以直接用来创建实际的工件。<br />
◇检查点Checkpoints—列出用于验收一种工件质量的核实标准,通过判断是否通过这些检查点,来复核工件质量是否满足要求。<br />
◇报告Report—为了便于阅读交流,经常需要将相关的工件内容,转换为报告的形式。</p>
<p>软件过程科目discipline<br />
科目是关于特定关注领域的一组相关活动,它描述了基于一类技能的关联角色、活动与工件,及其之间关系。每个科目下都对应有相应的工作流程。<br />
科目是软件开发活动的一种大粒度划分,每个科目都有一组特定的目标,以解决软件开发中的某类重大问题,包括产出相关的工件、或支持其它科目的活动等。<br />
而软件过程中的诸多工件,也以科目的形式组织在一起,组成工件集合。例如,业务建模科目的目标是描述客户的业务上下文,通过探索业务自动化来识别软件需求;而相关的产出是包含业务用例模型、业务词汇表、业务规则等的业务建模工件集。软件过程中的诸多角色,虽然不像工件那样直接与科目一一对应,但是它仍然与科目有密切的关联。例如,分析人员角色主要参与业务建模和需求科目的活动,而测试人员角色只是参与测试科目的活动。</p>
<p>科目下的工作流workflow<br />
将属于某个科目下的各种开发活动按顺序组织在一起,就形成了一个工作流。它定义了一组生成特定工件集而可能要经历的所有活动序列,并从逻辑上把相关工作角色与活动相对应,以描述软件过程的流程结构。<br />
软件开发的工作流workflow与普通问题解决步骤的流程并无本质差别,但其复杂程度则高得多。从图中我们还可以看到管理需求变更,与分析问题等活动是并行执行的。</p>
<p>工作流明细workflow details<br />
工作流workflow中只是列出了相关的活动名称,而与活动相关的角色Role、工件Artifact、工具指南等还需要在工作流细节中加以描述。<br />
系统分析师要执行开发前景文档Develop Vision、获取通用词汇表Capture a Common Vocabulary、识别执行者与用例Find Actors and Use Cases等活动;这些活动涉及相关工件,例如在识别执行者与用例活动中,前景文档是输入,用例模型是输出。<br />
活动、角色、工件等本身还要进一步被详细地定义,将在相应的文档中加以描述。在活动的细节说明中,常常还会附上相关的指南和工具指导的链接;而工件的细节说明中,则会附上相关的模板和检查点。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanjiang.net.cn/archives/826.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>需求编写十佳经验</title>
		<link>http://www.evanjiang.net.cn/archives/822.html</link>
		<comments>http://www.evanjiang.net.cn/archives/822.html#comments</comments>
		<pubDate>Wed, 18 Mar 2009 14:18:47 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[系统架构]]></category>
		<category><![CDATA[需求编写 经验]]></category>

		<guid isPermaLink="false">http://www.evanjiang.net.cn/?p=822</guid>
		<description><![CDATA[<p>需求表述不善可带来毁灭性影响，其所引发的多米诺效应可导致耗时返工、延期交付及预算超支，严重的还可造成业务违规甚至人员伤亡。
    近年来，随着ISO9000、CMM/CMMI、六西格码等国际标准逐步引入中国，“需求管理”正成为中国当前工程应用和商业热域的热点。目前，有关需求管理的实践大量应用于软件开发工程等领域，软件开发团队在开始一个新的项目之前，会通过详细的用户需求调研准确捕获了用户需求并汇总分析后，再进行下一步的设计与实施工作，以避免因未能正确识别用户的真正需求而导致不断返工和工作成本增加。</p>
<p>    对于从事软件工程的程序员们来说，在进行项目开发之前创建和管理良好的需求是非常重要的第一步，同时也是一项挑战。需求表述不善可带来毁灭性影响，其引发的多米诺效应可导致耗时返工、延期交付及预算超支，严重的还可造成业务违规甚至人员伤亡。因此，开发团队需要首先有效定义和管理需求，才能确保在保证进度和控制预算的同时，产品能够满足用户所需。</p>
<p>    良好需求的特征　　　　　　　　　　　　含义</p>
<p>    正确(Correct)　　　　　　　　　　　　 技术可行，内容合法</p>
<p>    完整(Complete)　　　　　　　　　　　　能够表达一个完整的想法</p>
<p>    清晰(Clear)　　　　　　　　　　　　　 不模棱两可，不易被误导</p>
<p>    一致性(Consistent)　　　　　　　　　　不与其它需求相冲突</p>
<p>    可验证性(Verifiable)　　　　　　　　　可验证系统能够满足用户需要</p>
<p>    可追踪性(Traceable)　　　　　　　　　 可唯一识别并进行跟踪</p>
<p>    可行性(Feasible)　　　　　　　　　　　可在预期成本和计划进度内完成</p>
<p>    模块化(Modular)　　　　　　　　　　　 可单独变更而不会造成较大影响</p>
<p>    独立于设计(Design-independent)　　　　不包括项目设计和实现的细节、计划信息等</p>
<p>   [...]]]></description>
			<content:encoded><![CDATA[<p>需求表述不善可带来毁灭性影响，其所引发的多米诺效应可导致耗时返工、延期交付及预算超支，严重的还可造成业务违规甚至人员伤亡。<br />
    近年来，随着ISO9000、CMM/CMMI、六西格码等国际标准逐步引入中国，“需求管理”正成为中国当前工程应用和商业热域的热点。目前，有关需求管理的实践大量应用于软件开发工程等领域，软件开发团队在开始一个新的项目之前，会通过详细的用户需求调研准确捕获了用户需求并汇总分析后，再进行下一步的设计与实施工作，以避免因未能正确识别用户的真正需求而导致不断返工和工作成本增加。</p>
<p>    对于从事软件工程的程序员们来说，在进行项目开发之前创建和管理良好的需求是非常重要的第一步，同时也是一项挑战。需求表述不善可带来毁灭性影响，其引发的多米诺效应可导致耗时返工、延期交付及预算超支，严重的还可造成业务违规甚至人员伤亡。因此，开发团队需要首先有效定义和管理需求，才能确保在保证进度和控制预算的同时，产品能够满足用户所需。</p>
<p>    良好需求的特征　　　　　　　　　　　　含义</p>
<p>    正确(Correct)　　　　　　　　　　　　 技术可行，内容合法</p>
<p>    完整(Complete)　　　　　　　　　　　　能够表达一个完整的想法</p>
<p>    清晰(Clear)　　　　　　　　　　　　　 不模棱两可，不易被误导</p>
<p>    一致性(Consistent)　　　　　　　　　　不与其它需求相冲突</p>
<p>    可验证性(Verifiable)　　　　　　　　　可验证系统能够满足用户需要</p>
<p>    可追踪性(Traceable)　　　　　　　　　 可唯一识别并进行跟踪</p>
<p>    可行性(Feasible)　　　　　　　　　　　可在预期成本和计划进度内完成</p>
<p>    模块化(Modular)　　　　　　　　　　　 可单独变更而不会造成较大影响</p>
<p>    独立于设计(Design-independent)　　　　不包括项目设计和实现的细节、计划信息等</p>
<p>    本文旨在阐述良好需求描述的特征，并介绍有助于更好地编写软件工程需求说明文档的十佳经验，以帮助软件开发团队能够更快更好地取得投资收益。<br />
<span id="more-822"></span><br />
    高质量需求的特征</p>
<p>    首先的问题是，何为良好的需求？一般而言，一项编写良好的需求描述，应该包含以下特征（见表1）:</p>
<p>    同时，一项需求描述应该用一个包含主语和谓语的完整句子来表述，使用“应该”“必须”等词来表明其强制性，使用“可以”等词来指明可选性。一个完整的需求还应写明预期达成的目标，并包含质量的达标标准或其它可测量的指标。</p>
<p>    提高需求编写质量的十佳经验</p>
<p>    在明确了何为良好的需求之后，以下介绍十个可以帮助开发团队编写出更好的需求描述的方法，加速软件工程投资回报率。</p>
<p>    经验1:将需求结构化(Structuring)</p>
<p>    每一项需求既不能被重复描述也不能被遗漏，诀窍之一是将需求结构化。需求组织应具有良好的结构，以增进理解，同时避免出现重复和忽略的情况。同时，须具备对需求的向上和向下的追溯能力之后，团队才能够评估需求的覆盖范围。结构化组织需求是控制和改善需求质量的第一步。</p>
<p>    经验2:把握好用户需要(customer needs)、项目需求(requirments)和合同文本(contractual documents)之间的互动关系</p>
<p>    用户需要是指软件的使用者对于软件所能实现的功能的期望及操作便利性上的要求;软件工程项目中的需求，则是将这些用户需要通过特定的描述方法重新表述为程序开发者可以识别并据此工作的说明性语句。</p>
<p>    一个项目需求通常会比用户的某项需要在描述上更加共性化，以便满足多个用户的需要。此外还经常会有一份工作合同来约束开发团队和软件使用方之间的工作关系。开发团队要把握好这三个因素之间的互动关系，把它们互相关联起来进行有机的管理，这能大大提高项目成功的几率。</p>
<p>    经验3:重视非功能性需求(Constraints)</p>
<p>    对于编写需求说明书而言，涉及法规遵从和提高软件系统质量的非功能性需求（又称约束条件，Constraints）同样重要，它们通常包括软件的性能、界面和可维护性等方面。</p>
<p>    编写良好需求应包含对约束条件的覆盖，原因是一旦如下领域（例如，性能、可靠性和易用性等）在开发完成后出现缺陷，通常都无法在系统中对其进行重新设计。因此，在项目初期将所有类型的非功能性需求考虑在内，可帮助开发团队大幅提高项目成功的几率。</p>
<p>    经验4:将需求可视化(Visualization)</p>
<p>    大多数需求分析人员发现建模有助于直观化文字形式的需求。无论是在白板上绘图、使用Microsoft PowerPoint演示工具，还是仅仅在脑海中构建一个模型，都可视为一种建模方法。以上这种图型化的文档应与文字形式的需求描述一起统一管理，以确保一致性、可跟踪性和变更控制能力。可视化需求建模提供了一种与客户及最终用户沟通的简单而有效的方法，通过该方法可较容易地掌握客户和最终用户的需求。此外，图型化还有助于阐明需求，增进软件项目所有相关人员之间的沟通与协作。</p>
<p>    经验5:使需求具备可测试性(Testable)</p>
<p>    产生良好需求的另一种行之有效的方法，就是从初期就确保每个需求具备明确的可验证性，这种做法不仅有助于为项目后续阶段做好准备，还可以帮助编写者保持正确的思路。</p>
<p>    对于非功能性需求此规则也同样适用，例如，对于“软件必须具有高可用性”这种表述的需求我们无法进行测试，而改写成明确的“普通用户应能够在3分钟内生成一个报告”就使该需求具备了可验证性。</p>
<p>    经验6:在客户需求和开发能力之间找到平衡</p>
<p>    许多情况下，较少的需求数量有助于产生更加优秀的需求描述。软件工程项目不可能实现既采纳和满足企业所有用户的需求、营销理念和商业计划，同时还符合预算并能按期交付。项目经理必须找到客户需求和开发能力之间的平衡点，确定可为客户带来最大价值，并帮助企业提升创新能力的那些需求，而不是一味地试图满足用户所有需求。</p>
<p>    经验7:管理好需求变更</p>
<p>    大多数软件工程项目中，来自用户的需求经常会发生变化。随着项目的进展，开发团队要保持清醒的头脑、按照工程要求做出相应调整，并响应不断变化的市场形势和客户需要。仅仅编写出完美的首版需求描述是不够的，如果未能对需求的变更过程进行恰当管理，那么控制不善的变更便可能导致系统和软件功能缺失、返工以及利润损失。开发团队应该实施可靠的、可重复的变更控制流程，借助Telelogic DOORS?、Telelogic Change?等工具，实施成熟的变更管理解决是一个良好途径。</p>
<p>    经验8:善于利用监测与跟踪工具</p>
<p>    复杂的项目都要求实现自动数据收集功能和简便的报告流程，以简化项目管理工作。同样地，项目经理和所有利益相关者都应拥有计量和趋势的“管理面板”，该面板可帮助他们快速监视项目活动（如，进展、增长和实际需求的变动等）。</p>
<p>    项目经理应将其主要精力放在制定决策上，而不是放在手动收集数据和编制报告方面。更为重要的是，必须高水准地显示主要需求的监视信息，从而使用户能够根据异常情况实施管理，并迅速查明故障区域。如果某需求或整个子系统变更频繁，则表示应就该需求对客户进行二次调查。如果执行阶段出现大规模返工的情况，则表示原始需求表述不妥。跟踪和分析趋势是CMMI第4级和第5级的主要内容，通过这些活动，企业的需求编写质量可得到持续改善。</p>
<p>    经验9:建立范例知识库(Knowledge Database)</p>
<p>    提高需求质量的另一有效途径是建立范例知识库，并参考其中的典型范例。知识库内容应该包括:良好需求和文档的正、反面示例，以往项目中可反映团队在特定领域内专门知识的良好（和不良）需求。为了使开发团队可以更好的参考，知识库中的需求案例应具备明显的积极或消极意义，而非中规中矩的。通过知识库示例开发团队可以参考以往的经验、吸取教训，避免重蹈覆辙，进而提高需求编写的质量、一致性和完整性。</p>
<p>    经验10:正确的重用以往优秀需求</p>
<p>    当之前项目的已编写的良好需求适用于当前情况时，不要单纯地将原有需求直接复制。重新使用以往需求的正确方法是继续维持两个需求之间的联系，如通常打上re-use标记。此标记使分析人员能够随时查找到原始需求，以检查需求分解分配等信息。通过灵活的方法重新用以往需求，开发团队可以获得技能、经验和知识的共享。</p>
<p>    编写好的需求说明是一个开发项目最为重要的活动之一，优秀的需求描述可以改善并加速项目的投资回报。就好像“垃圾输入，垃圾输出(garbage in, garbage out)”所表明的那样，如果前期用户需求收集得不明确，那么后期的开发过程注定生产错误的产品。开发团队可以通过经验提升需求编写质量。此外，通过应用业界领先的Telelogic DOORS等需求管理工具，可以优化项目开发的沟通和协作的过程，提升软件项目过程质量。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanjiang.net.cn/archives/822.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>需求分析20条原则</title>
		<link>http://www.evanjiang.net.cn/archives/820.html</link>
		<comments>http://www.evanjiang.net.cn/archives/820.html#comments</comments>
		<pubDate>Wed, 18 Mar 2009 14:14:02 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[系统架构]]></category>
		<category><![CDATA[需求分析 原则]]></category>

		<guid isPermaLink="false">http://www.evanjiang.net.cn/?p=820</guid>
		<description><![CDATA[<p>对商业用户来说，他们后面是成百上千个供应商，前面是成千上万个消费顾客。怎样利用软件管理错综复杂的供应商和消费顾客，如何做好精细到一个小小调料包的进、销、调、存的商品流通工作，这些都是商业企业需要信息管理系统的理由。软件开发的意义也就在于此。而弄清商业用户如此复杂需求的真面目，正是软件开发成功的关键所在。</p>
<p>    经理：“我们要建立一套完整的商业管理软件系统，包括商品的进、销、调、存管理，是总部-门店的连锁经营模式。通过通信手段门店自动订货，供应商自动结算，卖场通过扫条码实现销售，管理人员能够随时查询门店商品销售和库存情况。另外，我们也得为政府部门提供关于商品营运的报告。”</p>
<p>    分析员：“我已经明白这个项目的大体结构框架，这非常重要，但在制定计划之前，我们必须收集一些需求。”</p>
<p>    经理觉得奇怪：“我不是刚告诉你我的需求了吗？”</p>
<p>    分析员：“实际上，您只说明了整个项目的概念和目标。这些高层次的业务需求不足以提供开发的内容和时间。我需要与实际将要使用系统的业务人员进行讨论，然后才能真正明白达到业务目标所需功能和用户要求，了解清楚后，才可以发现哪些是现有组件即可实现的，哪些是需要开发的，这样可节省很多时间。”

    经理：“业务人员都在招商。他们非常忙，没有时间与你们详细讨论各种细节。你能不能说明一下你们现有的系统？”</p>
<p>    分析员尽量解释从用户处收集需求的合理性：“如果我们只是凭空猜想用户的要求，结果不会令人满意。我们只是软件开发人员，而不是采购专家、营运专家或是财务专家，我们并不真正明白您这个企业内部运营需要做些什么。我曾经尝试过，未真正明白这些问题就开始编码，结果没有人对产品满意。”</p>
<p>    经理坚持道：“行了，行了，我们没有那么多的时间。让我来告诉您我们的需求。实际上我也很忙。请马上开始开发，并随时将你们的进展情况告诉我。”</p>
<p>    风险躲在需求的迷雾之后</p>
<p>    以上我们看到的是某客户项目经理与系统开发小组的分析人员讨论业务需求。在项目开发中，所有的项目风险承担者都对需求分析阶段备感兴趣。这里所指的风险承担者包括客户方面的项目负责人和用户，开发方面的需求分析人员和项目管理者。这部分工作做得到位，能开发出很优秀的软件产品，同时也会令客户满意。若处理不好，则会导致误解、挫折、障碍以及潜在的质量和业务价值上的威胁。因此可见——需求分析奠定了软件工程和项目管理的基础。</p>
<p>    拨开需求分析的迷雾</p>
<p>    像这样的对话经常出现在软件开发的过程中。客户项目经理的需求对分析人员来讲，像“雾里看花”般模糊并令开发者感到困惑。那么，我们就拨开雾影，分析一下需求的具体内容：</p>
<p>    ·业务需求——反映了组织机构或客户对系统、产品高层次的目标要求，通常在项目定义与范围文档中予以说明。</p>
<p>    ·用户需求——描述了用户使用产品必须要完成的任务，这在使用实例或方案脚本中予以说明。</p>
<p>   [...]]]></description>
			<content:encoded><![CDATA[<p>对商业用户来说，他们后面是成百上千个供应商，前面是成千上万个消费顾客。怎样利用软件管理错综复杂的供应商和消费顾客，如何做好精细到一个小小调料包的进、销、调、存的商品流通工作，这些都是商业企业需要信息管理系统的理由。软件开发的意义也就在于此。而弄清商业用户如此复杂需求的真面目，正是软件开发成功的关键所在。</p>
<p>    经理：“我们要建立一套完整的商业管理软件系统，包括商品的进、销、调、存管理，是总部-门店的连锁经营模式。通过通信手段门店自动订货，供应商自动结算，卖场通过扫条码实现销售，管理人员能够随时查询门店商品销售和库存情况。另外，我们也得为政府部门提供关于商品营运的报告。”</p>
<p>    分析员：“我已经明白这个项目的大体结构框架，这非常重要，但在制定计划之前，我们必须收集一些需求。”</p>
<p>    经理觉得奇怪：“我不是刚告诉你我的需求了吗？”</p>
<p>    分析员：“实际上，您只说明了整个项目的概念和目标。这些高层次的业务需求不足以提供开发的内容和时间。我需要与实际将要使用系统的业务人员进行讨论，然后才能真正明白达到业务目标所需功能和用户要求，了解清楚后，才可以发现哪些是现有组件即可实现的，哪些是需要开发的，这样可节省很多时间。”<br />
<span id="more-820"></span><br />
    经理：“业务人员都在招商。他们非常忙，没有时间与你们详细讨论各种细节。你能不能说明一下你们现有的系统？”</p>
<p>    分析员尽量解释从用户处收集需求的合理性：“如果我们只是凭空猜想用户的要求，结果不会令人满意。我们只是软件开发人员，而不是采购专家、营运专家或是财务专家，我们并不真正明白您这个企业内部运营需要做些什么。我曾经尝试过，未真正明白这些问题就开始编码，结果没有人对产品满意。”</p>
<p>    经理坚持道：“行了，行了，我们没有那么多的时间。让我来告诉您我们的需求。实际上我也很忙。请马上开始开发，并随时将你们的进展情况告诉我。”</p>
<p>    风险躲在需求的迷雾之后</p>
<p>    以上我们看到的是某客户项目经理与系统开发小组的分析人员讨论业务需求。在项目开发中，所有的项目风险承担者都对需求分析阶段备感兴趣。这里所指的风险承担者包括客户方面的项目负责人和用户，开发方面的需求分析人员和项目管理者。这部分工作做得到位，能开发出很优秀的软件产品，同时也会令客户满意。若处理不好，则会导致误解、挫折、障碍以及潜在的质量和业务价值上的威胁。因此可见——需求分析奠定了软件工程和项目管理的基础。</p>
<p>    拨开需求分析的迷雾</p>
<p>    像这样的对话经常出现在软件开发的过程中。客户项目经理的需求对分析人员来讲，像“雾里看花”般模糊并令开发者感到困惑。那么，我们就拨开雾影，分析一下需求的具体内容：</p>
<p>    ·业务需求——反映了组织机构或客户对系统、产品高层次的目标要求，通常在项目定义与范围文档中予以说明。</p>
<p>    ·用户需求——描述了用户使用产品必须要完成的任务，这在使用实例或方案脚本中予以说明。</p>
<p>    ·功能需求——定义了开发人员必须实现的软件功能，使用户利用系统能够完成他们的任务，从而满足了业务需求。</p>
<p>    ·非功能性的需求——描述了系统展现给用户的行为和执行的操作等，它包括产品必须遵从的标准、规范和约束，操作界面的具体细节和构造上的限制。<br />

<!-- Begin alimama Adserver code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8438729971248494";
/* 728x90, ������ 10-2-7 */
google_ad_slot = "4752526529";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Alimama Adserver code -->
<br />
    ·需求分析报告——报告所说明的功能需求充分描述了软件系统所应具有的外部行为。“需求分析报告”在开发、测试、质量保证、项目管理以及相关项目功能中起着重要作用。</p>
<p>    前面提到的客户项目经理通常阐明产品的高层次概念和主要业务内容，为后继工作建立了一个指导性的框架。其他任何说明都应遵循“业务需求”的规定，然而“业务需求”并不能为开发人员提供开发所需的许多细节说明。</p>
<p>    下一层次需求——用户需求，必须从使用产品的用户处收集。因此，这些用户构成了另一种软件客户，他们清楚要使用该产品完成什么任务和一些非功能性的特性需求。例如：程序的易用性、健壮性和可靠性，而这些特性将会使用户很好地接受具有该特点的软件产品。</p>
<p>    经理层有时试图代替实际用户说话，但通常他们无法准确说明“用户需求”。用户需求来自产品的真正使用者，必须让实际用户参与到收集需求的过程中。如果不这样做，产品很可能会因缺乏足够的信息而遗留不少隐患。</p>
<p>    在实际需求分析过程中，以上两种客户可能都觉得没有时间与需求分析人员讨论，有时客户还希望分析人员无须讨论和编写需求说明就能说出用户的需求。除非遇到的需求极为简单；否则不能这样做。如果您的组织希望软件成功，那么必须要花上数天时间来消除需求中模糊不清的地方和一些使开发者感到困惑的方面。</p>
<p>    优秀的软件产品建立在优秀的需求基础之上，而优秀的需求源于客户与开发人员之间有效的交流和合作。只有双方参与者都明白自己需要什么、成功的合作需要什么时，才能建立起一种良好的合作关系。</p>
<p>    由于项目的压力与日俱增，所有项目风险承担者有着一个共同目标，那就是大家都想开发出一个既能实现商业价值又能满足用户要求，还能使开发者感到满足的优秀软件产品。<br />
客户的需求观</p>
<p>    客户与开发人员交流需要好的方法。下面建议20条法则，客户和开发人员可以通过评审以下内容并达成共识。如果遇到分歧，将通过协商达成对各自义务的相互理解，以便减少以后的磨擦（如一方要求而另一方不愿意或不能够满足要求）。</p>
<p>    1、 分析人员要使用符合客户语言习惯的表达</p>
<p>    需求讨论集中于业务需求和任务，因此要使用术语。客户应将有关术语（例如：采价、印花商品等采购术语）教给分析人员，而客户不一定要懂得计算机行业的术语。</p>
<p>    2、分析人员要了解客户的业务及目标</p>
<p>    只有分析人员更好地了解客户的业务，才能使产品更好地满足需要。这将有助于开发人员设计出真正满足客户需要并达到期望的优秀软件。为帮助开发和分析人员，客户可以考虑邀请他们观察自己的工作流程。如果是切换新系统，那么开发和分析人员应使用一下目前的旧系统，有利于他们明白目前系统是怎样工作的，其流程情况以及可供改进之处。s</p>
<p>    3、 分析人员必须编写软件需求报告</p>
<p>    分析人员应将从客户那里获得的所有信息进行整理，以区分业务需求及规范、功能需求、质量目标、解决方法和其他信息。通过这些分析，客户就能得到一份“需求分析报告”，此份报告使开发人员和客户之间针对要开发的产品内容达成协议。报告应以一种客户认为易于翻阅和理解的方式组织编写。客户要评审此报告，以确保报告内容准确完整地表达其需求。一份高质量的“需求分析报告”有助于开发人员开发出真正需要的产品。</p>
<p>    4、 要求得到需求工作结果的解释说明</p>
<p>    分析人员可能采用了多种图表作为文字性“需求分析报告”的补充说明，因为工作图表能很清晰地描述出系统行为的某些方面，所以报告中各种图表有着极高的价值；虽然它们不太难于理解，但是客户可能对此并不熟悉，因此客户可以要求分析人员解释说明每个图表的作用、符号的意义和需求开发工作的结果，以及怎样检查图表有无错误及不一致等。</p>
<p>    5、 开发人员要尊重客户的意见</p>
<p>    如果用户与开发人员之间不能相互理解，那关于需求的讨论将会有障碍。共同合作能使大家“兼听则明”。参与需求开发过程的客户有权要求开发人员尊重他们并珍惜他们为项目成功所付出的时间，同样，客户也应对开发人员为项目成功这一共同目标所做出的努力表示尊重。</p>
<p>    6、 开发人员要对需求及产品实施提出建议和解决方案</p>
<p>    通常客户所说的“需求”已经是一种实际可行的实施方案，分析人员应尽力从这些解决方法中了解真正的业务需求，同时还应找出已有系统与当前业务不符之处，以确保产品不会无效或低效；在彻底弄清业务领域内的事情后，分析人员就能提出相当好的改进方法，有经验且有创造力的分析人员还能提出增加一些用户没有发现的很有价值的系统特性。</p>
<p>    7、 描述产品使用特性</p>
<p>    客户可以要求分析人员在实现功能需求的同时还注意软件的易用性，因为这些易用特性或质量属性能使客户更准确、高效地完成任务。例如：客户有时要求产品要“界面友好”或“健壮”或“高效率”，但对于开发人员来讲，太主观了并无实用价值。正确的做法是，分析人员通过询问和调查了解客户所要的“友好、健壮、高效所包含的具体特性，具体分析哪些特性对哪些特性有负面影响，在性能代价和所提出解决方案的预期利益之间做出权衡，以确保做出合理的取舍。</p>
<p>    8、 允许重用已有的软件组件</p>
<p>    需求通常有一定灵活性，分析人员可能发现已有的某个软件组件与客户描述的需求很相符，在这种情况下，分析人员应提供一些修改需求的选择以便开发人员能够降低新系统的开发成本和节省时间，而不必严格按原有的需求说明开发。所以说，如果想在产品中使用一些已有的商业常用组件，而它们并不完全适合您所需的特性，这时一定程度上的需求灵活性就显得极为重要了。</p>
<p>    9、 要求对变更的代价提供真实可靠的评估</p>
<p>    有时，人们面临更好、也更昂贵的方案时，会做出不同的选择。而这时，对需求变更的影响进行评估从而对业务决策提供帮助，是十分必要的。所以，客户有权利要求开发人员通过分析给出一个真实可信的评估，包括影响、成本和得失等。开发人员不能由于不想实施变更而随意夸大评估成本。</p>
<p>    10、 获得满足客户功能和质量要求的系统</p>
<p>    每个人都希望项目成功，但这不仅要求客户要清晰地告知开发人员关于系统“做什么”所需的所有信息，而且还要求开发人员能通过交流了解清楚取舍与限制，一定要明确说明您的假设和潜在的期望，否则，开发人员开发出的产品很可能无法让您满意。</p>
<p>    11、 给分析人员讲解您的业务</p>
<p>    分析人员要依靠客户讲解业务概念及术语，但客户不能指望分析人员会成为该领域的专家，而只能让他们明白您的问题和目标；不要期望分析人员能把握客户业务的细微潜在之处，他们可能不知道那些对于客户来说理所当然的“常识”。</p>
<p>    12、 抽出时间清楚地说明并完善需求</p>
<p>    客户很忙，但无论如何客户有必要抽出时间参与“头脑高峰会议”的讨论，接受采访或其他获取需求的活动。有些分析人员可能先明白了您的观点，而过后发现还需要您的讲解，这时请耐心对待一些需求和需求的精化工作过程中的反复，因为它是人们交流中很自然的现象，何况这对软件产品的成功极为重要。</p>
<p>    13、 准确而详细地说明需求</p>
<p>    编写一份清晰、准确的需求文档是很困难的。由于处理细节问题不但烦人而且耗时，因此很容易留下模糊不清的需求。但是在开发过程中，必须解决这种模糊性和不准确性，而客户恰恰是为解决这些问题作出决定的最佳人选，否则，就只好靠开发人员去正确猜测了。</p>
<p>    在需求分析中暂时加上“待定”标志是个方法。用该标志可指明哪些是需要进一步讨论、分析或增加信息的地方，有时也可能因为某个特殊需求难以解决或没有人愿意处理它而标注上“待定”。客户要尽量将每项需求的内容都阐述清楚，以便分析人员能准确地将它们写进“软件需求报告”中去。如果客户一时不能准确表达，通常就要求用原型技术，通过原型开发，客户可以同开发人员一起反复修改，不断完善需求定义。</p>
<p>    14、 及时作出决定</p>
<p>    分析人员会要求客户作出一些选择和决定，这些决定包括来自多个用户提出的处理方法或在质量特性冲突和信息准确度中选择折衷方案等。有权作出决定的客户必须积极地对待这一切，尽快做处理，做决定，因为开发人员通常只有等客户做出决定才能行动，而这种等待会延误项目的进展。</p>
<p>    15、 尊重开发人员的需求可行性及成本评估</p>
<p>    所有的软件功能都有其成本。客户所希望的某些产品特性可能在技术上行不通，或者实现它要付出极高的代价，而某些需求试图达到在操作环境中不可能达到的性能，或试图得到一些根本得不到的数据。开发人员会对此作出负面的评价，客户应该尊重他们的意见。</p>
<p>    16、 划分需求的优先级</p>
<p>    绝大多数项目没有足够的时间或资源实现功能性的每个细节。决定哪些特性是必要的，哪些是重要的，是需求开发的主要部分，这只能由客户负责设定需求优先级，因为开发者不可能按照客户的观点决定需求优先级；开发人员将为您确定优先级提供有关每个需求的花费和风险的信息。<br />

<!-- Begin alimama Adserver code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8438729971248494";
/* 728x90, ������ 10-2-7 */
google_ad_slot = "4752526529";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Alimama Adserver code -->
<br />
    在时间和资源限制下，关于所需特性能否完成或完成多少应尊重开发人员的意见。尽管没有人愿意看到自己所希望的需求在项目中未被实现，但毕竟是要面对现实，业务决策有时不得不依据优先级来缩小项目范围或延长工期，或增加资源，或在质量上寻找折衷。</p>
<p>    17、 评审需求文档和原型</p>
<p>    客户评审需求文档，是给分析人员带来反馈信息的一个机会。如果客户认为编写的“需求分析报告”不够准确，就有必要尽早告知分析人员并为改进提供建议。</p>
<p>    更好的办法是先为产品开发一个原型。这样客户就能提供更有价值的反馈信息给开发人员，使他们更好地理解您的需求；原型并非是一个实际应用产品，但开发人员能将其转化、扩充成功能齐全的系统。<br />
 18、 需求变更要立即联系</p>
<p>    不断的需求变更，会给在预定计划内完成的质量产品带来严重的不利影响。变更是不可避免的，但在开发周期中，变更越在晚期出现，其影响越大；变更不仅会导致代价极高的返工，而且工期将被延误，特别是在大体结构已完成后又需要增加新特性时。所以，一旦客户发现需要变更需求时，请立即通知分析人员。</p>
<p>    19、 遵照开发小组处理需求变更的过程</p>
<p>    为将变更带来的负面影响减少到最低限度，所有参与者必须遵照项目变更控制过程。这要求不放弃所有提出的变更，对每项要求的变更进行分析、综合考虑，最后做出合适的决策，以确定应将哪些变更引入项目中。</p>
<p>    20、 尊重开发人员采用的需求分析过程</p>
<p>    软件开发中最具挑战性的莫过于收集需求并确定其正确性，分析人员采用的方法有其合理性。也许客户认为收集需求的过程不太划算，但请相信花在需求开发上的时间是非常有价值的；如果您理解并支持分析人员为收集、编写需求文档和确保其质量所采用的技术，那么整个过程将会更为顺利。 </p>
<p>   “需求确认”意味着什么</p>
<p>    在“需求分析报告”上签字确认，通常被认为是客户同意需求分析的标志行为，然而实际操作中，客户往往把“签字”看作是毫无意义的事情。“他们要我在需求文档的最后一行下面签名，于是我就签了，否则这些开发人员不开始编码。”</p>
<p>    这种态度将带来麻烦，譬如客户想更改需求或对产品不满时就会说：“不错，我是在需求分析报告上签了字，但我并没有时间去读完所有的内容，我是相信你们的，是你们非让我签字的。”</p>
<p>    同样问题也会发生在仅把“签字确认”看作是完成任务的分析人员身上，一旦有需求变更出现，他便指着“需求分析报告”说：“您已经在需求上签字了，所以这些就是我们所开发的，如果您想要别的什么，您应早些告诉我们。”</p>
<p>    这两种态度都是不对的。因为不可能在项目的早期就了解所有的需求，而且毫无疑问地需求将会出现变更，在“需求分析报告”上签字确认是终止需求分析过程的正确方法，所以我们必须明白签字意味着什么。</p>
<p>    对“需求分析报告”的签名是建立在一个需求协议的基线上，因此我们对签名应该这样理解：“我同意这份需求文档表述了我们对项目软件需求的了解，进一步的变更可在此基线上通过项目定义的变更过程来进行。我知道变更可能会使我们重新协商成本、资源和项目阶段任务等事宜。”对需求分析达成一定的共识会使双方易于忍受将来的摩擦，这些摩擦来源于项目的改进和需求的误差或市场和业务的新要求等。</p>
<p>    需求确认将迷雾拨散，显现需求的真面目，给初步的需求开发工作画上了双方都明确的句号，并有助于形成一个持续良好的客户与开发人员的关系，为项目的成功奠定了坚实的基础。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanjiang.net.cn/archives/820.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>高效开发与彻底测试</title>
		<link>http://www.evanjiang.net.cn/archives/712.html</link>
		<comments>http://www.evanjiang.net.cn/archives/712.html#comments</comments>
		<pubDate>Thu, 05 Mar 2009 06:14:35 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[vc++/vc#]]></category>
		<category><![CDATA[技术感悟]]></category>
		<category><![CDATA[系统架构]]></category>
		<category><![CDATA[高效开发与彻底测试]]></category>

		<guid isPermaLink="false">http://www.evanjiang.net.cn/?p=712</guid>
		<description><![CDATA[<p>一、“千般路”与“磨豆腐”</p>
<p>    很久以前听一个故事：从前有个小伙子，少时有大志，长大后却无好营生，开了个豆腐作坊，每天磨豆腐累得腰酸背疼。每到夜深人静，小伙子辗转反侧，总想找条更好的“事业之路”，可是想过千百条、尝试过几十条路，都走不通。夜不成寝，白天干活更累，小伙子不由慨叹：“晚上想过千般路，白天还得磨豆腐”。</p>
<p>    不久以前看过一篇文章：《CMM欺骗了中国的软件业》，内容是对CMM热的反思。CMM当然不会主动欺骗人民，实际上是我们的软件业自己欺骗自己。我们从来不缺少“某某模式”，“面向某某”，“某某认证”等等听起来美妙无比的东西，问题是实际的研发过程中能做得到码？现实是残酷的，美妙的概念漫天飞舞，开发过程仍然是作坊式的，正是：“晚上想过千般路，白天还得磨豆腐”。</p>
<p>    中国的故事通常都有圆满的结局，现在接着说“磨豆腐”的故事。过了很长时间，小伙子终于面对现实，不再沉迷于不切实际的空想，用心磨好豆腐，闲时琢磨些个窍门，慢慢地，他的豆腐质量越来越好，每天产量也越来越多，作坊越开越大，成了远近闻名的“豆腐老板”，后来，他做起了别的生意，发现年轻时的空想，其实很多都是可行的，因为现在“能力”和“财力”都不同。</p>
<p>    再说软件开发。我们不反对任何理论、技术、方法、模式等等，但第一，您的企业或团队做得到吗？不要做“如果开发时间延长一倍，就可以做到”之类毫无意义的假设。第二，做了真的有效益吗？效益是指扣除成本之后的收益。如果不具备这两点，那么还是不要整天想着“千般路”，首先想想如何好好的“磨豆腐”吧。</p>
<p>    对于所有软件开发来说，代码编写都是无可逃避的“磨豆腐”。改进代码编写工作，高率效低成本地开发出高质量的代码，对于软件产品能否在激烈的竞争中胜出，对于软件企业的生存和发展，都具有重要的现实意义。

    本文是Visual Unit应用的范例项目C++代码文档生成器的主题文档，叙述的正是改进代码编写工作的方法和工具，所有内容均经过实战检验，具有&#8221;可行&#8221;和&#8221;效益&#8221;两个特征，&#8221;可行&#8221;是指较低门槛或没有门槛，凭现有条件即可实施；&#8221;效益&#8221;是指能产生立竿见影的效果。</p>
<p>    本文所援引的范例项目，模拟最糟糕的开发团队，最混乱的开发流程：由很少写代码的测试和预研部门开发，人员不固定，时间也不固定，谁有空就写上一些；没有设计，没有文档，基至也不在代码文件中保存编码人员的信息，成员完全依赖于阅读代码和测试用例来理解其他成员写的代码；除了简单的命名规则外，没有其他规范，甚至连一个函数原则上不能超过50行之类的基本规范也没有（范例中有超过200行的函数CMacro::Unwind()，一万多条路径）。 任何开发团队和开发流程都会好于范例项目的开发团队和开发流程，因此，范例所展示的方法和工具，具有&#8221;广泛可行性&#8221;。</p>
<p>    本文介绍如何进行高效编码调试和实现彻底的单元测试。编码调试是任何软件开发都无可逃避的工作，在Visual Unit的支持下编码调试，只是把本来就一定要做的工作改变一下方式，不需要多做什么，就可以大幅提高编程效率和质量；另一方面，Visual Unit彻底改变了单元测试难于实施或成本昂贵的局面，无论团队中开发与测试人员的比例是怎么样的，都可以轻松快捷地实现彻底的单元测试。 </p>
<p>　
二、高效编码调试</p>
<p>    任何软件开发，都离不开编码调试。对于稍为复杂一点的函数，一般来说，编写几行代码，就要执行一下，看它们是否按预想的工作，然后再继续写，写完后还要将各种可能输入都执行一下。如何执行？一般由别的代码来调用，也就是说需要驱动，驱动通常是在开始编写函数实现代码之前建立，这样才能一边编写一边调试。驱动大致可分为自然驱动和专门驱动。</p>
<p>    自然驱动：利用项目中已有的代码作为驱动，通常是在被调试的函数中加断点，从界面执行一个需要调用该函数的功能，调试器中断时就可以调试了；专门驱动：为需要调试的函数编写专门的驱动代码，通过执行驱动代码来执行被调试函数。</p>
<p>    自然驱动的主要优点是不需要其他工作就可以直接调试，甚至感觉不到需要驱动，主要缺点是输入数据通常是公共的，即很多代码都使用相同的输入源进行调试，实际输入往往是经过其他代码处理后的中间结果，要针对各种可能输入都进行调试往往很困难，造成调试不全面，程序员的思维受到局限，难于做到全面地考虑各种可能输入。</p>
<p>    专门驱动的主要优点是输入数据是专门针对于被测试程序，容易做到比较全面，程序员的思维也会比较全面，对编写功能齐全的健壮的程序很有好处，要针对某种特定输入进行调试比较容易，缺点是需要花费大量的时间来编写驱动代码。</p>
<p>  [...]]]></description>
			<content:encoded><![CDATA[<p>一、“千般路”与“磨豆腐”</p>
<p>    很久以前听一个故事：从前有个小伙子，少时有大志，长大后却无好营生，开了个豆腐作坊，每天磨豆腐累得腰酸背疼。每到夜深人静，小伙子辗转反侧，总想找条更好的“事业之路”，可是想过千百条、尝试过几十条路，都走不通。夜不成寝，白天干活更累，小伙子不由慨叹：“晚上想过千般路，白天还得磨豆腐”。</p>
<p>    不久以前看过一篇文章：《CMM欺骗了中国的软件业》，内容是对CMM热的反思。CMM当然不会主动欺骗人民，实际上是我们的软件业自己欺骗自己。我们从来不缺少“某某模式”，“面向某某”，“某某认证”等等听起来美妙无比的东西，问题是实际的研发过程中能做得到码？现实是残酷的，美妙的概念漫天飞舞，开发过程仍然是作坊式的，正是：“晚上想过千般路，白天还得磨豆腐”。</p>
<p>    中国的故事通常都有圆满的结局，现在接着说“磨豆腐”的故事。过了很长时间，小伙子终于面对现实，不再沉迷于不切实际的空想，用心磨好豆腐，闲时琢磨些个窍门，慢慢地，他的豆腐质量越来越好，每天产量也越来越多，作坊越开越大，成了远近闻名的“豆腐老板”，后来，他做起了别的生意，发现年轻时的空想，其实很多都是可行的，因为现在“能力”和“财力”都不同。</p>
<p>    再说软件开发。我们不反对任何理论、技术、方法、模式等等，但第一，您的企业或团队做得到吗？不要做“如果开发时间延长一倍，就可以做到”之类毫无意义的假设。第二，做了真的有效益吗？效益是指扣除成本之后的收益。如果不具备这两点，那么还是不要整天想着“千般路”，首先想想如何好好的“磨豆腐”吧。</p>
<p>    对于所有软件开发来说，代码编写都是无可逃避的“磨豆腐”。改进代码编写工作，高率效低成本地开发出高质量的代码，对于软件产品能否在激烈的竞争中胜出，对于软件企业的生存和发展，都具有重要的现实意义。<br />
<span id="more-712"></span><br />
    本文是Visual Unit应用的范例项目C++代码文档生成器的主题文档，叙述的正是改进代码编写工作的方法和工具，所有内容均经过实战检验，具有&#8221;可行&#8221;和&#8221;效益&#8221;两个特征，&#8221;可行&#8221;是指较低门槛或没有门槛，凭现有条件即可实施；&#8221;效益&#8221;是指能产生立竿见影的效果。</p>
<p>    本文所援引的范例项目，模拟最糟糕的开发团队，最混乱的开发流程：由很少写代码的测试和预研部门开发，人员不固定，时间也不固定，谁有空就写上一些；没有设计，没有文档，基至也不在代码文件中保存编码人员的信息，成员完全依赖于阅读代码和测试用例来理解其他成员写的代码；除了简单的命名规则外，没有其他规范，甚至连一个函数原则上不能超过50行之类的基本规范也没有（范例中有超过200行的函数CMacro::Unwind()，一万多条路径）。 任何开发团队和开发流程都会好于范例项目的开发团队和开发流程，因此，范例所展示的方法和工具，具有&#8221;广泛可行性&#8221;。</p>
<p>    本文介绍如何进行高效编码调试和实现彻底的单元测试。编码调试是任何软件开发都无可逃避的工作，在Visual Unit的支持下编码调试，只是把本来就一定要做的工作改变一下方式，不需要多做什么，就可以大幅提高编程效率和质量；另一方面，Visual Unit彻底改变了单元测试难于实施或成本昂贵的局面，无论团队中开发与测试人员的比例是怎么样的，都可以轻松快捷地实现彻底的单元测试。 </p>
<p>　<br />
二、高效编码调试</p>
<p>    任何软件开发，都离不开编码调试。对于稍为复杂一点的函数，一般来说，编写几行代码，就要执行一下，看它们是否按预想的工作，然后再继续写，写完后还要将各种可能输入都执行一下。如何执行？一般由别的代码来调用，也就是说需要驱动，驱动通常是在开始编写函数实现代码之前建立，这样才能一边编写一边调试。驱动大致可分为自然驱动和专门驱动。</p>
<p>    自然驱动：利用项目中已有的代码作为驱动，通常是在被调试的函数中加断点，从界面执行一个需要调用该函数的功能，调试器中断时就可以调试了；专门驱动：为需要调试的函数编写专门的驱动代码，通过执行驱动代码来执行被调试函数。</p>
<p>    自然驱动的主要优点是不需要其他工作就可以直接调试，甚至感觉不到需要驱动，主要缺点是输入数据通常是公共的，即很多代码都使用相同的输入源进行调试，实际输入往往是经过其他代码处理后的中间结果，要针对各种可能输入都进行调试往往很困难，造成调试不全面，程序员的思维受到局限，难于做到全面地考虑各种可能输入。</p>
<p>    专门驱动的主要优点是输入数据是专门针对于被测试程序，容易做到比较全面，程序员的思维也会比较全面，对编写功能齐全的健壮的程序很有好处，要针对某种特定输入进行调试比较容易，缺点是需要花费大量的时间来编写驱动代码。</p>
<p>    显然，自然驱动的主要问题是不全面，代码错误较多，专门驱动的主要问题是编写驱动代码很费时。有没有更好的方法，既不需要编写驱动代码，又能方便且全面地调试？有 ！这就是自动驱动，即在Visual Unit的支持下编码调试，不但无需费时间写驱动代码，更拥有多种独特的便利，可以大幅提高编码调试的质量和效率。<br />

<!-- Begin alimama Adserver code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8438729971248494";
/* 728x90, ������ 10-2-7 */
google_ad_slot = "4752526529";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Alimama Adserver code -->
<br />
    Visual Unit是单元测试工具，但也是高效编程调试的支持环境，在Visual Unit的支持下调试，既全面又省时：<br />
    自动生成驱动代码，但又可以方便地设定调试输入；<br />
    测试用例编辑器列出全部输入，可以很方便地检查是否全面。<br />
    除了上述优点外，在Visual Unit的支持下调试，还可以：<br />
    可视化地选择调试输入；<br />
    调试过程中还可以切换输入；<br />
    无限制的后退，重复。</p>
<p>    上述仅是免费的个人版的功能，对于企业版用户，实际上大多数单步调试都可以省略：<br />
    自动输出参数、成员变量的输入输出值，返回值，用户也可以用简单的语法输出任何变量或表达式的值，这些数值都是上下文相关的；<br />
    显示在一个用例下，程序所执行的代码，可以很方便地查看程序是否按预想的流程执行。<br />
    程序无论多复杂，无非就是执行一些代码，读写、计算一些数据，因此，上述两方面信息已完整地描述了程序行为，一眼就能看出程序干了什么，通常可以很快判断程序是否按预想的工作并找到出错原因，比单步调试要快得多。</p>
<p>    下面以实例来进一步分析三种调试方式的优缺点。这里所用的示例是范例项目中的CExFunction::ParseOneParameter()函数，这是一个很普通的函数，读者也可以随便拿其他有些复杂度的代码来比较。该函数的功能是解析C++代码中的一个参数，原形如下：<br />
PARAMETER* CExFunction::ParseOneParameter(CTokenList&#038; iList);<br />
PARAMETER 是保存一个参数对象的结构，定义如下：<br />
     struct PARAMETER</p>
<p>     {</p>
<p>     CString type; //参数类型</p>
<p>     CString name; //参数名</p>
<p>     CString defVal; //缺省值</p>
<p>     CString array; //如果参数是数组，保存[]及[]内的文字常量</p>
<p>     };</p>
<p>    参数iList是一个输入参数（范例的命名规则是用i表示输入参数），传递由C++代码中的一个参数经过词法分析转换获得的记号对象序列，例如参数int* pi，将转换为三个记号对象，分别对应于：int, *, pi。该函数将记号对象序列解析到一个PARAMETER结构的指针中，并作为返回值返回。</p>
<p>    在这个示例中，如果要进行比较全面的调试，输入至少要考虑以下可能：<br />
    普通输入，如int i；<br />
    类型中有符号，如int* pi；<br />
    类型中有多个符号，如int*&#038; pi；<br />
    模板类，如CList<int, int> list；<br />
    带缺省值，如int i=0；<br />
    数组，如int ai[10]；<br />
    类型有多个单词，如const unsigned int&#038; i；<br />
    缺少参数名，如const int；</p>
<p>    我们在编写这个函数的实现代码前，首先建立调试驱动，以例边编码边执行调试。</p>
<p>自然驱动</p>
<p>    假设界面和要调用这个函数的其他代码都已完成。在函数的入口处插入断点，以调试方式运行工程，在界面中选择要生成文档的工程目录，点击&#8221;生成文档&#8221;，程序中断时就可以调试了。这种方式相信所有程序员都很熟悉，并且很多人都会认为这种方式最省时，但实际上，这种方式只是开头省时，当你试图把各个可能输入都调试一遍，就会发现它很费时：可能输入通常分散分布于输入源中（这里的输入源是代码文件），如果要比较全面地调试，通常要整理输入源，否则几乎不可能全面地调试，也就是说，要全面地调试，仍然要费时间整理输入，并不能完全依赖自然输入；<br />
    要针对某种输入进行调试，例如要调试参数带有缺省值的情形，一般通过反复跟踪直到想要的输入出现，或者设置条件断点拦截所需要输入，反复跟踪当然费时不少，设置条件断点也是要花时间的，并且有时无法满足需要 ，很多时候，要针对特殊输入进行调试都是很大费时的；<br />
    由于是公共输入源，输入数据很难管理，尤其是条件断点更不可能无限期地保存，以后需要再次调试时可能要做很多重复工作。<br />
    如上所述，自然驱动并不省时，不过这种方式的时间消耗隐藏在调试过程中，通常不会引起重视，其实&#8221;隐藏于调试过程中&#8221;，其成本更大，因为分散了开发人员的注意力，影响思维的连续性。<br />
    自然驱动的更主要问题是不全面，开发人员常常会将思维局限于现有的输入源，导致一些可能输入根本就没有考虑到，在本例中，很可能只是试一下解析一两个文件，检查得到的结果是否正确，如果文件中没有 带数组的参数，那这种输入很可能就被忽略掉。这种不全面，导致代码功能不齐，健壮性差，后期测试和维护成本居高不下，甚至导致项目的失败，因此，这是看起来高效，实际上很低效的方式，读者可以在看完后面两种方式的介绍后，自 已尝试并对比一下，可以拿任何有一定复杂度的代码编写来对比，不局限于这里所举的例子。</p>
<p>专门驱动</p>
<p>    专门驱动离单元测试只有一步之遥了，只要在驱动代码中添加判断预期输出的语句就构成了完整的测试代码，因此，在实际工作中，采用专门驱动最好是边编码边测试，并使用测试代码作为调试驱动。下面是为函数CExFunction::ParseOneParameter ()编写的调试驱动代码：<br />
     {CExFunction* pObj = new CExFunction();</p>
<p>     CTokenList iList;</p>
<p>     CTokenReader reader;</p>
<p>     reader.ReadTokenList(iList, &#8220;int i&#8221;);</p>
<p>     PARAMETER* ret = pObj->ParseOneParameter(iList) ;</p>
<p>     ASSERT( ret->type == &#8220;int&#8221; );</p>
<p>     ASSERT( ret->name == &#8220;i&#8221; );</p>
<p>     reader.ClearTokenList(iList); </p>
<p>     delete pParam;</p>
<p>     delete pObj;}</p>
<p>    上面的代码其实是一个测试用例的完整代码，测试代码通常都是很简单的，功能无非是使被测试的代码得于执行，被测试代码通常都涉及到外部数据，如参数、成员变量、全局变量什么的，这些数据当然要设定初始值，例如，上面的测试用例是将字符串&#8221;int i&#8221;经过CTokenReader对象的ReadTokenList方法转换成CToken对象指针的列表作为参数iList的输入。</p>
<p>    在实际工作中，函数的输入输出常常不是简单的数据类型，而是某些对象甚至是对象的集合，本例中，输入的数据就是CToken对象 指针的列表。这种情况下， 一般借助现有的代码来生成数据，通常，这些&#8221;现在代码&#8221;都是存在的，因为即使不做测试，也总有代码要调用该函数的，调用代码本来就需要生成相应的数据。本例中，CTokenReader::ReadTokenList()函数就是把字符串转换为CToken对象指针的列表。</p>
<p>    只要写完了第一个测试用例的代码，更多的用例就简单了，只要拷贝并对输入输出数据进行修改就行。细心的读都可能已注意到，第一个测试用例的前后加了{}，这是为了多个测试用例可以使用相同的变量名。</p>
<p>    使用这种方法，建立测试代码通常是很快的。编写很简单的函数时不需要调试，当然也不需要测试代码。测试代码的组织也很简单：一个产品工程对应一个测试工程，一个产品类对应一个测试类，一个需要测试的产品函数对应一个测试函数。测试工程可以加一个简单的界面，以便执行指定的测试，也可以使用相应的工具如CppUnit。</p>
<p>    再回到我们的主题：调试。有了测试代码，调试就简单了，要调试某种输入，只要在相应的测试用例中加断点就行了。使用这种方式，仅就调试来说，好处也是非常明显的：<br />
    所有输入在一起列出来，调试比较全面，程序员的思维也会比较全面；<br />
    要调试指定的输入很容易，通常不需要高级断点，更不需要通过反复跟踪来捕捉需要的输入；<br />
    调试数据可以永久保存，避免了以后修改代码时的重复工作。</p>
<p>自动驱动</p>
<p>    在Visual Unit的支持下编码调试，除了兼具自然驱动和专门驱动的优点外，还能享受Visual Unit的独特殊功能带来的便利。</p>
<p>    首先我们用个人版来说明，个人版是免费的版本，并且开发商也提供免费的基本技术支持。</p>
<p>    Visual Unit具有丰富的文档，包括视频教程，这里不再叙述其基本使用方法。只要选择要测试(调试)的类和函数(如果使用企业版的IDE插件，会根据当前文档和光标位置自动选择)，VU就会生成测试代码，并弹出测试用例编译器。VU是自动生成测试代码，而不是自动生成测试用例，也就是说，输入输出数据是由用户指定的，不过VU已经生成了输入输出数据的声明。下面是本例中VU生成的第一个测试用例的输入输出：</p>
<p>输入部分：<br />
CTokenList iList = </p>
<p>输出部分：<br />
ret ==</p>
<p>    这里的“=”和“==”仅仅表示可能需要赋值或判断输出，对于基本数据类型，可以直接填写数值，高级数据类型需要灵活处理(详细信息请查看帮助或教程)。只要把输入输出改为这样就完成了第一个测试用例的建立：</p>
<p>输入部分：<br />
     CTokenList iList = //多余的=会自动删除</p>
<p>     CTokenReader reader</p>
<p>     reader.ReadTokenList(iList, &#8220;int i&#8221;)</p>
<p>输出部分：<br />
     ret->type == &#8220;int&#8221;</p>
<p>     ret->name == &#8220;i&#8221;</p>
<p>    更多的测试用例，只要点击&#8221;新建&#8221;，就会自动拷贝当前用例，只要修改输入输出就行了。这里没有涉及到成员变量和变局全量，不过都很简单的(成员变量用点操作符访问，全局变量直接访问)，请查看帮助。</p>
<p>    可以看出，使用VU建立调试支持环境是很快速的：对于第一个测试用例，输入输出比较复杂时需要写少量简单的代码，输入输出简单时直接填写输入输出数值，其他测试用例只需点击一个按钮拷贝现有测试用例并修改输入输出就行，可以选择相近的用例来生成新的用例，这样通常只需要修改一两个数据就可以得到想要的用例。</p>
<p>    那么，还可以得到哪些好处呢？<br />
    方便地进入调式：在被调试函数的入口加断点，并调试测试工程即可进入调试；<br />
    方便地选择输入：在测试用例编辑器中轻点鼠标即可指定要调试的输入，如果执行了测试，只要点击出错的测试，就会自动选择相应的输入；<br />
    方便地切换输入：调试过程中，不需要退出调试，就可以切换到其他输入：只要在测试用例编辑器中选择另一个测试用例，用调试器的&#8221;执行到光标所在行&#8221;命令回到函数入口，即可切换到新的输入；<br />
    无限制后退重复：用调试器的&#8221;执行到光标所在行&#8221;命令可以自由地后退和重复执行，其实现的原理是&#8221;重来&#8221;，后退时相关数据也会&#8221;还原&#8221;，感觉上是真正的&#8221;后退&#8221;，这个奇特而有用的功能是VU生成的测试代码自动实现的。</p>
<p>    上述是免费的个人版所具有功能，VU企业版除了具有这些功能外，还具有&#8221;描述程序行为&#8221;的功能：<br />
    自动输出参数、成员变量的输入输出值，返回值，用户也可以用简单的语法输出任何变量或表达式的值。这些数值都是上下文相关的，也就是说，同一个用例的相关值放在一起；<br />
    显示在任一个用例下程序所执行的代码，可以很方便地查看程序是否按预想的流程执行。<br />
    程序无论多复杂，无非就是执行一些代码，读写、计算一些数据，因此，上述两方面信息已完整地描述了程序行为，很容易看出&#8221;程序干了什么&#8221;。这个功能大幅度地提高了开发人员的工作效率：<br />
    帮助整理、验证编程思路：写几行代码，就可以看看&#8221;程序干了什么&#8221;，轻松判断&#8221;现在所写的对不对&#8221;，也比较容易想清楚&#8221;接下来要怎么写&#8221;。<br />
    快速找出程序错误：根据输入输出数据和所执行的代码，通常可以很快判断程序是否按预期工作并找到出错原因，比单步调试要快得多。<br />
    编程的时间消耗主要不在于敲键盘，而在于编程思路和调试，VU企业版可谓&#8221;对症下药&#8221;，在这两方面大量提高工作效率。</p>
<p>    以上所述，都是针对软件开发过程中无可逃避的工作：编码调试。仅从时间上来说，对于编写调试有一定复杂度的程序，使用专门驱动，可能比自然驱动多费一点时间，但也是完全合算的，至于自动驱动，如果使用VU个人版，大概能省时10%，如果使用企业版，则可以省时20-50%!读者可以自行尝试比较一下。是否省时还不是最重要的，更高的价值在于：使用专门驱动或自动驱动编码调试，实际上也已经把令人望而生畏的单元测试工作完成了一半，并清除了实施单元测试的最主要障碍。</p>
<p>　<br />
三、实现彻底单元测试</p>
<p>    是什么使单元测试难于实施？首先是代码的可测性。可测性是什么？如果一个类具有基本的可测性，那么把它加入到另一个工程后（当然有关联的文件也要加入）能够通过编译，这其实是很低的要求，但对于一个有一定规模的项目，如果开发调试时使用自然驱动，在完成编码后才进行单元测试，那么通常都不具有可测性，因为开发人员常常在无意之中使代码之间产生了不当耦合，这些不当耦合累积起来，会使整个项目的代码纠缠在一起，造成难于测试。</p>
<p>    使单元测试难于实施的另一个方面是建立测试用例。在本例中，如果由不熟悉代码的测试人员建立测试用例，那么他很可能不知道如何生成CToken对象 指针的列表。</p>
<p>    如果边开发边使用专门驱动(测试代码放在另一个工程中)或自动驱动调试，那么一旦出现影响可测性的不当耦合就会及时发现及时解决，保证了代码的可测性，另一方面，由于至少建立了一个测试用例，测试人员建立其他用例时只要修改一下输入输出数据，从而大大降低建立测试用例的难度。总之，使用专门驱动或自动驱动调试，在不增加开发工作量的同时，已经为单元测试打一下了坚实的基础。</p>
<p>    范例项目V0.1处于这样一个阶段：刚刚完成代码编写，并未完成单元测试，现有的多数测试用例都是编码时用于调试的。在此基础上，单元测试由谁做，难度都不大。VU的典型应用是通过三个 阶段来完成针对一个函数的彻底的测试：<br />
    1）基本功能测试：测试代码的基本功能；<br />
    2）完成白盒覆盖：在现有用例的基础上，使用测试用例设计器为未覆盖的语句、条件、分支、路径设计测试用例，达到100%语句、条件、分支、路径覆盖；<br />
    3）执行自动边界测试捕捉意料之外的错误。<br />
    以上三阶段可以由不同人员在不同时间完成，团队可以根据实际情况做出灵活安排，下面是一个典型的开发测试流程。<br />

<!-- Begin alimama Adserver code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8438729971248494";
/* 728x90, ������ 10-2-7 */
google_ad_slot = "4752526529";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Alimama Adserver code -->
<br />
    1）开发人员边开发边使用VU调试测试，完成基本功能测试。在VU的支持下开发调试，可以大幅提高开发效率，绝不会影响开发进度。也许读者会认为，开发人员没有时间去设计测试用例，其实这是一种误解，开发人员写代码时肯定要想清楚代码的功能并且要使用基本的输入进行调试，这些就是基本的测试用例，实际上不需要多做什么。开发人员提交代码同时提交测试代码和测试报告。如果项目已完成或部分完成编码，也建议先由程序员首先对重要代码进行基本的功能测试。<br />
    2）测试人员检查基本测试用例是否符合设计，并在此基础上完成白盒覆盖和边界测试。由于有了初步的测试，保证了代码可测性，不可能产生因为不当耦合造成难于测试的状况；在现有用例的基础上，使用测试用例设计器找出遗漏用例也不会有太大障碍，这就使测试人员的工作易于进行。测试人员只需要提交更新过的测试代码和测试报告，不需要另外记录测出的问题。<br />
    3）开发人员下载新的测试代码和测试报告，执行整体测试，然后针对报告了错误的函数执行函数测试以获取详细信息，必要时进行调试，找出错误，修改代码，使所有测试通过，再次提交产品代码和测试报告。<br />
    4）测试人员再次执行整体测试，验证所有的测试均已通过。</p>
<p>    以上流程是动态和反复的，并不是编码完成后再单元测试。开发人员写完一个类后即可提交代码由测试人员完成白盒覆盖和边界测试。另外，团队可以根据开发与测试人员的比例调整工作份额，如果团队没有测试人员，那么由开发人员完成全部单元测试也是可行的。</p>
<p>    彻底的单元测试对于软件开发来说，其价值是难于估量的：除了保证局部代码的质量外，有了单元测试，任何时候修改代码后都可以通过回归测试来自动检查修改是否引入错误，这就使开发过程可以适应频繁变化的需求，系统分析、概要设计和详细设计都可以做得简单一些，也更能适应螺旋式开发过程，以后的维护升级成本也会大幅降低，同时，高质量的代码使集成测试和系统测试的工作量降低很多(实际上单元测试已包含了大部分的集成测试)，发现问题后的修改也会高效得多。总之，要提高软件开发质量、降低软件开发成本，最有效的改进就是进行彻底的单元测试，如果不进行单元测试，任何流程改进都无法保证产品质量，因为，程序始终是由代码构成的，代码的质量没有保证，软件的质量拿什么来保证？单元测试并不排斥其他过程改进，相反，单元测试对开发流程中的所有环节几乎都有促进作用。</p>
<p>    下边再谈谈关于白盒覆盖的话题。使用VU实施单元测试，100%的语句、条件、分支覆盖通常都是很容易的，路径覆盖有时候会很难，例如，我们所举的例了，CExFunction::ParseOneParameter ()，有九十多条路径，要覆盖似乎不现实或没必要，这种状况通常是设计不合理造成的，例如，CExFunction::ParseOneParameter ()函数的代码分为三块：1、解析缺省值，2、解析数组，3、解析类型和参数名，前两块解析了缺省值和数组后把相应的Token从列表中删除，这样的话，第3块与前两块是没有逻辑关系的，但是，这3块代码会组合出很多路径，没有逻辑关系的代码所组合出来的路径是没有意义的，这些代码具有&#8221;高耦合低内聚&#8221;的特征，不应该放在一个函数中。范例中另外写了一个函数：CExFunction::ParseOneParameter2()，把以上三块代码分别独立出来自成一个函数，这样 每个函数都能完成100%的路径覆盖，重构后的代码既易于测试，也易于维护。范例中有大量类似的函数，甚至有超过200行的函数，这是为了检验VU的适应能力，以后的版本是会进行重构。我们建议程序员完成编码后，检查一下路径数量，如果路径很多，代码很可能需要分拆，合理的路径数量应该是等价类数量的一至两倍。另外，从逻辑结构图也可以看出来：图中有两个或两个以上串联的复杂分支结构，往往表示代码的结构有问题。</p>
<p>    VU的逻辑结构图具有屏蔽对象的功能，因此，遇到上述情形时可以通过交替屏蔽部分分支结构的方式来实现路径覆盖，但这不是我们推荐的方式，因为它虽然可以保证测试的完整性，但并没有改进代码的结构。</p>
<p>    关于单元测试和范例项目，还有很多值得叙述的话题，例如内存泄漏测试以及一些复杂问题的处理等等，这里暂且不谈。最后谈谈已完成编码的项目的单元测试。对于已完成编码的项目，最好先由开发人员&#8221;去耦合&#8221;，方法是将代码文件从底层向上排列，按顺序依次将文件加入到另一个工程并编译，如果产生编译错误，则想办法消除编译错误 ，VU提供了文件排序工具，具体的使用方法请查阅帮助中《测试旧工程》部分。 完成“去耦合”后，由开发人员对自己编写的代码完成基本功能测试，测试人员完成白盒覆盖和边界测试。对于编码过程中使用自然驱动调试的已完成编写的代码，完全由测试部门进行单元测试通常是很难的。<br />
附：<br />
C++代码文档生成器（源代码下载）</p>
<p>    本软件的主要功能是解析C/C++代码，依据代码及注释自动生成代码文档。点击这里浏览本文档生成器依据自身代码生成的文档，文档格式为XML，需要XML解析器的支持，请允许ActiveX运行，如仍无法浏览，请下载安装微软的XML插件。</p>
<p>    这是凯乐软件测试部主持的一个开源项目，模拟最糟糕的开发团队，最混乱的开发流程，以恶劣环境下的实战检验和展示Visual Unit在软件开发和测试中的应用。此项目由很少写代码的测试和预研部门开发，人员不固定，时间也不固定，谁有空就写上一些；没有设计，没有文档，基至也不在代码文件中保存编码人员的信息，成员完全依赖于阅读代码和测试用例来理解其他成员写的代码；除了简单的命名规则外，没有其他规范，甚至连一个函数原则上不能超过50行之类的基本规范也没有（范例中有超过200行的函数CMacro::Unwind()，一万多条路径）。总之，此项目所展示的编码调试方式和单元测试方法，是任何开发团队都可以实施的。详细信息，请阅读相关文档：《高效开发与彻底测试》。</p>
<p>代码文档生成器使用说明</p>
<p>1) 不需要安装，双击启动；<br />
2) 选择要生成文档的项目目录，可以选择多个目录；<br />
3) 在编译条件输入框中添加编译条件（可选）；<br />
4) 选择文档的保存目录；<br />
5) 点击&#8221;生成&#8221;，即可生成XML文档；<br />
6) 将XSL目录下的文件拷贝到文档目录，点击index.htm即可浏览文档；<br />
7) 通过修改XSL目录下的文件可以定制显示格式或装饰页面。</p>
<p>项目源代码使用说明</p>
<p>源代码包括产品工程和测试工程:<br />
产品工程目录：/源代码/Docer/<br />
测试工程目录：/源代码/TestDocer/</p>
<p>安装Visual Unit1.3，启动VC6，将产品工程目录及Visual Unit安装目录/include/添加到搜索路径，更详细的信息请查看Visual Unit帮助《新建测试工程-VC6》。</p>
<p>产品工程可以使用VC6直接编译。</p>
<p>测试工程的编译运行：<br />
1）启动Visual Unit(个人版或企业版)，导航窗口->菜单->目录，选择产品工程和测试工程的目录；<br />
2）试一下编译测试工程，如果通不过编译，请查看帮助《编译错误》章节的说明；<br />
3）在导航窗口选择要测试的源文件，如产品工程目录下的ExFunction.cpp文件；<br />
4）在导航窗口函数列表中选择一个函数，如ParseOneParameter，编译并执行测试工程（Execute Program或Ctrl+F5），即可执行测试。<br />
5）企业版用户可以使用IDE插件，自动选择要测试的文件和函数，请查看帮助中《使用IDE插件》章节。<br />
6）要调试程序，添加断点，如在CExFunction::ParseOneParameter()入口处加断点，执行调试(Go或F5)，即可进入调试，调试前可以打开测试用例编辑器选择调试输入(测试用例)，调试过程中也可以切换用例，请参考帮助《排错&#8211;调试》。企业版用户，可以直接执行IDE插件的调试命令，无需手工断点。<br />
7）大多数代码（比较简单的除外）都是边开发边在Visual Unit的支持下调试的，不需要界面，随便选择一个函数都可以立即进入调试，也可以随便增删修改调试输入（使用测试用例编辑器）。<br />
8）目前版本仅实现了最基本功能，为了检验和展示VU的适应能力，很多代码不完善或有重构的必要，同时也有很多测试用例不完整。如果您有意扩展 本项目的功能，请在Visual Unit的支持下编码调试，即使是免费的个人版，也能大幅提高开发的效率和质量。 　<br />
　<br />
变量命名规则</p>
<p>m 成员变量<br />
g 全局变量<br />
s 静态变量<br />
p 指针<br />
i 输入参数<br />
o 输出参数</p>
<p>示例<br />
CString name; //局部变量<br />
CStrin mName; //成员变量<br />
CString iName; //输入参数<br />
CString& oName; //输出参数<br />
CString gName; //全局变量<br />
CString* pName; //局部变量，指针<br />
CString* mpName; //成员变量，指针<br />
CString* ipName; //输入参数，指针<br />
CString* opName; //输出参数，指针<br />
CString* iopName; //输入输出参数，指针</p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanjiang.net.cn/archives/712.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>系统分析员、系统架构师、项目经理的区别</title>
		<link>http://www.evanjiang.net.cn/archives/186.html</link>
		<comments>http://www.evanjiang.net.cn/archives/186.html#comments</comments>
		<pubDate>Mon, 05 Jan 2009 06:52:05 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[技术管理]]></category>
		<category><![CDATA[系统架构]]></category>
		<category><![CDATA[项目管理]]></category>
		<category><![CDATA[系统分析员 系统架构师 项目经理]]></category>

		<guid isPermaLink="false">http://www.hunttech.com.cn/wpblog/?p=186</guid>
		<description><![CDATA[<p> </p>
<p>上周从开发部转来一个刚毕业的小伙子，要我面试一下看看是否适合质量部的相关工作。交谈中，小伙子说大学里已经考过了系统分析员，于是我便问他：“系统分析员主要做什么？” 小伙子想了一会说道：“系统分析员主要就是组织、管理和规划系统”。于是我接着问道：“如果负责组织、管理、规划的话，那和项目经理的区别是什么？”小伙子想了半天，终于摇着头说：“不知道。”问这个问题倒不是为了为难小伙子，主要是希望他能够明白，书本上学来的东西必须和实践联系起来，在开发也好在质量部也好，都离不开自己的主动学习和思考，没有思考的学习只是在收集知识而已，是不能够化为己用的。在离开学校的头两年里，大部分人是无法找到自己真正的兴趣所在，我也是一样，所以刚开始无论在哪个岗位都必须主动学习和思考，包括对自己现有岗位的知识的学习，以及由于不满而对岗位之外的知识的学习（当然这是在工作之外），而不满正是思考的起点。不过，正是因为无法找到真正的兴趣所在，就需要坚守岗位，一方面也许它就是自己的兴趣所在，一方面也为了寻找真正的爱好而积蓄力量。</p>
<p></p>
<p>　　额外的话说了不少，还是回来看看，到底“系统分析员、架构师、项目经理”之间有着什么样的差别？下面按自己的理解粗略的整理了一下，也许并不全面，绿色部分代表每一个角色主要需要参与考虑的活动（注：下面所说的系统分析员混合了设计的职责）： </p>
<p align="center"></p>
<p>　　首先看一下架构师和系统分析员的区别：








　　1、系统分析员必须考虑自己所设计系统的方方面面，他是系统实现的原始作者，也对系统能否满足客户的技术要求以及产品成本是否可接受起着最直接的作用。</p>
<p>　　2、架构师一般在软件组织内仅仅是少数人，他们主要负责对产品的架构进行评估以及子系统之间的接口批准上，评估的主要方面集中在系统级的质量属性和成本上，包括：当前架构是否满足可靠性要求、系统架构的可扩展性、可重用性、性能以及基础的公共功能等等。他们必须对系统分析员设计出来的系统进行最初的把关，所以责任重大，也需要经验非常丰富的人来承担。在公司其他部门和Ivar Jacobson的交流中，Jacobson明确的指出，架构委员会不是常设组织，通常都来源于团队的系统分析员，唯一常设的职位通常只有一个主席，其他的成员必须临时来源于系统开发的一线，只有他们最了解系统开发的基本思想。</p>
<p>　　3、系统成本是架构师和系统分析员最容易忽略的事情，而这个也是他们最基本的职责之一</p>
<p> </p>
<p>接下来看看系统分析员和项目经理的差别：








　　1、一个不合理的计划往往被归咎于项目经理，但这并不是事实。计划的制定严重依赖于系统分析员所设计系统的部件完成工序，而唯一能对这个作出准确判断的只有系统分析员。所以，计划的最初版本是来源于系统分析员而不是项目经理。项目经理在这方面的主要作用是协助系统分析员制定计划，帮助考虑人员、资源方面的投入情况，并在项目的执行过程中严格监控项目的进度情况。</p>
<p>　　2、质量目标的制定和计划一样，来源于系统分析员，尤其是性能、可靠性等关键技术指标，而这些的第一跟踪主体也是系统分析员。项目经理在其中的角色，只是协助系统分析员安排各种资源，完成这些目标的测试、跟踪等活动。</p>
<p>　　3、成本是唯一的需要架构师、系统分析员以及项目经理共同关注并且严格控制的因素，原因很简单，这是大家靠着吃饭的来源。</p>
<p>　　4、项目其他的非技术方面的因素，则基本都是由项目经理负责搞定，包括合同、人员沟通、采购等等。</p>
]]></description>
			<content:encoded><![CDATA[<p> </p>
<p>上周从<a onclick="javascript:tagshow(event, '%BF%AA%B7%A2');" href="javascript:;" target="_self"><span style="text-decoration: underline;"><strong>开发</strong></span></a>部转来一个刚毕业的小伙子，要我<a onclick="javascript:tagshow(event, '%C3%E6%CA%D4');" href="javascript:;" target="_self"><span style="text-decoration: underline;"><strong>面试</strong></span></a>一下看看是否适合<a onclick="javascript:tagshow(event, '%D6%CA%C1%BF');" href="javascript:;" target="_self"><span style="text-decoration: underline;"><strong>质量</strong></span></a>部的相关工作。交谈中，小伙子说大学里已经考过了<a onclick="javascript:tagshow(event, '%CF%B5%CD%B3%B7%D6%CE%F6%D4%B1');" href="javascript:;" target="_self"><span style="text-decoration: underline;"><strong>系统分析员</strong></span></a>，于是我便问他：“系统分析员主要做什么？” 小伙子想了一会说道：“系统分析员主要就是组织、<a onclick="javascript:tagshow(event, '%B9%DC%C0%ED');" href="javascript:;" target="_self"><span style="text-decoration: underline;"><strong>管理</strong></span></a>和<a onclick="javascript:tagshow(event, '%B9%E6%BB%AE');" href="javascript:;" target="_self"><span style="text-decoration: underline;"><strong>规划</strong></span></a>系统”。于是我接着问道：“如果负责组织、管理、规划的话，那和<a onclick="javascript:tagshow(event, '%CF%EE%C4%BF%BE%AD%C0%ED');" href="javascript:;" target="_self"><span style="text-decoration: underline;"><strong></strong></span></a><span style="text-decoration: underline;"><strong><a onclick="javascript:tagshow(event, '%CF%EE%C4%BF');" href="javascript:;" target="_self"><span style="text-decoration: underline;"><strong>项目</strong></span></a>经理</strong></span>的区别是什么？”小伙子想了半天，终于摇着头说：“不知道。”问这个问题倒不是为了为难小伙子，主要是希望他能够明白，书本上学来的东西必须和实践联系起来，在开发也好在质量部也好，都离不开自己的主动<a onclick="javascript:tagshow(event, '%D1%A7%CF%B0');" href="javascript:;" target="_self"><span style="text-decoration: underline;"><strong>学习</strong></span></a>和<a onclick="javascript:tagshow(event, '%CB%BC%BF%BC');" href="javascript:;" target="_self"><span style="text-decoration: underline;"><strong>思考</strong></span></a>，没有思考的学习只是在收集知识而已，是不能够化为己用的。在离开学校的头两年里，大部分人是无法找到自己真正的兴趣所在，我也是一样，所以刚开始无论在哪个岗位都必须主动学习和思考，包括对自己现有岗位的知识的学习，以及由于不满而对岗位之外的知识的学习（当然这是在工作之外），而不满正是思考的起点。不过，正是因为无法找到真正的兴趣所在，就需要坚守岗位，一方面也许它就是自己的兴趣所在，一方面也为了寻找真正的爱好而积蓄力量。</p>
<p><span id="more-186"></span></p>
<p>　　额外的话说了不少，还是回来看看，到底“系统分析员、<a onclick="javascript:tagshow(event, '%BC%DC%B9%B9');" href="javascript:;" target="_self"><span style="text-decoration: underline;"><strong>架构</strong></span></a>师、项目经理”之间有着什么样的差别？下面按自己的理解粗略的整理了一下，也许并不全面，绿色部分代表每一个角色主要需要参与考虑的活动（注：下面所说的系统分析员混合了<a onclick="javascript:tagshow(event, '%C9%E8%BC%C6');" href="javascript:;" target="_self"><span style="text-decoration: underline;"><strong>设计</strong></span></a>的职责）： </p>
<p align="center"><img title="点击图片可在新窗口打开" src="http://image.it168.com/cms/2006-11-20/image/061120927.gif" alt="" width="452" height="325" /></p>
<p>　　<strong>首先看一下架构师和系统分析员的区别：</strong><br />

<!-- Begin alimama Adserver code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8438729971248494";
/* 728x90, ������ 10-2-7 */
google_ad_slot = "4752526529";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Alimama Adserver code -->
<br />
　　1、系统分析员必须考虑自己所设计系统的方方面面，他是系统实现的原始作者，也对系统能否满足<a onclick="javascript:tagshow(event, '%BF%CD%BB%A7');" href="javascript:;" target="_self"><span style="text-decoration: underline;"><strong>客户</strong></span></a>的<a onclick="javascript:tagshow(event, '%BC%BC%CA%F5');" href="javascript:;" target="_self"><span style="text-decoration: underline;"><strong>技术</strong></span></a>要求以及产品成本是否可接受起着最直接的作用。</p>
<p>　　2、架构师一般在<a onclick="javascript:tagshow(event, '%C8%ED%BC%FE');" href="javascript:;" target="_self"><span style="text-decoration: underline;"><strong>软件</strong></span></a>组织内仅仅是少数人，他们主要负责对产品的架构进行评估以及子系统之间的接口批准上，评估的主要方面集中在系统级的质量属性和成本上，包括：当前架构是否满足可靠性要求、系统架构的可扩展性、可重用性、性能以及基础的公共功能等等。他们必须对系统分析员设计出来的系统进行最初的把关，所以责任重大，也需要经验非常丰富的人来承担。在公司其他部门和Ivar Jacobson的交流中，Jacobson明确的指出，架构委员会不是常设组织，通常都来源于<a onclick="javascript:tagshow(event, '%CD%C5%B6%D3');" href="javascript:;" target="_self"><span style="text-decoration: underline;"><strong>团队</strong></span></a>的系统分析员，唯一常设的职位通常只有一个主席，其他的<a onclick="javascript:tagshow(event, '%B3%C9%D4%B1');" href="javascript:;" target="_self"><span style="text-decoration: underline;"><strong>成员</strong></span></a>必须临时来源于系统开发的一线，只有他们最了解系统开发的基本思想。</p>
<p>　　3、系统成本是架构师和系统分析员最容易忽略的事情，而这个也是他们最基本的职责之一</p>
<p> </p>
<p><strong>接下来看看系统分析员和项目经理的差别：</strong><br />

<!-- Begin alimama Adserver code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8438729971248494";
/* 728x90, ������ 10-2-7 */
google_ad_slot = "4752526529";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Alimama Adserver code -->
<br />
　　1、一个不合理的计划往往被归咎于项目经理，但这并不是事实。计划的制定严重依赖于系统分析员所设计系统的部件完成工序，而唯一能对这个作出准确判断的只有系统分析员。所以，计划的最初版本是来源于系统分析员而不是项目经理。项目经理在这方面的主要作用是协助系统分析员制定计划，帮助考虑人员、<a onclick="javascript:tagshow(event, '%D7%CA%D4%B4');" href="javascript:;" target="_self"><span style="text-decoration: underline;"><strong>资源</strong></span></a>方面的投入情况，并在项目的执行过程中严格监控项目的进度情况。</p>
<p>　　2、质量目标的制定和计划一样，来源于系统分析员，尤其是性能、可靠性等关键技术指标，而这些的第一跟踪主体也是系统分析员。项目经理在其中的角色，只是协助系统分析员安排各种资源，完成这些目标的测试、跟踪等活动。</p>
<p>　　3、成本是唯一的需要架构师、系统分析员以及项目经理共同关注并且严格控制的因素，原因很简单，这是大家靠着吃饭的来源。</p>
<p>　　4、项目其他的非技术方面的因素，则基本都是由项目经理负责搞定，包括合同、人员<a onclick="javascript:tagshow(event, '%B9%B5%CD%A8');" href="javascript:;" target="_self"><span style="text-decoration: underline;"><strong>沟通</strong></span></a>、采购等等。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanjiang.net.cn/archives/186.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
