宏基电脑 怎样解除C 盘的sftp 权限属性,今天属性安全

您所在位置: &
&nbsp&&nbsp&nbsp&&nbsp
00051管理系统中计算机应用最近三真题及答案要点分析.doc 91页
本文档一共被下载:
次 ,您可全文免费在线阅读后下载本文档。
下载提示
1.本站不保证该用户上传的文档完整性,不预览、不比对内容而直接下载产生的反悔问题本站不予受理。
2.该文档所得收入(下载+内容+预览三)归上传者、原创者。
3.登录后可充值,立即自动返金币,充值渠道很便利
需要金币:300 &&
你可能关注的文档:
··········
··········
全国2009年1月高等教育自学考试管理系统中计算机应用试题
一、单项选择题(本大题共30题,每小题1分,共30分)
在每小题列出的四个备选项中只有—个是最符合题目要求的,请将其代码填写在题后的括号内。错选、多选或未选均无分。
1.MRPII中,完成建立、组织和维护企业的基本数据(如:产品结构、制造工艺、设备等)
功能的子系统是(
A.工厂维护子系统B.技术和生产数据管理子系统C.采购及进货子系统
D.订货服务子系统
2.在信息时代,企业将一些不具备竞争优势或效率相对低下的业务内容外包并虚拟化的改
革创新行为称为(
A.业务流程重组B.供应链管理C.虚拟企业 D.电子商务
3.信息商品如计算机软件、电子读物等可直接通过网络传送。这一 (
A.网上广告宣传B.网上产品订购C.意见征询 D.服务传递
4.下列不属于企业信息化应用领域的是(
A.CAMB.CAI
C.CAD D.Intranet
5.微型计算机又称为(
A.个人机B.工作站C.小型机 D.大型机
6.微型计算机系统中,各种数据和命令传输的公共通道称为(
A.存储器B.运算器C.操作系统 D.总线
7.下列选项中,属于系统软件的是(
A.WordB.Excel
C.DBMS D.Photoshop
8.下列通信介质中,价格最低廉,安装维护方便的是(
A.同轴电缆B.双绞线C.光缆 D.无线通信
9.关系student如题9表所示,则主码是
张小林 男 18
张小林 女 19
李斯 女 19
A.姓名B.学号C.性别 D.年龄
.下列关于系统开发的描述不正确的是(
A.系统开发的历史长,有丰富的经验可借鉴B.系统开发的成果不容许有任何错误
C.系统开发一般都需要耗费大量的人力、物力和时间资源D.系统开发的产品是无形的
11.下列不属于系统开发指导原则要点的是(
A.目的性B.整体性C.扩展性 D.环境适应性
12.结构化系统开发的主导原则是(
A.由内向外B.由简向繁C.由底向上 D.自顶向下
13.下列系统开发方式中,开发周期最短的是(
A.自行开发B.购买应用软件产品C.委托开发 D.合作开发
14.信息系统规划的主要目的不包括(
A.符合企业总的战略目标B.明确系统开发的优先顺序
C.保证部门内的信息格式正确 D.为领导对系统开发决策提供依据
15.企业信息系统的规划分为战略性规划和(
A.战术性规划B.作业性规划C.指标性规划 D.执行性规划
16.现有一部分U/C矩阵如题6表所示,则下列描述不正确的是(
) 成品库存 材料供应
库存控制 C U
A.成品库存信息是在库存控制功能中产生的B.材料供应信息是在库存控制功能中产生的
C.材料供应信息是在材料需求功能中产生的D.库存控制功能要应用材料供应信息
17.绘制数据流程图时,系统中的全系统共享的数据存储常画在(
A.任意层次数据流程图B.扩展数据流程图C.低层次数据流程图 D.顶层数据流程图
18.下列选项不属于系统分析报告内容的是(
A.系统使用说明文档B.原系统的状况和问题C.新系统的目标 D.新系统的逻辑设计
19.在E-R图中,实体之间存在的联系有(
A.1种B.2种C.3种 D.4种
20.如题20图的控制结构图表示的是
A.顺序结构B.选择结构
C.循环结构D.调用结构
21.一个菜单项的任务是连接文件名为“表单1”的表单。在菜单设计器的结果列的命令栏中应输入(
A.LINK表单1B.DO FORM表单lC.DO FROM表单1 D.REPEAT TO表单1
22.在运行自己的菜单系统前,需要隐含Visual FoxPro系统菜单,其命令是(
A.HIDE THIS.MENUB.SET MEU TO
C.CLOSE SYSTEM MENU D.SET SYSMENU TO
23.在Visual FoxPro中,为了屏蔽表单的标题栏,需要将某属性设置为关闭,该属性是(
A.ButtonsB.Caption
C.ContrlBox
D.TitleBar
24.Visual FoxPro的表(
A.THISFORM.REFRESHB.THISFORM.RELEASE
C.THISFORM
正在加载中,请稍后...&什么是软件架构
前言:软体设计师中有一些技术水平较高、经验较为丰富的人,他们需要承担软件系统的架构设计,也就是需要设计系统的元件如何划分、元件之间如何发生相互作用,以及系统中逻辑的、物理的、系统的重要决定的作出。在很多公司中,架构师不是一个专门的和正式的职务。通常在一个开发小组中,最有经验的程序员会负责一些架构方面的工作。在一个部门中,最有经验的项目经理会负责一些架构方面的工作。但是,越来越多的公司体认到架构工作的重要性。
  什么是软件系统的架构(Architecture)?一般而言,架构有两个要素:
  &它是一个软件系统从整体到部分的最高层次的划分。
  一个系统通常是由元件组成的,而这些元件如何形成、相互之间如何发生作用,则是关于这个系统本身结构的重要信息。
  详细地说,就是要包括架构元件(Architecture Component)、联结器(Connector)、任务流(Task-flow)。所谓架构元素,也就是组成系统的核心"砖瓦",而联结器则描述这些元件之间通讯的路径、通讯的机制、通讯的预期结果,任务流则描述系统如何使用这些元件和联结器完成某一项需求。
  &建造一个系统所作出的最高层次的、以后难以更改的,商业的和技术的决定。
  在建造一个系统之前会有很多的重要决定需要事先作出,而一旦系统开始进行详细设计甚至建造,这些决定就很难更改甚至无法更改。显然,这样的决定必定是有关系统设计成败的最重要决定,必须经过非常慎重的研究和考察。
  计算机软件的历史开始于五十年代,历史非常短暂,而相比之下建筑工程则从石器时代就开始了,人类在几千年的建筑设计实践中积累了大量的经验和教训。建筑设计基本上包含两点,一是建筑风格,二是建筑模式。独特的建筑风格和恰当选择的建筑模式,可以使一个独一无二。
  下面的照片显示了中美洲古代玛雅建筑,Chichen-Itza大金字塔,九个巨大的石级堆垒而上,九十一级台阶(象征着四季的天数)夺路而出,塔顶的神殿耸入云天。所有的数字都如日历般严谨,风格雄浑。难以想象这是石器时代的建筑物。
图1、位于墨西哥Chichen-Itza(在玛雅语中chi意为嘴chen意为井)的古玛雅建筑。(摄影:作者)
  软件与人类的关系是架构师必须面对的核心问题,也是自从软件进入历史舞台之后就出现的问题。与此类似地,自从有了建筑以来,建筑与人类的关系就一直是建筑设计师必须面对的核心问题。英国首相丘吉尔说,我们构造建筑物,然后建筑物构造我们(We shape our buildings, and afterwards our buildings shape us)。英国下议院的会议厅较狭窄,无法使所有的下议院议员面向同一个方向入座,而必须分成两侧入座。丘吉尔认为,议员们入座的时候自然会选择与自己政见相同的人同时入座,而这就是英国政党制的起源。Party这个词的原意就是"方"、"面"。政党起源的关键就是建筑物对人的影响。
  在软件设计界曾经有很多人认为功能是最为重要的,形式必须服从功能。与此类似地,在建筑学界,现代主义建筑流派的开创人之一Louis Sullivan也认为形式应当服从于功能(Forms follows function)。
  几乎所有的软件设计理念都可以在浩如烟海的建筑学历史中找到更为遥远的历史回响。最为著名的,当然就是模式理论和XP理论。
  架构的目标是什么
  正如同软件本身有其要达到的目标一样,架构设计要达到的目标是什么呢?一般而言,软件架构设计要达到如下的目标:
  &可靠性(Reliable)。软件系统对于用户的商业经营和管理来说极为重要,因此软件系统必须非常可靠。
  &安全行(Secure)。软件系统所承担的交易的商业价值极高,系统的安全性非常重要。
  &可扩展性(Scalable)。软件必须能够在用户的使用率、用户的数目增加很快的情况下,保持合理的性能。只有这样,才能适应用户的市场扩展得可能性。
  &可定制化(Customizable)。同样的一套软件,可以根据客户群的不同和市场需求的变化进行调整。
  &可扩展性(Extensible)。在新技术出现的时候,一个软件系统应当允许导入新技术,从而对现有系统进行功能和性能的扩展
  &可维护性(Maintainable)。软件系统的维护包括两方面,一是排除现有的错误,二是将新的软件需求反映到现有系统中去。一个易于维护的系统可以有效地降低技术支持的花费
  &客户体验(Customer Experience)。软件系统必须易于使用。
  &市场时机(Time to Market)。软件用户要面临同业竞争,软件提供商也要面临同业竞争。以最快的速度争夺市场先机非常重要。
  架构的种类
  根据我们关注的角度不同,可以将架构分成三种:
  &逻辑架构、软件系统中元件之间的关系,比如用户界面,数据库,外部系统接口,商业逻辑元件,等等。
  比如下面就是笔者亲身经历过的一个软件系统的逻辑架构图
图2、一个逻辑架构的例子
  从上面这张图中可以看出,此系统被划分成三个逻辑层次,即表象层次,商业层次和数据持久层次。每一个层次都含有多个逻辑元件。比如WEB服务器层次中有HTML服务元件、Session服务元件、安全服务元件、系统管理元件等。
  &物理架构、软件元件是怎样放到硬件上的。
  比如下面这张物理架构图描述了一个分布于北京和上海的分布式系统的物理架构,图中所有的元件都是物理设备,包括网络分流器、代理服务器、WEB服务器、应用服务器、报表服务器、整合服务器、存储服务器、主机等等。
图3、一个物理架构的例子
  &系统架构、系统的非功能性特征,如可扩展性、可靠性、强壮性、灵活性、性能等。
  系统架构的设计要求架构师具备软件和硬件的功能和性能的过硬知识,这一工作无疑是架构设计工作中最为困难的工作。
  此外,从每一个角度上看,都可以看到架构的两要素:元件划分和设计决定。
  首先,一个软件系统中的元件首先是逻辑元件。这些逻辑元件如何放到硬件上,以及这些元件如何为整个系统的可扩展性、可靠性、强壮性、灵活性、性能等做出贡献,是非常重要的信息。
  其次,进行软件设计需要做出的决定中,必然会包括逻辑结构、物理结构,以及它们如何影响到系统的所有非功能性特征。这些决定中会有很多是一旦作出,就很难更改的。
  根据作者的经验,一个基于数据库的系统架构,有多少个数据表,就会有多少页的架构设计文档。比如一个中等的数据库应用系统通常含有一百个左右的数据表,这样的一个系统设计通常需要有一百页左右的架构设计文档。
  架构师
  软体设计师中有一些技术水平较高、经验较为丰富的人,他们需要承担软件系统的架构设计,也就是需要设计系统的元件如何划分、元件之间如何发生相互作用,以及系统中逻辑的、物理的、系统的重要决定的作出。
  这样的人就是所谓的架构师(Architect)。在很多公司中,架构师不是一个专门的和正式的职务。通常在一个开发小组中,最有经验的程序员会负责一些架构方面的工作。在一个部门中,最有经验的项目经理会负责一些架构方面的工作。
  但是,越来越多的公司体认到架构工作的重要性,并且在不同的组织层次上设置专门的架构师位置,由他们负责不同层次上的逻辑架构、物理架构、系统架构的设计、配置、维护等工作。
软件的架构设计
好的开始相当于成功一半
开始之初的架构设计决定着软件产品的生死存亡。&好的开始相当于成功一半&。
开始的架构设计也是最难的,需要调研同类产品的情况以及技术特征,了解当前世界上对这种产品所能提供的理论支持和技术平台支持。再结合自己项目的特点(需要透彻的系统分析),才能逐步形成自己项目的架构蓝图。
比如要开发网站引擎系统,就从Yahoo的个人主页生成工具到虚拟主机商提供的网站自动生成系统,以及IBM Webphere Portal的特点和局限 从而从架构设计角度定立自己产品的位置。
好的设计肯定需要经过反复修改,从简单到复杂的循环测试是保证设计正确的一个好办法
由于在开始选择了正确的方向,后来项目的实现过程也验证了这种选择,但在一些架构设计的细部方面,还需要对方案进行修改,属于那种螺旋上升的方式,显然这是通过测试第一的思想和XP工程方法来实现的。
如果我们开始的架构设计在技术平台定位具有一定的世界先进水平,那么,项目开发实际有一半相当于做实验,是研发,存在相当的技术风险。
因此,一开始我们不可能将每个需求都实现,而是采取一种简单完成架构流程的办法,使用最简单的需求将整个架构都简单的完成一遍(加入人工干预),以检验各个技术环节是否能协调配合工作(非常优秀先进的两种技术有时无法在一起工作),同时也可以探知技术的深浅,掌握项目中的技术难易点。这个过程完成后,我们就对设计方案做出上面的重大修改,丰富完善了设计方案。
设计模式是支撑架构的重要组件
架构设计也类似一种工作流,它是动态的,这点不象建筑设计那样,一开始就能完全确定,架构设计伴随着整个项目的进行过程之中,有两种具体操作保证架构设计的正确完成,那就是设计模式(静态)和工程项目方法(RUP或XP 动态的)。
设计模式是支撑架构的一种重要组件,这与建筑有很相象的地方,一个建筑物建立设计需要建筑架构设计,在具体施工中,有很多建筑方面的规则和模式。
我们从J2EE蓝图模式分类中就可以很清楚的看到J2EE这样一个框架软件的架构与设计模式的关系。
架构设计是骨架,设计模式就是肉
这样,一个比较丰富的设计方案可以交由程序员进一步完成了,载辅助以适当的工程方法,这样就可保证项目的架构设计能正确快速的完成。
时刻牢记架构设计的目标
由于架构设计是在动态中完成的,因此在把握架构设计的目标上就很重要,因此在整个项目过程中,甚至每一步我们都必须牢记我们架构设计的总体目标,可以概括下面几点:
1. 最大化的重用:这个重用包括组件重用 和设计模式使用等多个方面。
比如,我们项目中有用户注册和用户权限系统验证,这其实是个通用课题,每个项目只是有其内容和一些细微的差别,如果我们之前有这方面成功研发经验,可以直接重用,如果没有,那么我们就要进行这个子项目的研发,在研发过程中,不能仅仅看到这个项目的需求,也要以架构的概念去完成这个可以称为组件的子项目。
2. 尽可能的简单明了:我们解决问题的总方向是将复杂问题简单化,其实这也是中间件或多层体系技术的根本目标。但是在具体实施设计过程中,我们可能会将简单问题复杂化,特别是设计模式的运用上很容易范这个错误,因此如何尽可能的做到设计的简单明了是不容易的。
我认为落实到每个类的具体实现上要真正能体现系统事物的本质特征,因为事物的本质特征只有一个,你的代码越接近它,表示你的设计就是简单明了,越简单明了,你的系统就越可靠。更多情况是,一个类并不能反应事物本质,需要多个类的组合协调,那么能够正确使用合适的设计模式就称为重中之重。
我们看一个具备好的架构设计的系统代码时,基本看到的都是设计模式,宠物店(pet store)就是这样的例子。或者可以这样说,一个好的架构设计基本是由简单明了的多个设计模式完成的。
3. 最灵活的拓展性:架构设计要具备灵活性 拓展性,这样,用户可以在你的架构上进行二次开发或更加具体的开发。
要具备灵活的拓展性,就要站在理论的高度去进行架构设计,比如现在工作流概念逐步流行,因为我们具体很多实践项目中都有工作流的影子,工作流中有一个树形结构权限设定的概念就对很多领域比较通用。
树形结构是组织信息的基本形式,我们现在看到的网站或者ERP前台都是以树形菜单来组织功能的,那么我们在进行架构设计时,就可以将树形结构和功能分开设计,他们之间联系可以通过树形结构的节点link在一起,就象我们可以在圣诞树的树枝上挂各种小礼品一样,这些小礼品就是我们要实现的各种功能。
有了这个概念,通常比较难实现的用户级别权限控制也有了思路,将具体用户或组也是和树形结构的节点link在一起,这样就间接实现了用户对相应功能的权限控制,有了这样的基本设计方案的架构无疑具备很灵活的拓展性。&
如何设计架构?
11:11 来源: 作者: 网友评论&0&条 浏览次数&26
&&& 层(layer)这个概念在计算机领域是非常了不得的一个概念。计算机本身就体现了一种层的概念:系统调用层、设备驱动层、操作系统层、CPU指令集。每个层都负责自己的职责。网络同样也是层的概念,最著名的TCP/IP的七层协议。
&&& 层到了软件领域也一样好用。为什么呢?我们看看使用层技术有什么好处:
&&& ● 你使用层,但是不需要去了解层的实现细节。&&& ● 可以使用另一种技术来改变基础的层,而不会影响上面的层的应用。&&& ● 可以减少不同层之间的依赖。&&& ● 容易制定出层标准。&&& ● 底下的层可以用来建立顶上的层的多项服务。
&&& 当然,层也有弱点:
&&& ● 层不可能封装所有的功能,一旦有功能变动,势必要波及所有的层。&&& ● 效率降低。
当然,层最难的一个问题还是各个层都有些什么,以及要承担何种责任。
典型的三层结构
&&& 三层结构估计大家都很熟悉了。就是表示(presentation)层, 领域(domain)层, 以及基础架构(infrastructure)层。
&&& 表示层逻辑主要处理用户和软件的交互。现在最流行的莫过于视窗图形界面(wimp)和基于html的界面了。表示层的主要职责就是为用户提供信息,以及把用户的指令翻译。传送给业务层和基础架构层。
&&& 基础架构层逻辑包括处理和其他系统的通信,代表系统执行任务。例如数据库系统交互,和其他应用系统的交互等。大多数的信息系统,这个层的最大的逻辑就是存储持久数据。
&&& 还有一个就是领域层逻辑,有时也被叫做业务逻辑。它包括输入和存储数据的计算。验证表示层来的数据,根据表示层的指令指派一个基础架构层逻辑。
&&& 领域逻辑中,人们总是搞不清楚什么事领域逻辑,什么是其它逻辑。例如,一个销售系统中有这样一个逻辑:如果本月销售量比上个月增长10%,就要用红色标记。要实现这个功能,你可能会把逻辑放在表示层中,比较两个月的数字,如果超出10%,就标记为红色。
&&& 这样做,你就把领域逻辑放到了表示层中了。要分离这两个层,你应该现在领域层中提供一个方法,用来比较销售数字的增长。这个方法比较两个月的数字,并返回boolean类型。表示层则简单的调用该方法,如果返回true,则标记为红色。
&&& 层技术不存在说永恒的技巧。如何使用都要看具体的情况才能够决定,下面我就列出了三个例子:
&&& 例子1:一个电子商务系统。要求能够同时处理大量用户的请求,用户的范围遍及全球,而且数字还在不断增长。但是领域逻辑很简单,无非是订单的处理,以及和库存系统的连接部分。这就要求我们1、表示层要友好,能够适应最广泛的用户,因此采用html技术;2、支持分布式的处理,以胜任同时几千的访问;3、考虑未来的升级。
&&& 例子2:一个租借系统。系统的用户少的多,但是领域逻辑很复杂。这就要求我们制作一个领域逻辑非常复杂的系统,另外,还要给他们的用户提供一个方便的输入界面。这样,wimp是一个不错的选择。
&&& 例子3:简单的系统。非常简单,用户少、逻辑少。但是也不是没有问题,简单意味着要快速交付,并且还要充分考虑日后的升级。因为需求在不断的增加之中。
&&& 这样的三个例子,就要求我们不能够一概而论的解决问题,而是应该针对问题的具体情况制定具体的解决方法。这三个例子比较典型。
&&& 第二个例子中,可能需要严格的分成三个层次,而且可能还要加上另外的中介(mediating)层。例3则不需要,如果你要做的仅是查看数据,那仅需要几个server页面来放置所有的逻辑就可以了。
&&& 我一般会把表示层和领域层/基础架构层分开。除非领域层/基础架构层非常的简单,而我又可以使用工具来轻易的绑定这些层。这种两层架构的最好的例子就是在VB、PB的环境中,很容易就可以构建出一个基于SQL数据库的windows界面的系统。这样的表示层和基础架构层非常的一致,但是一旦验证和计算变得复杂起来,这种方式就存在先天缺陷了。
&&& 很多时候,领域层和基础架构层看起来非常类似,这时候,其实是可以把它们放在一起的。可是,当领域层的业务逻辑和基础架构层的组织方式开始不同的时候,你就需要分开二者。
更多的层模式
&&& 三层的架构是最为通用的,尤其是对IS系统。其它的架构也有,但是并不适用于任何情况。
&&& 第一种是Brown model [Brown et al]。它有五个层:表示层(Presentation),控制/中介层(Controller/Mediator),领域层(Domain), 数据映射层(Data Mapping), 和数据源层(Data Source)。它其实就是在三层架构种增加了两个中间层。控制/中介层位于表示层和领域层之间,数据映射层位于领域层和基础架构层之间。
&&& 表示层和领域层的中介层,我们通常称之为表示-领域中介层,是一个常用的分层方法,通常针对一些非可视的控件。例如为特定的表示层组织信息格式,在不同的窗口间导航,处理交易边界,提供Server的facade接口(具体实现原理见设计模式)。最大的危险就是,一些领域逻辑被放到这个层里,影响到其它的表示层。
&&& 我常常发现把行为分配给表示层是有好处的。这可以简化问题。但表示层模型会比较复杂,所以,把这些行为放到非可视化的对象中,并提取出一个表示-领域中介层还是值得的。
&&& Brown ISA&&& 表示层 表示层&& 控制/中介层 表示-领域中介层&&& 领域层 领域层&&& 数据映射层 数据库交互模式中的Database Mapper&&& 数据源层 基础架构层
&&& 领域层和基础架构层之间的中介层属于本书中提到的Database Mapper模式,是三种领域层到数据连接的办法之一。和表示-领域中介层一眼,有时候有用,但不是所有时候都有用。
&&& 还有一个好的分层架构是J2EE的架构,这方面的讨论可以见『J2EE核心模式』一书。他的分层是客户层(Client),表示层(Presentation),业务层(Business ),整合层(Integration),资源层(Resource)。差别如下图:
&&& J2EE核心 ISA&&& 客户层 运行在客户机上的表示层&& 表示层 运行在服务器上的表示层&&& 业务层 领域层&&& 整合层 基础架构层&&& 资源层 基础架构层通信的外部数据
&&& 微软的DNA架构定义了三个层:表示层(presentation),业务层(business),和数据存储层(data access),这和我的架构相似,但是在数据的传递方式上还有很大的不同。在微软的DNA中,各层的操作都基于数据存储层传出的SQL查询结果集。这样的话,实际上是增加了表示层和业务层同数据存储层之间的耦合度。
&&& DNA的记录集在层之间的动作类似于Data Transfer Object。&&&&
Part 2 组织领域逻辑
&&& 要组织基于层的系统,首要的是如何组织领域逻辑。领域逻辑的组织有好几种模式。但其中最重要的莫过于两种方法:Transation Script和Domain Model。选定了其中的一种,其它的都容易决定。不过,这两者之间并没有一条明显的分界线。所以如何选取也是门大学问。一般来说,我们认为领域逻辑比较复杂的系统可以采用Domain Model。
&&& Transation Script就是对表示层用户输入的处理程序。包括验证和计算,存储,调用其它系统的操作,把数据回传给表示层。用户的一个动作表示一个程序,这个程序可以是script,也可以是transation,也可以是几个子程序。在例子1中,检验,在购物车中增加一本书,显示递送状态,都可以是一个Transation Script。
&&& Domain Model是要建立对应领域名词的模型,例如例1中的书、购物车等。检验、计算等处理都放到领域模型中。
&&& Transation Script属于结构性思维,Domain Model属于OO思维。Domain Model比较难使用,一旦习惯,你能够组织更复杂的逻辑,你的思想会更OO。到时候,即使是小的系统,你也会自然的使用Domain Model了。
&&& 但如何抉择呢?如果逻辑复杂,那肯定用Domain Model:如果只需要存取数据库,那Transation Script会好一些。但是需求是在不断进化的,你很难保证以后的需求还会如此简单。如果你的团队不善于使用Domain Model,那你需要权衡一下投入产出比。另外,即使是Transation Script,也可以做到把逻辑和基础架构分开,你可以使用Gateway。
&&& 对例2,毫无疑问要使用Domain Model。对例1就需要权衡了。而对于例3,你很难说它将来会不会像例2那样,你现在可以使用Transation Script,但未来你可能要使用Domain Model。所以说,架构的决策是至关紧要的。
&&& 除了这两种模式,还有其它中庸的模式。Use Case Controller就是处于两者之间。只有和单个的用例相关的业务逻辑才放到对象中。所以大致上他们还是在使用Transation Script,而Domain Model只是Database Gateway的一组集合而已。我不太用这种模式。
&&& Table Module是另一个中庸模式。很多的GUI环境依托于SQL查询的返回结果。你可以建立内存中的对象,来把GUI和数据库分开来。为每个表写一个模块,因此每一行都需要关键字变量来识别每一个实例。
&&& Table Module适用于很多的组件构建于一个通用关系型数据库之上,而且领域逻辑不太复杂的情况。Microsoft COM 环境,以及它的带ADO.NET的.NET环境都适合使用这种模式。而对于Java,就不太适用了。
&&& 领域逻辑的一个问题是领域对象非常的臃肿。因为对象的行为太多了,类也就太大了。它必须是一个超集。这就要考虑哪些行为是通用的,哪些不是,可以由其它的类来处理,可能是Use Case Controller,也可能是表示层。
&&& 还有一个问题,复制。他会导致复杂和不一致。这比臃肿的危害更大。所以,宁可臃肿,也不要复制。等到臃肿为害时再处理它吧。
选择一个地方运行领域逻辑
&&& 我们的精力集中在逻辑层上。领域逻辑要么运行在Client上,要么运行在Server上。
&&& 比较简单的做法是全部集中在Server上。这样你需要使用html的前端以及web server。这样做的好处是升级和维护都非常的简单,你也不用考虑桌面平台和Server的同步问题,也不用考虑桌面平台的其它软件的兼容问题。
&&& 运行在Client适合于要求快速反应和没有联网的情况。在Server端的逻辑,用户的一个再小的请求,也需要信息从Client到Server绕一圈。反应的速度必然慢。再说,网络的覆盖程度也不是说达到了100%。
&&& 对于各个层来说,又是怎么样的呢?
&&& 基础架构层:一般都是在Server啦,不过有时候也会把数据复制到合适的高性能桌面机,但这是就要考虑同步的问题了。
&&& 表示层在何处运行取决于用户界面的设计。一个Windows界面只能在Client运行。而一个Web界面就是在Server运行。也有特别的例子,在桌面机上运行web server的,例如X Server。但这种情况少的多。
&&& 在例1中,没有更多的选择了,只能选在Server端。因此你的每一个bit都会绕一个大圈子。为了提高效率,尽量使用一些纯html脚本。
&&& 人们选用Windows界面的原因主要就是需要执行一些非常复杂的任务,需要一个合适的应用程序,而web GUI则无法胜任。这就是例2的做法。不过,人们应该会渐渐适应web GUI,而web GUI的功能也会越来越强大。
&&& 剩下的是领域逻辑。你可以全部放在Server,也可以全部放在Client,或是两边都放。
&&& 如果是在Client端,你可以考虑全部逻辑都放在Client端,这样至少保证所有的逻辑都在一个地方。而把web server移至Client,是可以解决没有联网的问题,但对反应时间不会有多大的帮助。你还是可以把逻辑和表示层分离开来。当然,你需要额外的升级和维护的工作。
&&& 在Client和Server端都具有逻辑并不是一个好的处理办法。但是对于那些仅有一些领域逻辑的情况是适用的。有一个小窍门,把那些和系统的其它部分没有联系的逻辑封装起来。
领域逻辑的接口
&&& 你的Server上有一些领域逻辑,要和Client通信,你应该有什么样的接口呢?要么是一个http接口,要么是一个OO接口。
&&& http接口适用于web browser,就是说你要选择一个html的表示层。最近的新技术就是web service,通过基于http、特别是XML进行通信。XML有几个好处:通信量大,结构好,仅需一次的回路。这样远程调用的的开销就小了。同时,XML还是一个标准,支持平台异构。XML又是基于文本的,能够通过防火墙。
&&& 虽然XML有那么多的好处,不过一个OO的接口还是有它的价值的。hhtp的接口不明显,不容易看清楚数据是如何处理的。而OO的接口的方法带有变量和名字,容易看出处理的过程。当然,它无法通过防火墙,但可以提供安全和事务之类的控制。
&&& 最好的还是取二者所长。OO接口在下,http接口在上。但这样做就会使得实现机制非常的复杂。
Part 3 组织web Server
&&& 很多使用html方式的人,并不能真正理解这种方式的优点。我们有各种各样好用的工具,但是却搞到让程序难以维护。
&&& 在web server上组织程序的方式大致可以分为两种:脚本和server page。
&&& 脚本方式就是一个程序,用函数和方法来处理http调用。例如CGI脚本和java servlet。它和普通的程序并没有什么两样。它从web页面上获得html string形态的数据,有时候还要做一些表达式匹配,这正是perl能够成为CGI脚本的常用语言的原因。而java servelet则是把这种分析留给程序员,但它允许程序员通过关键字接口来访问信息,这样就会少一些表达式的判断。这种格式的web server输出是另一种html string,称为response,可以通过流数据来操作。
&&& 糟糕的是流数据是非常麻烦的,因此就导致了server page的产生,例如PHP,ASP,JSP。
&&& server page的方式适合回应(response)的处理比较简单的情况。例如&显示歌曲的明细&,但是你的决策取决于输入的时候,就会比较杂乱。例如&通俗和摇滚的显示格式不同&。
&&& 脚步擅长于处理用户交互,server page擅长于处理格式化回应信息。所以很自然的就会采用脚本处理请求的交互,使用server page处理回应的格式化。这其实就是著名的MVC(Model View Controller)模式中的view/controller的处理。
web server端的MVC工作流程示意图
&&& 应用Model View Controller模式首要的一点就是模型要和web服务完全分离开来。使用Transaction Script或Domain Model模式来封装处理流程。
&&& 接下来,我们就把剩余的模式归入两类模式中:属于Controller的模式,以及属于View的模式。
&&& View这边有三种模式:Transform View,Template View和Two Step View。Transform View和Template View的处理只有一步,将领域数据转换为html。Two Step View要经过两步的处理,第一步把领域数据转换为逻辑表示形式,第二步把逻辑表示转换为html。
&&& 两步处理的好处是可以将逻辑集中于一处,如果只有一步,变化发生时,你就需要修改每一个屏幕。但这需要你有一个很好的逻辑屏幕结构。如果一个web应用有很多的前端用户时,两步处理就特别的好用。例如航空订票系统。使用不同的第二步处理,就可以获得不同的逻辑屏幕。
&&& 使用单步方法有两个可选的模式:Template View,Transform View。Template View其时就是把代码嵌入到html页面中,就像现在的server page技术,如ASP,PHP,JSP。这种模式灵活,强大,但显得杂乱无章。如果你能够把逻辑程序逻辑在页面结构之外进行很好的组织,这种模式还是有它的优点的。
&&& Transform View使用翻译方式。例如XSLT。如果你的领域数据是用XML处理的,那这种模式就特别的好用。
Controller模式
&&& Controller有两种模式。一般我们会根据动作来决定一项控制。动作可能是一个按钮或链接。所这种模式就是Action Controller模式。
&&& Front Controller更进一步,它把http请求的处理和处理逻辑分离开来。一般是只有一个web handle来处理所有的请求。你的所有的http请求的处理都由一个对象来负责。你改变动作结构的影响就会降到最小
约公元前25年,古罗马建筑师维特鲁威说:&理想的建筑师应该既是文学家又是数字家,他还应通晓历史,热衷于哲学研究,精通音乐,懂得医药知识,具有法学造诣,深谙天文学及天文计算。&(好难哪,软件构架设计师的要求呢?大家好好想想吧。)&&本文目录&&一、与构架有关的几个基本概念;&&二、构架设计应考虑的因素概揽;&&三、程序的运行时结构方面的考虑;&&四、源代码的组织结构方面的考虑;&&五、写系统构架设计文档应考虑的问题&&六、结语&&一、与构架有关的几个基本概念:& 1、模块(module):一组完成指定功能的语句,包括:输入、输出、逻辑处理功能、内部信息、运行环境(与功能对应但不是一对一关系)。&&2、组件(component):系统中相当重要的、几乎是独立的可替换部分,它在明确定义的构架环境中实现确切的功能。&&3、模式(pattern):指经过验证,至少适用于一种实用环境(更多时候是好几种环境)的解决方案模板(用于结构和行为。在&UML中:模式由参数化的协作来表示,但&UML&不直接对模式的其他方面(如使用结果列表、使用示例等,它们可由文本来表示)进行建模。存在各种范围和抽象程度的模式,例如,构架模式、分析模式、设计模式和代码模式或实施模式。模式将可以帮助我们抓住重点。构架也是存在模式的。比如,对于系统结构设计,我们使用层模式;对于分布式系统,我们使用代理模式(通过使用代理来替代实际的对象,使程序能够控制对该对象的访问);对于交互系统,我们使用MVC(M模型(对象)/V视图(输出管理)/C控制器(输入处理))模式。模式是针对特定问题的解,因此,我们也可以针对需求的特点采用相应的模式来设计构架。&&4、构架模式(architectural pattern):表示软件系统的基本结构组织方案。它提供了一组预定义的子系统、指定它们的职责,并且包括用于组织其间关系的规则和指导。&&5、层(layer):对模型中同一抽象层次上的包进行分组的一种特定方式。通过分层,从逻辑上将子系统划分成许多集合,而层间关系的形成要遵循一定的规则。通过分层,可以限制子系统间的依赖关系,使系统以更松散的方式耦合,从而更易于维护。(层是对构架的横向划分,分区是对构架的纵向划分)。&&6、系统分层的几种常用方法:&&1) 常用三层服务:用户层、业务逻辑层、数据层;&&2) 多层结构的技术组成模型:表现层、中间层、数据层;&&3) 网络系统常用三层结构:核心层、汇聚层和接入层;&&4)&RUP典型分层方法:应用层、专业业务层、中间件层、系统软件层;&&5) 基于Java的B/S模式系统结构:浏览器端、服务器端、请求接收层、请求处理层;&&6) 某六层结构:功能层(用户界面)、模块层、组装层(软件总线)、服务层(数据处理)、数据层、核心层;&&7、构架(Architecture,愿意为建筑学设计和建筑物建造的艺术与科学):&在RUP中的定义:软件系统的构架(在某一给定点)是指系统重要构件的组织或结构,这些重要构件通过接口与不断减小的构件与接口所组成的构件进行交互;《软件构架实践》中的定义:某个软件或者计算系统的软件构架即组成该系统的一个或者多个结构,他们组成软件的各个部分,形成这些组件的外部可见属性及相互间的联系;IEEE 中的定义:the fundamental organization of a system emboided in its components,their relationships to each other,and to the enviroment and the principles guiding its design and evolution,构架是系统在其所处环境中的最高层次的概念。软件系统的构架是通过接口交互的重要构件(在特定时间点)的组织或结构,这些构件又由一些更小的构件和接口组成。(&构架&可以作为名词,也可作为动词,作为动词的&构架&相当于&构架设计&)&&8、构架的描述方式:&4+1&视图(用例视图、设计视图、实现视图、过程视图、配置视图)是一个被广为使用的构架描述的模型;RUP过程的构架描述模板在&4+1&视图的基础上增加了可选的数据视图(从永久性数据存储方面来对系统进行说明);HP公司的软件描述模板也是基于&4+1&视图。&&9、结构:软件构架是多种结构的体现,结构是系统构架从不同角度观察所产生的视图。就像建筑物的结构会随着观察动机和出发点的不同而有多种含义一样,软件构架也表现为多种结构。常见的软件结构有:模块结构、逻辑或概念结构、进程或协调结构、物理结构、使用结构、调用结构、数据流、控制流、类结构等等。&&二、构架设计应考虑的因素概揽:&&模块构架设计可以从程序的运行时结构和源代码的组织结构方面考虑。&&1、程序的运行时结构方面的考虑:&&1) 需求的符合性:正确性、完整性;功能性需求、非功能性需求;&&2) 总体性能(内存管理、数据库组织和内容、非数据库信息、任务并行性、网络多人操作、关键算法、与网络、硬件和其他系统接口对性能的影响);&&3) 运行可管理性:便于控制系统运行、监视系统状态、错误处理;模块间通信的简单性;与可维护性不同;&&4) 与其他系统接口兼容性;&&5) 与网络、硬件接口兼容性及性能;&&6) 系统安全性;&&7) 系统可靠性;&&8) 业务流程的可调整性;&&9) 业务信息的可调整性&&10) 使用方便性&&11) 构架样式的一致性&&注:运行时负载均衡可以从系统性能、系统可靠性方面考虑。&&2、源代码的组织结构方面的考虑:&&1) 开发可管理性:便于人员分工(模块独立性、开发工作的负载均衡、进度安排优化、预防人员流动对开发的影响)、利于配置管理、大小的合理性与适度复杂性;&&2) 可维护性:与运行可管理性不同;&&3) 可扩充性:系统方案的升级、扩容、扩充性能;&&4) 可移植性:不同客户端、应用服务器、数据库管理系统;&&5) 需求的符合性(源代码的组织结构方面的考虑)。
三、程序的运行时结构方面的考虑:&&1、 需求的符合性:正确性、完整性;功能性需求、非功能性需求&&软件项目最主要的目标是满足客户需求。在进行构架设计的时候,大家考虑更多的是使用哪个运行平台、编成语言、开发环境、数据库管理系统等问题,对于和客户需求相关的问题考虑不足、不够系统。如果无论怎么好的构架都无法满足客户明确的某个功能性需求或非功能性需求,就应该与客户协调在项目范围和需求规格说明书中删除这一需求。否则,架构设计应以满足客户所有明确需求为最基本目标,尽量满足其隐含的需求。(客户的非功能性需求可能包括接口、系统安全性、可靠性、移植性、扩展性等等,在其他小节中细述)&&一般来说,功能需求决定业务构架、非功能需求决定技术构架,变化案例决定构架的范围。需求方面的知识告诉我们,功能需求定义了软件能够做些什么。我们需要根据业务上的需求来设计业务构架,以使得未来的软件能够满足客户的需要。非功能需求定义了一些性能、效率上的一些约束、规则。而我们的技术构架要能够满足这些约束和规则。变化案例是对未来可能发生的变化的一个估计,结合功能需求和非功能需求,我们就可以确定一个需求的范围,进而确定一个构架的范围。(此段From林星)&&这里讲一个前几年因客户某些需求错误造成构架设计问题而引起系统性能和可靠性问题的小小的例子:此系统的需求本身是比较简单的,就是将某城市的某业务的全部历史档案卡片扫描存储起来,以便可以按照姓名进行查询。需求阶段客户说卡片大约有20万张,需求调研者出于对客户的信任没有对数据的总量进行查证。由于是中小型数据量,并且今后数据不会增加,经过计算20万张卡片总体容量之后,决定使用一种可以单机使用也可以联网的中小型数据库管理系统。等到系统完成开始录入数据时,才发现数据至少有60万,这样使用那种中小型数据库管理系统不但会造成系统性能的问题,而且其可靠性是非常脆弱的,不得不对系统进行重新设计。从这个小小的教训可以看出,需求阶段不仅对客户的功能需求要调查清楚,对于一些隐含非功能需求的一些数据也应当调查清楚,并作为构架设计的依据。&&对于功能需求的正确性,在构架设计文档中可能不好验证(需要人工、费力)。对于功能需求完整性,就应当使用需求功能与对应模块对照表来跟踪追溯。对于非功能需求正确性和完整性,可以使用需求非功能与对应设计策略对照表来跟踪追溯评估。&&&软件设计工作只有基于用户需求,立足于可行的技术才有可能成功。&&&2、 总体性能&&性能其实也是客户需求的一部分,当然可能是明确的,也有很多是隐含的,这里把它单独列出来在说明一次。性能是设计方案的重要标准,性能应考虑的不是单台客户端的性能,而是应该考虑系统总的综合性能;&&性能设计应从以下几个方面考虑:内存管理、数据库组织和内容、非数据库信息、任务并行性、网络多人操作、关键算法、与网络、硬件和其他系统接口对性能的影响;几点提示:算法优化及负载均衡是性能优化的方向。经常要调用的模块要特别注意优化。占用内存较多的变量在不用时要及时清理掉。需要下载的网页主题文件过大时应当分解为若干部分,让用户先把主要部分显示出来。&&3、 运行可管理性&&系统的构架设计应当为了使系统可以预测系统故障,防患于未然。现在的系统正逐步向复杂化、大型化发展,单靠一个人或几个人来管理已显得力不从心,况且对于某些突发事件的响应,人的反应明显不够。因此通过合理的系统构架规划系统运行资源,便于控制系统运行、监视系统状态、进行有效的错误处理;为了实现上述目标,模块间通信应当尽可能简单,同时建立合理详尽的系统运行日志,系统通过自动审计运行日志,了解系统运行状态、进行有效的错误处理;(运行可管理性与可???护性不同)&&4、 与其他系统接口兼容性(解释略)&&5、 与网络、硬件接口兼容性及性能(解释略)&&6、 系统安全性&&随着计算机应用的不断深入和扩大,涉及的部门和信息也越来越多,其中有大量保密信息在网络上传输,所以对系统安全性的考虑已经成为系统设计的关键,需要从各个方面和角度加以考虑,来保证数据资料的绝对安全。&&7、 系统可靠性&&系统的可靠性是现代信息系统应具有的重要特征,由于人们日常的工作对系统依赖程度越来越多,因此系统的必须可靠。系统构架设计可考虑系统的冗余度,尽可能地避免单点故障。系统可靠性是系统在给定的时间间隔及给定的环境条件下,按设计要求,成功地运行程序的概率。成功地运行不仅要保证系统能正确地运行,满足功能需求,还要求当系统出现意外故障时能够尽快恢复正常运行,数据不受破坏。&&8、 业务流程的可调整性&&应当考虑客户业务流程可能出现的变化,所以在系统构架设计时要尽量排除业务流程的制约,即把流程中的各项业务结点工作作为独立的对象,设计成独立的模块或组件,充分考虑他们与其他各种业务对象模块或组件的接口,在流程之间通过业务对象模块的相互调用实现各种业务,这样,在业务流程发生有限的变化时(每个业务模块本身的业务逻辑没有变的情况下),就能够比较方便地修改系统程序模块或组件间的调用关系而实现新的需求。如果这种调用关系被设计成存储在配置库的数据字典里,则连程序代码都不用修改,只需修改数据字典里的模块或组件调用规则即可。&&9、 业务信息的可调整性&&应当考虑客户业务信息可能出现的变化,所以在系统构架设计时必须尽可能减少因为业务信息的调整对于代码模块的影响范围。&&10、 使用方便性&&使用方便性是不须提及的必然的需求,而使用方便性与系统构架是密切相关的。WinCE(1.0)的失败和后来改进版本的成功就说明了这个问题。WinCE(1.0)有太多层次的视窗和菜单,而用户则更喜欢简单的界面和快捷的操作。失败了应当及时纠正,但最好不要等到失败了再来纠正,这样会浪费巨大的财力物力,所以在系统构架阶段最好能将需要考虑的因素都考虑到。当然使用方便性必须与系统安全性协调平衡统一,使用方便性也必须与业务流程的可调整性和业务信息的可调整性协调平衡统一。&满足用户的需求,便于用户使用,同时又使得操作流程尽可能简单。这就是设计之本。&&&11、构架样式的一致性&&软件系统的构架样式有些类似于建筑样式(如中国式、哥特式、希腊复古式)。软件构架样式可分为数据流构架样式、调用返回构架样式、独立组件构架样式、以数据为中心的构架样式和虚拟机构架样式,每一种样式还可以分为若干子样式。构架样式的一致性并不是要求一个软件系统只能采用一种样式,就像建筑样式可以是中西结合的,软件系统也可以有异质构架样式(分为局部异质、层次异质、并行异质),即多种样式的综合,但这样的综合应该考虑其某些方面的一致性和协调性。每一种样式都有其使用的时机,应当根据系统最强调的质量属性来选择。&&&四、源代码的组织结构方面的考虑:&&1、 开发可管理性&&便于人员分工(模块独立性、开发工作的负载均衡、进度安排优化、预防人员流动对开发的影响:一个好的构架同时应有助于减少项目组的压力和紧张,提高软件开发效率)、利于配置管理、大小的合理性、适度复杂性;&&1)便于人员分工-模块独立性、层次性&&模块独立性、层次性是为了保证项目开发成员工作之间的相对独立性,模块联结方式应该是纵向而不是横向,&模块之间应该是树状结构而不是网状结构或交叉结构,这样就可以把开发人员之间的通信、模块开发制约关系减到最少。同时模块独立性也比较利于配置管理工作的进行。现在有越来越多的的软件开发是在异地进行,一个开发组的成员可能在不同城市甚至在不同国家,因此便于异地开发的人员分工与配置管理的源代码组织结构是非常必要的。&&2)便于人员分工-开发工作的负载均衡&&不仅仅是开发出来的软件系统需要负载均衡,在开发过程中开发小组各成员之间工作任务的负载均衡也是非重要的。所谓工作任务的负载均衡就是通过合理的任务划分按照开发人员特点进行分配任务,尽量让项目组中的每个人每段时间都有用武之地。这就需要在构架设计时应当充分考虑项目组手头的人力资源,在实现客户需求的基础上实现开发工作的负载均衡,以提高整体开发效率。&&3)便于人员分工-进度安排优化;&&进度安排优化的前提是模块独立性并搞清楚模块开发的先后制约关系。利用工作分解结构对所有程序编码工作进行分解,得到每一项工作的输入、输出、所需资源、持续时间、前期应完成的工作、完成后可以进行的工作。然后预估各模块需要时间,分析各模块的并行与串行(顺序制约),绘制出网络图,找出影响整体进度的关键模块,算出关键路径,最后对网络图进行调整,以使进度安排最优化。&&有个家喻户晓的智力题叫烤肉片策略:约翰逊家户外有一个可以同时烤两块肉片的烤肉架,烤每块肉片的每一面需要10分钟,现要烤三块肉片给饥肠辘辘急不可耐的一家三口。问题是怎样才能在最短的时间内烤完三片肉。一般的做法花20分钟先烤完前两片,再花20分钟烤完第三片。有一种更好的方法可以节省10分钟,大家想想。&&4)便于人员分工-预防员工人员流动对开发的影响&&人员流动在软件行业是司空见惯的事情,已经是一个常见的风险。作为对这一风险的有效的防范对策之一,可以在构架设计中考虑到并预防员工人员流动对开发的影响。主要的思路还是在模块的独立性上(追求高内聚低耦合),组件化是目前流行的趋势。&&5)利于配置管理(独立性、层次性)&&利于配置管理与利于人员分工有一定的联系。除了逻辑上的模块组件要利于人员分工外,物理上的源代码层次结构、目录结构、各模块所处源代码文件的部署也应当利于人员分工和配置管理。(尽管现在配置管理工具有较强大的功能,但一个清楚的源码分割和模块分割是非常有好处的)。&&6)大小的合理性与适度复杂性&&大小的合理性与适度复杂性可以使开发工作的负载均衡,便于进度的安排,也可以使系统在运行时减少不必要的内存资源浪费。对于代码的可阅读性和系统的可维护性也有一定的好处。另外,过大的模块常常是系统分解不充分,而过小的模块有可能降低模块的独立性,造成系统接口的复杂。&&2、 可维护性&&便于在系统出现故障时及时方便地找到产生故障的原因和源代码位置,并能方便地进行局部修改、切割;(可维护性与运行可管理性不同)&&3、 可扩充性:系统方案的升级、扩容、扩充性能&&系统在建成后会有一段很长的运行周期,在该周期内,应用在不断增加,应用的层次在不断升级,因此采用的构架设计等方案因充分考虑升级、扩容、扩充的可行性和便利&&4、 可移植性&&不同客户端、应用服务器、数据库管理系统:如果潜在的客户使用的客户端可能使用不同的操作系统或浏览器,其可移植性必须考虑客户端程序的可移植性,或尽量不使业务逻辑放在客户端;数据处理的业务逻辑放在数据库管理系统中会有较好的性能,但如果客户群中不能确定使用的是同一种数据库管理系统,则业务逻辑就不能数据库管理系统中;达到可移植性一定要注重标准化和开放性:只有广泛采用遵循国际标准,开发出开放性强的产品,才可以保证各种类型的系统的充分互联,从而使产品更具有市场竞争力,也为未来的系统移植和升级扩展提供了基础。&&5、 需求的符合性&&从源代码的组织结构看需求的符合型主要考虑针对用户需求可能的变化的软件代码及构架的最小冗余(同时又要使得系统具有一定的可扩展性)。&&五、写系统构架设计文档应考虑的问题&&构架工作应该在需求开发完成约80%的时候开始进行,不必等到需求开发全部完成,需要项目经理以具体的判断来评估此时是否足以开始构建软件构架。&&给出一致的轮廓:系统概述。一个系统构架需要现有概括的描述,开发人员才能从上千个细节甚至数十个模块或对象类中建立一致的轮廓。&&构架的目标应该能够清楚说明系统概念,构架应尽可能简化,最好的构架文件应该简单、简短,清晰而不杂乱,解决方案自然。&&构架应单先定义上层的主要子系统,应该描述各子系统的任务,并提供每个子系统中各模块或对象类的的初步列表。&&构架应该描述不同子系统间相互通信的方式,而一个良好的构架应该将子系统间的通信关系降到最低。&&成功构架的一个重要特色,在于标明最可能变更的领域,应当列出程序中最可能变更的部分,说明构架的其他部分如何应变。&&复用分析、外购:缩短软件开发周期、降低成本的有效方案未必是自行开发软件,可以对现有软件进行复用或进行外购。应考虑其对构架的影响。&&除了系统组织的问题,构架应重点考虑对于细节全面影响的设计决策,深入这些决策领域:外部软件接口(兼容性、通信方式、传递数据结构)、用户接口(用户接口和系统层次划分)、数据库组织和内容、非数据库信息、关键算法、内存管理(配置策略)、并行性、安全性、可移植性、网络多人操作、错误处理。&&要保证需求的可追踪性,即保证每个需求功能都有相应模块去实现。&&构架不能只依据静态的系统目标来设计,也应当考虑动态的开发过程,如人力资源的情况,进度要求的情况,开发环境的满足情况。构架必须支持阶段性规划,应该能够提供阶段性规划中如何开发与完成的方式。不应该依赖无法独立运行的子系统构架。将系统各部分的、依赖关系找出来,形成一套开发计划。&&六、结语&&系统构架设计和千差万别的具体的开发平台密切相关,因此在此无法给出通用的解决方案,主要是为了说明哪些因素是需要考虑的。对于每个因素的设计策略和本文未提到的因素需要软件构架设计师在具体开发实践中灵活把握。不同因素之间有时是矛盾的,构架设计时需要根据具体情况进行平衡。&
架构设计中的方法学
架构设计是一种权衡(trade-off)。一个问题总是有多种的解决方案。而我们要确定唯一的架构设计的解决方案,就意味着我们要在不同的矛盾体之间做出一个权衡。我们在设计的过程总是可以看到很多的矛盾体:开放和整合,一致性和特殊化,稳定性和延展性等等。任何一对矛盾体都源于我们对软件的不同期望。可是,要满足我们希望软件稳定运行的要求,就必然会影响我们对软件易于扩展的期望。我们希望软件简单明了,却增加了我们设计的复杂度。没有一个软件能够满足所有的要求,因为这些要求之间带有天生的互斥性。而我们评价架构设计的好坏的依据,就只能是根据不同要求的轻???缓急,在其间做出权衡的合理性。
1.&&&&&&&&目标&我们希望一个好的架构能够:&
重用:为了避免重复劳动,为了降低成本,我们希望能够重用之前的代码、之前的设计。重用是我们不断追求的目标之一,但事实上,做到这一点可没有那么容易。在现实中,人们已经在架构重用上做了很多的工作,工作的成果称为框架(Framework),比如说Windows的窗口机制、J2EE平台等。但是在企业商业建模方面,有效的框架还非常的少。&&&&&透明:有些时候,我们为了提高效率,把实现的细节隐藏起来,仅把客户需求的接口呈现给客户。这样,具体的实现对客户来说就是透明的。一个具体的例子是我们使用JSP的tag技术来代替JSP的嵌入代码,因为我们的HTML界面人员更熟悉tag的方式。&延展:我们对延展的渴求源于需求的易变。因此我们需要架构具有一定的延展性,以适应未来可能的变化。可是,如上所说,延展性和稳定性,延展性和简单性都是矛盾的。因此我们需要权衡我们的投入/产出比。以设计出具有适当和延展性的架构。&简明:一个复杂的架构不论是测试还是维护都是困难的。我们希望架构能够在满足目的的情况下尽可能的简单明了。但是简单明了的含义究竟是什么好像并没有一个明确的定义。使用模式能够使设计变得简单,但这是建立在我熟悉设计模式的基础上。对于一个并不懂设计模式的人,他会认为这个架构很复杂。对于这种情况,我只能对他说,去看看设计模式。&&&&&&高效:不论是什么,我们都希望架构是高效的。这一点对于一些特定的来说尤其重要。例如实时、高访问量的网站。这些值的是技术上的高效,有时候我们指的高效是效益上的高效。例如,一个只有几十到一百访问量的信息,是不是有必要使用EJB技术,这就需要我们综合的评估效益了。&安全:安全并不是我们文章讨论的重点,却是架构的一个很重要的方面。
为了达到上述的目的,我们通常需要对架构设计制定一些简单的规则:&
顾名思义,就是把功能分解开来。为什么呢?我们之所以很难达到重用目标就是因为我们编写的经常处于一种好像是重复的功能,但又有轻微差别的状态中。我们很多时候就会经不住诱惑,用拷贝粘贴再做少量修改的方式完成一个功能。这种行为在XP中是坚决不被允许的。XP提倡"Once&and&only&once",目的就是为了杜绝这种拷贝修改的现象。为了做到这一点,我们通常要把功能分解到细粒度。很多的设计思想都提倡小类,为的就是这个目的。
所以,我们的中的类和方法的数目就会大大增长,而每个类和方法的平均代码却会大大的下降。可是,我们怎么知道这个度应该要如何把握呢,关于这个疑问,并没有明确的答案,要看个人的功力和具体的要求,但是一般来说,我们可以用一个简单的动词短语来命名类或方法的,那就会是比较好的分类方法。&
我们使用功能分解的规则,有助于提高重用性,因为我们每个类和方法的精度都提高了。这是符合大自然的原则的,我们研究自然的主要的一个方向就是将物质分解。我们的思路同样可以应用在软件开发上。除了重用性,功能分解还能实现透明的目标,因为我们使用了功能分解的规则之后,每个类都有自己的单独功能,这样,我们对一个类的研究就可以集中在这个类本身,而不用牵涉到过多的类。&
根据实际情况决定不同类间的耦合度
虽然我们总是希望类间的耦合度比较低,但是我们必须客观的评价耦合度。之间不可能总是松耦合的,那样肯定什么也做不了。而我们决定耦合的程度的依据何在呢?简单的说,就是根据需求的稳定性,来决定耦合的程度。对于稳定性高的需求,不容易发生变化的需求,我们完全可以把各类设计成紧耦合的(我们虽然讨论类之间的耦合度,但其实功能块、模块、包之间的耦合度也是一样的),因为这样可以提高效率,而且我们还可以使用一些更好的技术来提高效率或简化代码,例如Java中的内部类技术。可是,如果需求极有可能变化,我们就需要充分的考虑类之间的耦合问题,我们可以想出各种各样的办法来降低耦合程度,但是归纳起来,不外乎增加抽象的层次来隔离不同的类,这个抽象层次可以是具体的类,也可以是接口,或是一组的类(例如Beans)。我们可以借用Java中的一句话来概括降低耦合度的思想:"针对接口编程,而不是针对实现编程。
设计不同的耦合度有利于实现透明和延展。对于类的客户(调用者)来说,他不需要知道过多的细节(实现),他只关心他感兴趣的(接口)。这样,目标类对客户来说就是一个黑盒子。如果接口是稳定的,那么,实现再怎么扩展,对客户来说也不会有很大的影响。以前那种牵一发而动全身的问题完全可以缓解甚至避免。&
其实,我们仔细的观察GOF的23种设计模式,没有一种模式的思路不是从增加抽象层次入手来解决问题的。同样,我们去观察Java源码的时候,我们也可以发现,Java源码中存在着大量的抽象层次,初看之下,它们什么都不干,但是它们对的设计起着重大的作用。&
够用就好&:&&&&我们在上一章中就谈过敏捷方法很看重刚好够用的问题,现在我们结合架构设计来看:在同样都能够满足需要的情况下,一项复杂的设计和一项简单的设计,哪一个更好。从敏捷的观点来看,一定是后者。因为目前的需求只有10项,而你的设计能够满足100项的需求,只能说这是种浪费。你在设计时完全没有考虑成本问题,不考虑成本问题,你就是对开发组织的不负责,对客户的不负责。&
这篇文章的写作思路很多来源于对模式的研究。因此,文章中到处都可以看到模式思想的影子。模式是一种整理、传播思想的非常优秀的途径,我们可以通过模式的方式学习他人的经验。一个好的模式代表了某个问题研究的成果,因此我们把模式应用在架构设计上,能够大大增强架构的稳定性。
架构的本质在于其抽象性。它包括两个方面的抽象:业务抽象和技术抽象。架构是现实世界的一个模型,所以我们首先需要对现实世界有一个很深的了解,然后我们还要能够熟练的应用技术来实现现实世界到模型的映射。因此,我们在对业务或技术理解不够深入的情况下,就很难设计出好的架构。当然,这时候我们发现一个问题:怎样才能算是理解足够深入呢。我认为这没有一个绝对的准则。&
一次,一位朋友问我:他现在做的有很大的变化,原先设计的工作流架构不能满足现在的要求。他很希望能够设计出足够好的工作流架构,以适应不同的变化。但是他发现这样做无异于重新开发一个lotus&notes。我听了他的疑问之后觉得有两点问题:&
首先,他的开发团队中并没有工作流领域的专家。他的客户虽然了解自己的工作流程,但是缺乏足够的理论知识把工作流提到抽象的地步。显然,他本身虽然有技术方面的才能,但就工作流业务本身,他也没有足够的经验。所以,设计出象notes那样的的前提条件并不存在。
其次,开发一个工作流的目的是什么。原先的工作流运作的不好,其原因是有变化发生。因此才有改进工作流的动机出现。可是,毕竟notes是为了满足世界上所有的工作流而开发的,他目前的应用肯定达不到这个层次。&
因此,虽然做不到最优的业务抽象,但是我们完全可以在特定目的下,特定范围内做到最优的业务抽象。比如说,我们工作流可能的变化是工组流路径的变化。我们就完全可以把工作流的路径做一个抽象,设计一个可以动态改变路径的工作流架构。&
有些时候,我们虽然在技术上和业务上都有所欠缺,没有办法设计出好的架构。但是我们完全可以借鉴他人的经验,看看类似的问题别人是如何解决的。这就是我们前面提到的模式。我们不要把模式看成是一个硬性的解决方法,它只是一种解决问题的思路。Martin&Fowler曾说:"模式和业务组件的区别就在于模式会引发你的思考。
在《分析模式》一书中,Martin&Fowler提到了分析和设计的区别。分析并不仅仅只是用用例列出所有的需求,分析还应该深入到表面需求的的背后,以得到关于问题本质的Mental&Model。然后,他引出了概念模型的概念。概念模型就类似于我们在讨论的抽象。Martin&Fowler提到了一个有趣的例子,如果要开发一套软件来模拟桌球游戏,那么,用用例来描述各种的需求,可能会导致大量的运动轨迹的出现。如果你没有了解表面现象之后隐藏的运动定律的本质,你可能永远无法开发出这样一个。&
关于架构和抽象的问题,在后面的文章中有一个测量模式的案例可以很形象的说明这个问题。&
架构的一些误解&
我们花了一些篇幅来介绍架构的一些知识。现在回到我们的另一个主题上来。对于一个敏捷开发过程,架构意味着什么,我们该如何面对架构。这里我们首先要澄清一些误解:&
误解1:架构设计需要很强的技术能力。从某种程度来说,这句话并没有很大的错误。毕竟,你的能力越强,设计出优秀架构的几率也会上升。但是能力和架构设计之间并没有一个很强的联系。即使是普通的编程人员,他一样有能力设计出能实现目标的架构。&
误解2:架构由专门的设计师来设计,设计出的蓝图交由员来实现。我们之所以会认为架构是设计师的工作,是因为我们喜欢把软件开发和建筑工程做类比。但是,这两者实际上是有着很大的区别的。关键之处在于,建筑设计已经有很长的历史,已经发展出完善的理论,可以通过某些理论(如力学原理)来验证设计蓝图。可是,对软件开发而言,验证架构设计的正确性,只能够通过写代码来验证。因此,很多看似完美的架构,往往在实现时会出现问题。&
误解3:在一开始就要设计出完善的架构。这种方式是最传统的前期设计方式。这也是为XP所摒弃的一种设计方式。主要的原因是,在一开始设计出完美的架构根本就是在自欺欺人。因为这样做的基本假设就是需求的不变性。但需求是没有不变的(关于需求的细节讨论,请参看拙作『需求的实践』)。这样做的坏处是,我们一开始就限制了整个的软件的形状。而到实现时,我们虽然发现原来的设计有失误之处,但却不愿意面对现实。这使得软件畸形的生长。原本一些简单的问题,却因为别扭的架构,变得非常的复杂。这种例子我们经常可以看到,例如为兼容前个版本而导致的软件复杂性。而2000年问题,TCP/IP的安全性问题也从一个侧面反映了这个问题的严重性。
误解4:架构蓝图交给员之后,架构设计师的任务就完成了。和误解2一样,我们借鉴了建筑工程的经验。我们看到建筑设计师把设计好的蓝图交给施工人员,施工人员就会按照图纸建造出和图纸一模一样的大厦。于是,我们也企图在软件开发中使用这种模式。这是非常要命的。软件开发中缺乏一种通用的语言,能够充分的消除设计师和员的沟通隔阂。有人说,UML不可以吗?UML的设计理念是好的,可以减轻沟通障碍问题。可是要想完全解决这个问题,UML还做不到。首先,员都具有个性化的思维,他会以自己的思维方式去理解设计,因为从设计到实现并不是一项机械的劳动,还是属于一项知识性的劳动(这和施工人员的工作是不同的)。此外,对于员来说,他还极有可能按照自己的想法对设计图进行一定的修改,这是非常正常的一项举动。更糟的是,员往往都比较自负,他们会潜意识的排斥那些未经过自己认同的设计。
架构设计的过程模式&
通常我们认为模式都是用在软件开发、架构设计上的。其实,这只是模式的一个方面。模式的定义告诉我们,模式描述了一个特定环境的解决方法,这个特定环境往往重复出现,制定出一个较好的解决方法有利于我们在未来能有效的解决类似的问题。其实,在管理学上,也存在这种类似的这种思维。称为结构性问题的化解决方法。所以呢,我们完全可以把模式的思想用在其它的方面,而目前最佳的运用就是过程模式和组织模式。在我们的文章中,我们仅限于讨论过程模式。&方法论对软件开发而言意味着什么?我们如何看待软件开发中的方法论?方法论能够成为软件开发的救命稻草吗?在读过此文后,这些疑惑就会得到解答。&&&架构设计中的方法学(1)&&方法源于恐惧
&&方法论的英文为Methodology,词典中的解释为:&A series of related methods or techniques&,我们可以把它定义为软件开发(针对软件开发)的一整套方法、过程、规则、实践、技术。关于方法论出现的问题,我很赞同Alistair Cockburn的一句话,&方法论源于恐惧。&出于对项目的超期、成本失控等等因素的恐惧,项目经理们从以前的经验出发,制定出了一些控制、监测项目的方法、技巧。这就是方法论产生的原因。
&&在Agile Software Development一书中,作者提到了方法论的十三个要素,基本能够函盖方法论的各个方面:
&&角色(Roles)、个性(Personality)、技能(Skills)、团队(Teams)、技术(Techniques)、活动(Activities)、过程(Process)、工件(Work products)、里程碑(Milestones)、标准(Standards)、质量(Quality)、工具(Tools)、团队价值(Team Values)。
&&它们之间的关系可以用一幅图来表示:
&&&&&图&1.&方法论的十三个要素
&&很多的方法论,都涉及了上面列举的十三要素中的部分要素,因此,我们可以把方法论看作是一个抽象的、无穷的超集,而现实中的方法论都是指超集的一个有限的子集而已。它们之间的关系就好像有理数和1到100之间的整数的关系一样。不论是XP,还是UI设计经验之类,都属于方法论的一个子集,只是这两个子集之间有大小的差别而已。我们还应该看到,讨论一个完备的方法论是没有意义的,因此这种方法论铁定不存在,就好像你视图穷举出所有的有理数一样荒唐。因此,我们关于一个通用的方法论的说法也是无意义的。好的方法论,比如说XP、水晶系列,它们都有一个适合的范围,因为它们了解一点,自己并不是一个无所不能的方法论。
在现实中,我们其实不断的在接触方法论。比如说,为了控制项目的进度,项目经理要求所有的开发人员每周递交一份详细的进度报告,这就是一种方法、一种技巧。如果把开发过程中的这些技巧系统的组织起来,就能够成为一种方法论。你可能会说,那一种方法论的产生也太容易了吧。不,这样产生的方法论并没有太大的实用价值,没有实用价值的方法论根本就没有存在的必要。因此,一个成功的方法论是要能够为多个的项目所接受,并且能够成功实现软件的交付的方法论。
我和我的同事在实践中做了一些试验,希望能够把一些好的方法论应用于开发团队。试验的结果很无奈,方法论实施的效果并不理想,一开始我们认为是方法本身的原因,到后来,我们发现事情并不是这么简单。在试验的过程中,开发人员一致认同方法论的优势所在,但是在实施过程中,鲜有坚持的下来的。在Agile Software Development中,我发现作者遇到了和我们一样的问题。
Alistair Cockburn在和大量的项目团队的访谈之后,写成了Agile Software Development一书。在访谈之前,他笃定自己将会发现高度精确的过程控制是成功的关键所在,结果他发现事实并非如此,他把他的发现归结为7条定律。而我在实际中的发现也包含在这七条定律中,总结起来就只有两点:沟通和反馈。
只要能够保证良好的沟通和即时的反馈,那么开发团队即使并没有采用先进的方法论,一样可以成功。相反,那些&高质量&的团队却往往由于缺乏这两个因素而导致失败(我们这里指的失败是用户拒绝使用最终的软件)。最有效,而成本也最低的沟通方法就是面对面(face to face)的沟通,而随着项目团队的变大,或是另外一些影响因素的加入(比如地理位置的隔绝),面对面的沟通越来越难实现,这导致沟通的成本逐渐加大,质量也慢慢下降。但这并不是说非面对面的沟通不可,重要的是我们需要知道不同的沟通方式的成本和质量并不相同。XP方法尤为强调面对面的沟通,通过现场客户、站立会议、结对编程等方式来保证沟通的有效。在我的经验中,一个开发团队其实是需要多种沟通方式的结合的。完全的面对面的沟通对某些团队来说是很难实现的,那么问题的关键就在于你如何应用沟通的方式来达到你希望的效果。在前不久结束的欧莱雅创业计划大赛上,有一支团队特别引人注目,他们彼此间素未谋面,仅仅凭借Internet和电话完成了高效的合作。他们虽然没有使用面对面的沟通方式,但是仍然达成了既定的目标。软件开发也是一样的,面对面的沟通是非常有必要的,但其它的沟通方式也是需要的。
再看反馈,不论是控制进度,还是保证客户的满意度,这些活动都需要管理成本。软件开发中的管理成本的一个通性就是伴随有中间产出物(intermediate delivery)。比如说我们的需求规约、分析文档、设计文档、测试计划,这些都属于中间产出物。中间产出物的增加将会带来效率下降的问题,因为开发人员的时间都花在了完成中间产出物的工作上,花在给软件新功能上的时间就减少了。而中间产出物的主要目的是两个,一个是为了保证软件如客户所愿,例如需求规约;另一个是为了作为团队中的其他成员工作的输入,例如开发计划、测试计划等。因此,我们也可以针对这两点来商讨对策,一种是采用迭代的思想,提高软件发布的频率,以保证客户的需求被确实的满足,另一种就是缩小团队的沟通范围,保证成员能够从其他人那里得到新的思路,而不是撰写规范的内部文档(内部文档指那些仅为内部开发人员之间的沟通所需要的文档)。
因此,一个软件项目的成功和你采用的开发方法论并没有直接的关系。
我们根据把拥有大量artifact(RUP官方翻译为工件,意思是软件开发过程中的中间产物,如需求规约、设计模型等)和复杂控制的软件开发方法称为重型(Heavy Weight)方法,相对的,我们称artifact较少的方法为轻型(Light Weight)方法。在传统的观念中,我们认为重型方法要比轻型安全许多。因为我们之所以想出重型方法,就是由于在中大型的项目中,项目经理往往远离代码,他无法有效的了解目前的工程的进度、质量、成本等因素。为了克服未知的恐惧感,项目经理制定了大量的中间管理方法,希望能够控制整个项目,最典型的莫过于要求开发人员频繁的递交各种表示项目目前状态的报告。
在Planning XP一书中有一段讨论轻重型方法论的精辟论述,它把重型方法论归结为一种防御性的姿态(defensive posture),而把轻型方法论归结为一种渴望成功(Plan to win)的心态。如果你是采用了防御性姿态,那么你的工作就集中在防止和跟踪错误上,大量的工作流程的制定,是为了保证项目不犯错误,而不是项目成功。而这种方法也不可谓不好,但前提是如果整个团队能够满足前面所提到的两个条件的话,项目也肯定会成功,但是重型方法论的一个弊端就在于,大家都在防止错误,都在惧怕错误,因此人和人之间的关系是很微妙的,要达到充分的沟通也是很难的。最终,连对人的评价也变成是以避免错误的多寡作为考评的依据,而不是成就。我们在做试验的时候,一位项目经理开玩笑说,&方法论源自项目经理的恐惧,这没错。但最糟糕的是整个团队只有项目经理一个人恐惧,如果能够做到人人的恐惧,那大家也就没有什么好恐惧的了。&这句话提醒了我们,如果一个团队的精神就是力求成功,那么这支团队的心态就和其它的团队不同了,尤其是对待错误的心态上。根本就没有必要花费大量的精力来预防错误,错误犯了就犯了,即时改正就可以了。这其实就是渴望成功的心态。
方法论的艺术
&管理,被称为科学和艺术的融合体,而管理的艺术性部分很大程度的体现在人的管理上。我说,方法学,一样是科学和艺术的融合体。这是有依据的,其实方法论和管理学是近亲关系,管理学中有一门分支是项目管理,而在软件组织中,项目管理是非常重要的,方法学就是一种针对软件开发的一种特定的项目管理(或是项目管理的一个子集)。&
重型方法最大的一个问题就在于他不清楚或忽略了艺术这个层次,忽视了人的因素,把人做为一个计量单位,一种资源,一种线性元素。而人的要素在软件开发中是非常重要的,软件开发实际上是一种知识、智力的转移过程,最终形成的产品是一种知识产品,它的成本取决于开发者的知识价值,因此,人是最重要的因素。而人这个要素是很难衡量的,每个人都有不同的个性、想法、经验、经历,这么多复杂的因素加在一起,就导致了人的不可预见性。因此,我们强调管人的艺术。
&&最简单的例子是,在重型方法中,我们的基本假设是对人的不信任。项目经理要控制项目。但不信任就会产生很多的问题,比如士气不高,计划赶不上变化,创新能力低下,跳槽率升高等等。人都是希望被尊重的,技术人员更看重这一点,而很多公司也口口声声说自己多么多么以人为本,可是采用的却是以不信任人为前提的开发方法,言行不一。我们说敏捷方法的出发点是相互信任,做到这一点是很难的,但是一旦做到了,那这个团队就是非常具有竞争力的。因此,这就产生了一个问题,在没有做到完全的相互信任之前,我们到底相不相信他人呢,这就是我提到的艺术性的问题,什么时候你要相信人?什么时候你不相信人,这些都是需要权衡的问题,也都是表现你艺术性的问题。
&&敏捷方法
敏捷代表着有效和灵活。我们称那些轻型的、有效的方法为敏捷方法。在重型方法中,我们在一些不必要、重复的中间环节上浪费了太多的精力,而敏捷则避免了这种浪费。我们的文章将会重点的讨论敏捷(Agile)方法论的思想,敏捷这个名字的前身就是轻型。目前已经有了一个敏捷联盟,他们制定了敏捷宣言:
&Individuals and interactions over processes and tools.
&Working software over comprehensive documentation.
&Customer collaboration over contract negotiation.
Responding to change over following a plan.
而我对敏捷的理解包括了几个方面:
较低的管理成本和高质量的产出。软件开发存在两个极端:一个是没有任何的管理成本,所有的工作都是为了软件的产出,但是这种方式却往往导致软件开发过程的混沌,产品的低质量,团队士气的低落。另一个是大量管理活动的加入,评审、变更管理,缺陷跟踪,虽然管理活动的加入能够在一定程度上提高开发过程的有序性,但是成本却因此提高,更糟糕的是,很容易导致团队的低效率,降低创新能力。因此,敏捷方法试图寻找一个平衡点,用低成本的管理活动带来最大的产出,即软件的高质量。
&尊重人性。敏捷方法尊重人性,强调效率。软件开发可以说是一种脑力的投入,如果不能保证开发人员的自愿投入,产品就肯定要打折扣。事实多次的证明,一个愿意投入的开发人员和一个不愿意投入的开发人员效率相差在三倍以上,对组织的贡献更是在十倍以上。
&沟通和反馈是一切的基础。我们已经讨论过沟通的重要程度,而即时的反馈是拥抱变化的前提条件。
&客户是上帝。没有客户就没有一切,客户的重要性可以用一句话来形容,就是以合理的成本建造合适的软件(build the right system at the right cost)。
敏捷其实也有轻重之分,关键在于是否能够做到有效和灵活。因此,敏捷方法论提倡的一个思想是&刚好够(barely sufficient)&。不过这个&刚好够&可不是那么容易判断的。一支8个人的团队采用XP方法,随着方法的熟练使用,团队的能力在不断的增强,能够处理的问题越越来越复杂,也许他们能够处理采用重型方法的20个人团队能够处理的问题。可是如果团队的人数突然增加到12人,这支团队肯定就会出问题,他的表现可能还不如那支20个人的团队了。人数增加的时候,原先的方法肯定还做适当的调整,比如说,在原先的敏捷方法上增加一些重型方法的技巧。我们不能够要求一支6个人的团队和一支20个人的团队用同样的方法,前者可能采用轻一些的敏捷方法,后者可能采用重一些的敏捷方法,关键的问题在于,两支团队都把重点放在沟通、反馈、频繁交付软件这些关键的因素上,也就是做到有效和灵活。
&&架构设计
&&架构(Architecture)(也有被称为体系结构的)是软件设计中非常重要的一个环节。软件开发的过程中只要需求和架构确定之后,这个软件就基本上可以定型了。这就好比骨骼确定了,这个人的体形就不会有很大的变化。因此我选择了架构设计来讨论敏捷软件开发(需求我已经写过了)。我们在前面讨论过超集和子集的概念,因此我们接下去要讨论的架构设计也是一个很小的子集。方法论如果没有经历过多个项目的检验是不能称为成功的方法论的,我也并不认为我的架构设计就是一个好的方法论,但引玉还需抛砖,他的主要目的是为了传播一种思想。因此,我采用了模式语言(PLOP)做为写作架构设计的形式,主要的原因就是模式是一种很好的组织思想的方法。
因此,在我们接下去的历程中,我们集中讨论的东西就围绕着架构、方法学、敏捷这三个要素展开。这篇文章并不是讨论如何编码实现软件架构的,也不要单纯的把它看作架构设计的指南,其实文中的很多思想来自于方法论,因此提到的很多架构设计的思想也适用于其它工作,如果能够了解这一点,看这篇文章的收获可能会更多一些。&架构设计中的方法学(3)&&架构源自需求
从需求到架构
&&在需求阶段,我们可以得到一些代表需求调研成果的中间产物。比如说,CRC卡片、基本用例模型、用户素材、界面原型、界面原型流程图
、非功能需求、变化案例等。我们在架构设计阶段的主要工作就是要把这些需求阶段的中间产物转换为架构设计阶段的中间产物。
&&其实,架构设计就是要完成两项工作,一是分析,二是设计。分析是分析需求,设计则是设计软件的大致结构。很多的方法论把分析和设计两种活动分开来,但其实这两者是很难区分的,做分析的时候会想到如何设计,而思考如何设计反过来又会影响分析的效果。可以说,他们两者之间是相互联系和不断迭代的。这种形态我们将会在后面的迭代设计模式中详细的讨论。
在敏捷方法论中,需求最好是迭代进行的,也就是说一点一点的作需求。这种做法在那些需求变化快的项目中尤其适用。由于我们采用的流程是一种迭代式的流程,这里我们将会面临着如何对待上一次迭代的中间产物的问题。如果我们每一次迭代都需要修改已存在的中间产物,那么这种维护的成本未免过大。因此,敏捷方法论的基本做法是,扔掉那些已经没有用处的中间产物。还记得在第一章的时候,我们强调说软件要比文档重要。我们生成中间产物的目的都是为了生成最终的程序,对于这些已经完成作用的模型,没有必要付出额外的维护成本。
不要断章取义的采用抛弃模型的做法。因为,抛弃模型的做法需要一个适合环境的支持。后面会针对这个话题开展大范围的讨论。这里我们简单的做一个了解:
&简单化:简单的模型和简单的程序。模型和程序越复杂,就需要更多的精力来处理它们。因此,我们尽可能的简化它们,为的是更容易的处理它们。
&高效的沟通渠道:通过增强沟通的效果来减少对中间产物的需要。试想一下,如果我随时能够从客户那里得到需求的细节资料,那前期的需求调研就没有必要做的太细致。
角色的交叉轮换:开发人员之间建立起交换角色的机制,这样,能够尽量的避免各子系统诸侯割据的局面。
清晰的流程:或者我们可以称之为明确的过程。过程在方法论中向来都是一个重点,敏捷方法论也不例外。开发人员能够清楚的知道,今天做什么,明天做什么。过程不是给别人看的,而是给自己用的。
工具:好用的工具能够节省大量的时间,这里的工具并不仅仅指CASE工具,还包括了版本控制工具、自动化测试工具、画图工具、文档制作和管理工具。使用工具要注意成本和效益的问题。
标准和风格:语言不通是沟通的一个很大的障碍。语言从某个角度来看属于一种标准、一种风格。因此,一个团队如果采用同样的编码标准、文档标准、注释风格、制图风格,那么这个团队的沟通效率一定非常的高。
如果上述的环境你都不具备,或是欠缺好几项,那你的文档的模型还是留着的好。
&仅针对需求设计架构
仅针对需求设计架构的含义就是说不要做未来才有用的事情。有时候,我们会把架构考虑的非常复杂,主要的原因就是我们把很多未来的因素放入到现在来考虑。或者,我们在开发第一个产品的时候就视图把它做成一个完美的框架。以上的这两种思路有没有错呢?没有错,这只是如何看待投入的问题,有人希望开始的时候多投入一些,这样后续的投入就会节省下来。但在现实中,由于需求的不确定性,希望通过增加开始阶段的投入来将降低未来的投入往往是难以做到的,框架的设计也绝对不是能够一蹴而就的,此这种做法并不是一个好的做法。所以我们在后头会着重论述架构设计的简单性和迭代过程,也就是因为这个理由。
模式将可以帮助我们抓住重点。为了解决设计文档编辑器引出的七个问题,一共使用了8种不同的模式。这8种模式的组合其实就是架构,因为它们解决的,都是系统中最高层的问题。&&&&&&在实践中,人们发现架构也是存在模式的。比如,对于系统结构设计,我们使用层模式;对于分布式系统,我们使用代理模式;对于交互系统,我们使用MVC(模型-视图-控制器)模式。模式本来就是针对特定问题的解,因此,针对需求的特点,我们也可以采用相应的模式来设计架构。&&&&&&在sun网站上提供的宠物商店的范例中,就把MVC模式的思想扩展成为架构的思想,用于提供不同的界面视图:&&&&&&&&&&我们可以了解到在图的背后隐藏着的需求:系统需要支持多种用户界面,包括为普通用户提供的HTML界面,为无线用户提供的WML界面,为管理员提供的Swing界面,以及为B2B业务设计的WebService界面。这是系统最重要的需求,因此,系统的设计者就需要确定一个稳定的架构,以解决多界面的问题。相对于多界面的问题,后端的业务处理逻辑都是一致的。比如HTML界面和WML界面的功能并没有太大的差别。把处理逻辑和界面分离开来还有额外的好处,可以在添加功能的同时,不涉及界面的改动,反之亦然。这就是我们在第二篇中提到的耦合度的问题。&&&&&&MVC模式正可以适用于解决该问题。系统使用控制器来为业务逻辑选择不同的界面,这就完成了MVC架构的设计思路。在架构设计的工作中,我们手头上有模式这样一张好牌,有什么理由不去使用它呢?&&&&抓住重点&&&&&在架构设计一开始,我们就说架构是一种抽象,那就是说,架构设计摒弃了具体的细节,仅仅抓住软件最高层的概念,也就是最上层、优先级最高、风险最大的那部分需求。&&&&&&我们考虑、分析、解决一个问题,一定有一个渐进的过程。架构设计就是解决问题其中比较早期的一个阶段,我们不会在架构设计这个阶段投入过多的时间(具体的原因在下文会有讨论),因此关键点在于我们要能够在架构设计中把握住需求的重点。比如,我们在模式一节中提到了分布式系统和交互系统,分布和交互就是这两个系统的重点。那么,如果说我们面对的是一个分布式的交互系统,那么,我们就需要把这两种特性做为重点来考虑,并以此为基础,设计架构。而我们提到的宠物商店的范例也是类似的,除了MVC的架构,还有很多的设计问题需要解决,例如用于数据库访问的数据对象,用于视图管理的前端控制器,等等(具体使用到的架构模式可以访问sun的网站)。但是这些相对于MVC模式来说,属于局部的,优先级较低的部分,可以在架构确定后再来设计。&&&&&&架构设计和领域专家&&&&&&一个架构要设计的好,和对需求的理解是分不开的。因此在现实中,我们发现业务领域专家凭借着他对业务领域的了解,能够帮助开发人员设计出优秀的架构来。架构是需要抽象的,它是现实社会活动的一个

我要回帖

更多关于 sftp 权限属性 的文章

 

随机推荐