软件设计与体系结构 2-软件设计基础_第1页
软件设计与体系结构 2-软件设计基础_第2页
软件设计与体系结构 2-软件设计基础_第3页
软件设计与体系结构 2-软件设计基础_第4页
软件设计与体系结构 2-软件设计基础_第5页
已阅读5页,还剩100页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

2-软件设计基础目录壹软件设计的基本概念贰软件设计的范畴与内容叁软件设计的质量肆软件架构的概念与范畴伍高可用设计软件设计是一系列创造活动,是借助编程语言以简单和优雅的方式表达并解决现实需求的一门科学和艺术。什么是设计?设计是你身处两个世界---技术世界和人类的目标世界---而你尝试将这两个世界结合在一起。---MitchKapor,Lotus1-2-3发明者,《软件设计宣言》概述软件设计这一行为的目的是把软件的功能需求转化为软件的系统设计。设计师要产出系统的整体结构、功能模块划分、每个模块的数据库设计和实现方法,最后形成概要设计文档和详细设计文档。软件设计文档是架构师交付的文档,需求文档是产品经理交付的文档。互联网公司有三类核心的岗位,分别是:产品、技术、运营。概述产品经理是通过用户调研、功能设计让产品有用。技术是把产品实现出来,实现产品经理的构想,让产品可用。运营是为了更好地连接产品和用户而做的一切行为和实践。产品和用户不能产生关系的,产品就没有价值了。运营这件事做到极致,可以让你的用户成为产品的一部分。软件开发周期系统设计系统设计是把需求转化为软件系统的最重要的环节。系统设计的优劣在根本上决定了软件系统的质量。就象“心里充满的,口里就说出来”那样可以断定“差的系统设计必定产生差的软件系统。”所以我们要努力保证系统设计“根正苗红”,把一切不良的设计思潮消灭在萌芽状态。Coad和Yourdon把“设计”定义为:为问题域的外部可见行为的规约增添实际的计算机系统实现所需的细节,包括关于人机交互、任务管理和数据管理的细节。系统设计曾经的WindowsNT的一位系统设计师拥有8辆法拉利跑车,让Microsoft公司的一些程序员十分眼红。但你只能羡慕、嫉妒而不能愤恨,因为并不是每个程序员都有本事成为复杂软件系统的设计师。系统设计要比纯粹的编程困难得多。即便你清楚客户的需求,却未必知道应该设计什么样的软件系统——既能挣最多的钱又能让客户满意。“天下西湖三十六,最美是杭州”,千年前苏东坡大学士对西湖精采绝伦的系统设计,使杭州荣升为“天堂”一些建议(1)让业务骨干来参与到软件的需求调研和业务设计,与供应商软件架构师们一起设计;而不是让一些“闲人”来凑热闹。(2)主动帮助供应商了解业务,因为即使再老练的供应商也不会懂多少你企业的水深水浅。(3)软件前期多听听阶段汇报,将上线时的一次性验收拆解成很多个小验收。将压力提前分解,让软件质量更健康。包括四方面内容从功用上来讲,软件设计包括四方面内容:体系结构设计、模块设计、数据结构与算法设计、用户界面设计。如果将软件系统比喻为人体,那么:(1)体系结构就如同人的骨架。如果某个家伙的骨架是猴子,那么无论怎样喂养和美容,这家伙始终都是猴子,不会成为人。(2)模块就如同人的器官,具有特定的功能。人体中最出色的模块设计之一是手,手只有几种动作,却能做很多的事情。包括四方面内容(3)数据结构与算法就如同人的血脉和神经,它让器官具有生命并能发挥功能。数据结构与算法分布在体系结构和模块中,它将协调系统的各个功能。人的耳朵和嘴巴虽然是相对独立的器官,但如果耳朵失聪了,嘴巴就只能发出“啊”“呜”的声音,等于丧失了说话的功能(所以聋子天生就是哑巴),可人们却又能用手势代替说话。人体的数据结构与算法设计真是十分奇妙。包括四方面内容(4)用户界面就如同人的外表,最容易让人一见钟情或一见恶心。象人类追求心灵美和外表美那样,软件系统也追求(内在的)功能强大和(外表的)界面友好。但随着生活节奏的加快,人们已少有兴趣去品味深藏不露的内在美。如果把Unix系统比作是健壮的汉子和妇人,那么Windows系统就象妩媚的小白脸和狐狸精。想不到Windows系统竟然能兴风作浪,占去大半市场。深情地关注软件的质量因素正确性与精确性、性能与效率、易用性、可理解性与简洁性、可复用性与可扩展性等。即使把软件设计做好了,也并不意味着就能产生好的软件系统。在程序设计、测试、维护等环节还要做大量的工作,无论哪个环节出了差错,都会把好事搞砸了。我们在开发软件时,一定要吸取这个教训。从建筑设计看软件设计:“设计良好的建筑应该展示出坚固、适用和令人赏心悦目的特点。”对好的软件设计来说也是如此:适用:软件要符合开发的目标,满足用户需求;坚固:软件应该不含任何妨碍其功能的缺陷;赏心悦目:使用软件的体验应该是愉快的。几个常见的问题(1)是不是开发前一定需要进行软件设计?不能马上编写代码吗?当软件结构复杂的时候,如果直接编写代码的话,会造成后期一系列的问题,而这个时候软件产品的维护和扩展举步维艰、难以测试和差错,从而直接影响项目的开发效率和产品的最终指令,以及工程师的生活质量。(2)用户需求,需要实现什么功能?使用什么用户交互方式?软件开发时根据用户所需的功能进行设计开发的。我们需要以用户为中心来思考设计功能的实现。几个常见的问题(3)如何部署到用户的设备上去呢?我们需要考虑软件的部署是因为我们开发使用的设备与最终用户使用的设备可能不一样。所以我们需要考虑软件部署的问题。不能出现开发和测试过程时候软件可以正常运行,到了用户设备时不能正常运行的现象。几个常见的问题(4)为什么要考虑扩展性、维护性、复用性?a)我们需要考虑代码的扩展性是因为,到产品需要升级或者功能增加的时候,我们是否可以很快的吧功能添加上去?b)当开发人员离职时,后面接手工作的人员是否可以很快的熟悉这份代码并且容易进行维护?c)当有新项目需要开发时,我们是否可以重复使用这个项目的代码呢?需求1:教学秘书需要将学生的综合成绩按高到低进行排序:(1)教学秘书将学生成绩单录入,形成学生成绩文件;(2)打印成绩单,交给学生;(3)依据学生成绩文件,对学生成绩进行综合分析,形成分析报告文件;(4)将分析报告打印出来,交给主管校长。其中最重要的设计需求是排序,可以采用的设计是对实现排序方法的设计:voidOrderScores(struct*scores[]){冒泡排序算法,step1;step2;...}关于“软件设计”的几个小例子需求2:数据字典“销售订单”,可以设计关系数据表:Order(ID,Date,Customer,...),OrderItem(ID,Product,Quantity,...)关于“软件设计”的几个小例子需求3:边界类“查询满足条件的图书”,可以设计图形化web用户界面:关于“软件设计”的几个小例子软件设计在软件工程中所处的位置良好的软件工程设计具有不可比拟的意义,它胜于执行软件需求、软件编码、软件维护等任何一个环节,这就是设计的优越性。秉承设计优先这一原则,会让软件开发变得简单而高效,可以尽量避免掉因设计失误而导致的缺陷。一个健壮的程序必然有良好的设计,软件工程设计是构建复杂软件中必不可少的重要环节。在软件设计中,通常要考虑软件的特征:模块化、抽象与信息隐蔽、局部化、一致性以及适应性等特征。软件设计在软件工程中所处的位置因此,我们把设计理解为:将用户需求准确的转化为软件设计模型与文档的方法。而设计的目标是质量:“设计阶段”是软件工程中形成质量的关键阶段,其后所有阶段的活动都要依赖于设计的结果。“编写一段能工作的灵巧的代码是一回事,而设计能支持某个长久业务的东西则完全是另一回事。” ---C.Ferguson软件设计在软件工程中所处的位置case:设计支持长久业务人类历史上的几个典型关于“设计”的案例案例一:2004年5月23日,法国戴高乐机场塌顶真相大白原因是设计缺陷。调查委员会负责人让·贝尔捷解释说,由于最初的安全准备不足,顶棚处于“濒临死亡”状态,虽然支撑了一段时间,但抵抗外力的能力却逐渐减弱。一系列结构上的问题使顶棚抗外力强度逐渐受损,最终导致结构坍塌。调查委员会还指出该建筑的一些缺陷:钢筋混凝土骨架不够或定位不好、缺乏当某一局部出现问题时向其他区域分散压力的可能性、连接水泥顶棚和下层玻璃的承梁抗击外力的能力不足等。调查报告分析认为,由于顶棚的抗外力强度不断减弱乃至消失,在某些因素的触发下,顶棚就会发生坍塌。人类历史上的几个典型关于“设计”的案例人类历史上的几个典型关于“设计”的案例案例二:名为“瓦萨号”的古战舰,始建于1625年,建成于1628年,至今已近400年。检索一下17世纪世界造船史,瓦萨号显然不是最大的船只。早它200年,大明王朝三保郑和的宝船,据传已有140多米长。但都是记载,没有实物呈现。就目前人类已经打捞上来、能够展示的、最大最完整最真实的古代战船而言,瓦萨号绝无仅有。一般说法,是因为瓦萨国王在原设计基础上,加了装备,负载过重,导致沉船。从技术层面上分析,肯定是结构上有问题。徒有豪华的躯体,追求大而全,没有稳固的结构和支撑,难以行稳致远。人类历史上的几个典型关于“设计”的案例人类历史上的几个典型关于“设计”的案例案例三:为什么协和式飞机的机头是下垂式的,其原因也是一样的,由于独特的三角翼以及苗条的机身,如果保持机头位置不变,飞行员的水平视线就会被机头挡住。所以,设计师们将协和式飞机的机头设计成可下垂式,可以在5到10度范围进行调节,以便飞机在起飞和降落时,飞行员获得良好的视野。在巡航时则转到正常状态。正是因为有了这样的设计,在所有有记录的飞行过程中,协和式飞机几乎没有发生过尾翼撞击地面的事故。人类历史上的几个典型关于“设计”的案例人类历史上的几个典型关于“设计”的案例案例四:染色体端粒(Telomere)和端粒酶(Telomerase)。人体的每个器官都由许多细胞组成,每个细胞的寿命都是有限的,必须分裂产生新的细胞来补充已死的细胞。当没有足够的新细胞补充已死的细胞时,器官就会逐渐衰竭,最终导致死亡。因此,单个细胞的寿命和细胞分裂的次数决定了人类的平均寿命。①人体单个细胞的寿命是有限的:细胞在生命过程中,DNA遗传物质的损伤和代谢过程中的废物积累到一定程度,会导致细胞的正常功能受损。这时为了防止发生癌变,细胞会自动启动被称为细胞凋亡(Apoptosis)的「程序性死亡(ProgrammedCellDeath)」。在大洪水之前,没有那么多污染和宇宙射线,单个细胞的寿命会比较长。人类历史上的几个典型关于“设计”的案例②细胞分裂次数是有限的:端粒(Telomere)是染色体末端的DNA重复碱基对,作用是保持染色体的完整性和控制细胞分裂周期,作用相当于鞋带两端的「帽子」。细胞每分裂一次,DNA就要复制一次,端粒就会缩短一点。一旦端粒消耗殆尽,细胞将会启动凋亡机制。端粒酶(Telomerase)可以把端粒修复延长,让端粒不会因细胞分裂而损耗,增加细胞分裂复制的次数。但在正常人体细胞中,端粒酶的活性受到相当严密的调控,只有在造血细胞、干细胞和生殖细胞中才具有活性。在大洪水之前,只要控制端粒的长度或端粒酶的活性,就可以延长人的寿命。人类历史上的几个典型关于“设计”的案例③人并不能通过激活端粒酶来达到长寿,因为端粒酶过多会导致癌症,癌细胞就是不会停止分裂的细胞;端粒酶太少会降低人体正常的再生能力,同样会导致癌症。只有造物主有能力精心调控端粒酶,掌管人的寿命。④正如正常功能受损的细胞会自动启动「程序性死亡」,以免成为不死的癌细胞,影响整个人体的生存。被罪恶污染的人也会启动「程序性死亡」,以免「恶人活千年」,这真是一个精妙的设计!设计的总结①设计=不断的作出决策。解决“Howtodo”,就需要不断的做出各种“设计决策”,在各类需求之间进行“折中”,使得最终设计性能达到最优。②设计=天才+创造力:每个工程师都希望做设计工作,因为这里有“创造性”——客户需求、业务要求和技术限制都在某个产品或系统中得到集中的体现。“设计”是最充分展现工程师个人水平的工作。设计的总结目录壹软件设计的基本概念贰软件设计的范畴与内容叁软件设计的质量肆软件架构的概念与范畴伍高可用设计软件设计的范畴与内容软件设计是从软件需求规格说明出发,形成软件的具体设计方案的过程也就是说在需求分析阶段明确软件是“做什么”的基础上,解决软件“怎么做”的问题。软件设计的基本目标是用比较抽象、概括的方式确定目标系统如何完成预定的任务,软件设计是确定系统的物理模型。软件设计是开发阶段最重要的步骤,是将需求准确地转化为完整的软件产品或系统的唯一途径。

软件设计的范畴与内容从技术观点上看,软件设计包括软件结构设计、数据设计、接口设计、过程设计:(1)软件结构设计定义软件系统各主要部件之间的关系;(2)数据设计将分析时创建的模型转化为数据结构的定义;(3)接口设计描述软件内部、软件和协作系统之间及软件与人之间如何通信;(4)过程设计则把系统结构部件交换为软件的过程性描述。软件设计的范畴与内容软件设计的范畴与内容1.软件系统结构设计从需求分析到软件设计之间的过渡过程称为软件架构(在本书中,我们将“软件体系结构”等同于“软件架构”)。只要软件架构设计好了,整个软件就不会出现坍塌的错误,即不会奔溃。架构设计就是需求分配,将满足需求的职责分配到组件上。软件架构为软件系统提供了一个结构、行为和属性的高级抽象,由构建的描述、构建的相互作用(连接件)、指导构件集成的模式以及这些模式的约束组成。软件架构不仅指定了系统的组织结构和拓扑结构,并且显示了系统需求和构件之间的对应关系,提供了一些设计决策的基本原理。软件结构解决好软件的复用、质量和维护问题,是研究软件架构的根本目的。1.软件系统结构设计软件架构设计包括提出架构模型,产生架构设计和进行架构设计评审等活动,是一个迭代的过程,架构设计主要关注软件组件的结构、属性和交互作用,并通过多种视图全面的描述特定系统的架构。软件架构能够在设计变更相对容易的阶段,考虑系统结构的可选方案,便于技术人员与非技术人员就软件设计进行交互,能够展现软件的结构、属性和内部交互关系。1.软件系统结构设计软件架构师项目干系人进行交流的手段,明确了对系统实现的约束条件,决定了开发和维护组织的组织结构,制约着系统的质量属性。软件架构使推理和控制的更改更加简单,有助于循序渐进的原型设计,可以作为培训的基础。软件架构是可传递和可用复用的模型,通过研究软件架构可能预测软件的质量。架构设计要求选择适合于需求的软件架构风格;如果是基于功能层次结构建立系统,其步骤是:采用某种设计方法,将系统按功能划分成模块的层次结构确定每个模块的功能建立与已确定的软件需求的对应关系确定模块间的调用关系确定模块间的接口评估模块划分的质量1.软件系统结构设计case:选择适合的软件架构风格2.接口设计接口设计包括用户界面、软件接口、硬件接口等。API是软件系统的核心,而软件系统的复杂度Complexity是大规模软件系统能否成功最重要的因素。但复杂度Complexity并非某一个单独的问题能完全败坏的,而是在系统设计尤其是API设计层面很多很多小的设计考量一点点叠加起来的也即JohnOusterhout说的Complexityisincremental。成功的系统不是有一些特别闪光的地方,而是设计时点点滴滴的努力积累起来的。接口是目前前后端交互(Rest),系统交互(RPC)最普遍的一种方式。一个好的接口,应该清晰易懂,职责明确,易于维护。反之,则会造成很多困扰。特别是OpenAPI,谁做谁知道。2.接口设计2.接口设计(1)编写文档文档与程序员之间有着一种非常奇妙的关系。一句话概括就是:“写之,痛之。用之,悔之”。怎么解释呢?就是:写的时候觉得很痛苦,不愿意写!用的时候呢,又后悔当初没有留下文档!可见文档是多么重要。以Rest接口为例,文档需要详细的记录请求参数,返回参数,每个字段的意思,是否必填,请求方法等。随着代码的更新,文档也应该及时更新。在很多开发者眼里,觉得写文档是一件浪费时间的事情,写代码才是正经事。随着工作经验的积累,愈发觉得文档的重要性,不但没浪费时间,反而还在节省时间。2.接口设计(2)符合最小原则这个原则其实是有点像设计模式中的迪米特法则(也称为:最小知识原则),这其中包含了两层意思:其一:在接口设计中,请求参数在保证功能的前提下:尽可能的减少参数,更不允许添加无用的参数。以Rest接口为例:一旦添加了无用的参数,在后续迭代过程中,就会遇到:弃之可惜,留之无用的尴尬局面。对于Client端也会造成困扰,还会浪费带宽。其二:接口粒度应该尽量小且保持单一职责,不要写大而全的接口。单一职责的好处不必多说,是一个老生常谈的问题。case:符合最小原则2.接口设计(3)新老兼容在接口设计中,新老接口的兼容是必须要考虑的,堪称事故多发地。常见事故如下所示:v1版本API上线发布后。随着需求变化,需要在v2接口版本中新增几个字段。上线后,发现使用v1版本的客户端业务中断。(v1版本没有兼容V2版本(新字段)导致)。v1版本API上线发布后。随着需求变化,需要删除某个接口。系统上线后,造成低版本客户端业务中断(没有兼容老的ClientVersion导致),等等问题。2.接口设计(3)新老兼容对于Rest接口,在这方面需要特别注意。因为客户端更新的周期是漫长的,以微信Android客户端为例。目前最新版本是:V7.0.6,但事实上:并不是每一个Android客户端的版本都是最新的V7.0.6,有可能是:V6.7.2,也有可能更低。对于微信这类国民软件而言,每一个版本影响的用户数都是极大的。如果不兼容,造成影响是巨大的。对于这种情况,API接口的更新:一般会采用新老版本并行使用进行过渡,并在大版本中进行逐步更新,直至没有ClientVersion进行使用时,API接口才能进行下线。2.接口设计(3)新老兼容同样的道理,放在内部的RPC接口也适用。一个常见的错误:在更新一个必须强制更新RPC接口时,采用了同步发布法。当时以为全部理清楚所有调用端,上线后,依然造成了生产事故,因为还有一个调用端没有在计划内。这样做的弊端包括但不限于:涉及应用多,(如果该接口为底层服务,那调用的上层应用都需要同步修改,一旦缺少一个,则会发布失败);发布时间长。事实上,我们应该尽量避免这种”同步发布法”。2.接口设计(4)及时移除不要的代码这个确实是一个容易忽略的细节,特别是一些策略性的代码及产品代码中,非常容易出现这样的现象。例如:某段代码一开始是有的,后面因为优化也好,因为调整也好,要去掉。但“自认为“后面还是会使用,则将其注释之。时而久之,这段注释的灰代码就此扎根,谁也不敢修改。代码中的坏味道就此慢慢的发酵,直至变臭。因此:无论从扩展方面,还是可维护方面考虑,都建议及时清除不必要的代码。2.接口设计(5)API设计准则:什么是好的APIa)提供清晰的思维模型:API是用于程序之间的交互,但是一个API如何被使用,以及API本身如何被维护,是依赖于维护者和使用者能够对该API有清晰的、一致的认识。这种状况实际上是不容易达到的。b)简单:“Makethingsassimpleaspossible,butnosimpler.”在实际的系统中,尤其是考虑到系统随着需求的增加不断的演化,我们绝大多数情况下见到的问题都是过于复杂的设计,而非过于简单,因此强调简单性一般是恰当的。API接口规范作业的流程2.接口设计确定软件涉及的文件系统的结构以及数据库的模式、子模式,进行数据完整性和安全性的设计确定输入、输出文件的详细的数据结构结合算法设计,确定算法所必需的逻辑数据结构及其操作确定对逻辑数据结构所必需的那些操作的程序模块(软件包)限制和确定各个数据设计决策的影响范围确定其详细的数据结构和使用规则数据的一致性、冗余性设计3.数据设计case:数据设计的过程3.数据设计早期的数据设计是以数据库设计为核心的设计过程;先理需求,再设计数据库,后开发;当系统规模小、团队人员小时,这种方式能有效推动项目的上线,不会存在较大的问题;但是当系统规模大、团队成员多时,会给整个项目带来风险。目前的主流做法是数据架构设计,为应用架构设计提供数据框架支撑,为应用数据资源采集、存储、处理和交换提供建设性依据(详见“数据架构设计”)。过程设计阶段的根本目标是经过这个阶段的设计工作得出对目标系统的精确描述,从而在编码阶段可以把这个描述直接翻译成用某种程序设计语言书写的程序。详细设计阶段的任务还不是具体地编写程序而是要设计出程序的“蓝图”,以后程序员将根据这个蓝图写出实际的程序代码。4.过程设计确定软件各个组成部分内的算法以及各部分的内部数据组织选定某种过程的表达形式来描述各种算法。进行详细设计的评审4.过程设计case:过程设计5.软件设计的两大阶段根据用信息域表示的软件需求以及功能和性能需求分析,软件设计阶段的目标有软件系统结构设计、接口设计、数据设计和过程设计,这是从技术的观点出发得到的,如前所述。从工程管理的角度来看,软件设计分两步完,即概要设计和详细设计,这也就是软件设计的任务。–概要设计:也称为高层设计,将软件需求转化为数据结构和软件的系统结构。例如,如果采用结构化设计,则将从宏观的角度将软件划分成各个组成模块,并确定模块的功能及模块之间的调用关系。–详细设计:即过程设计,通过对结构表示进行细化,得到软件的详细的数据结构和算法。同样的,如果采用结构化设计,则详细设计的任务就是为每个模块进行设计。5.软件设计的两大阶段目录壹软件设计的基本概念贰软件设计的范畴与内容叁软件设计的质量肆软件架构的概念与范畴伍高可用设计软件设计的质量在一个项目/迭代中,范围(包括质量)、进度、成本始终围绕着我们,我们必须作出平衡,达成目标,在软件项目中,特别是敏捷开发过程中,我们建议一次做成,什么叫一次做成就是软件设计到位,能够考虑复用和扩展性,等于说需要有一定的设计(前瞻性),当然如果你还做不到,那就慢慢朝着这个方向去做。作为一名开发人员,我们必须明白,什么才是优秀的软件设计。1.代码复用无论是开发哪种软件产品,成本和时间都是最重要的。较少的开发时间意味着可以比竞争对手更早进入市场,尤其在互联网时代。较低的开发成本意味着能够留出更多的营销资金,覆盖更广泛的潜在客户。其中,代码复用是减少开发成本最常用的方式之一,其目的非常明显,即:与其反复从头开发,不如在新对象中重用已有的代码。这个想法表面看起来很棒,但实际上要让已有的代码在全新的代码中工作,还是需要付出额外努力的。组件间紧密的耦合、对具体类而非接口的依赖和硬编码的行为都会降低代码的灵活性,使得复用这些代码变得更加困难。使用设计模式是增加软件组件灵活性并使其易于复用的方式之一。这可能也会让组件变得更加复杂,掌握不好,反而会适得其反。1.代码复用一般情况下,复用可以分为三个层次:在最底层,可以复用类、类库、容器。框架位于最高层。它们能帮助你精简自己的设计,可以明确解决问题所需的抽象概念,然后用类来表示这些概念并定义其关系。例如,我们很多人在用的Spring框架,其中定义了不少注解,创建对象被Spring接管,“你想要什么类,你不要自己创建,告诉我,我会给你”。还有一个中间层次。这是我们运用设计模式的地方。设计模式比框架更小且更抽象。它们实际上是对一组类的关系及其互动方式的描述。当你从类转向模式,并最终到达框架的过程中,复用程度会不断增加。case:代码复用的三个层次2.扩展性在VUCA时代(乌卡时代volatile,uncertain,complex,ambiguous。正处于一个易变性、不确定性、复杂性、模糊性的世界里),变化越来越多,在开发过程中,需求的变化是程序员经常需要面对的事情,一般我们都不建议变但是敏捷提倡变化,互联网行业尤其如此,一个小的变化,也许能带来极大的友好流量。每个软件开发者都经历过许多相似的故事,导致它们发生的原因也不少。首先,在完成了第一版的程序后,我们就应该做好了从头开始优化重写代码的准备,因为现在你已经能在很多方面更好的理解问题了,同时在专业水平上也有所提高,所以之前的代码现在看上去可能会显得很糟糕。2.扩展性其次,可能是在你掌控之外的某些事情发生了变化,这也是导致许多开发团队转变最初想法的原因。比如,早前流行的Flash应用,现在主流浏览器逐步不再支持,每位在网络应用中使用Flash的开发者都必须重新开发,不然很多功能会受到影响,这些已经超出了你能掌控的范围。最后,是业务需求的变化,你的客户用得好好地,但是他们的业务发生变化,突然提出需要在哪些点做一些改动,你不得不对着自己的代码进行完善修改。在软件设计时,有经验的开发者都会尽量选择支持未来任何可能变更的方式,做好扩展性,在软件架构方面支持架构演进。目录壹软件设计的基本概念贰软件设计的范畴与内容叁软件设计的质量肆软件架构的概念与范畴伍高可用设计软件设计的过程陈蕃是东汉时期的著名学者,字仲举,汝南郡平舆人。他的祖父曾任河东太守。不过到了陈蕃一辈,家道中落,不再名显乡里。陈蕃15岁时,曾经独处一个庭院习读诗书。一天,他父亲的一位老朋友薛勤来看他,看到院里杂草丛生,秽物满地,就对陈蕃说:“孩子,为什么不把屋子收拾干净来招待宾客?”陈蕃当即回答:“大丈夫处世,应当以扫除天下为己任,又怎么能打扫一间屋子呢!”这个回答让薛勤暗自吃惊,知道这人虽然年少却胸怀大志。但感悟之余,不免劝道:“一间屋子都不愿意打扫,又怎么能扫天下?”陈蕃一听,脸红了,马上就打扫房屋,招待客人。软件设计的过程如果把“陈蕃扫屋”的故事放到软件设计过程来看的话“孺子何不洒扫以待宾客”是需求分析;“大丈夫处世,当扫除天下,安事一室乎”对应于概要设计;“一屋不扫何以扫天下”就是详细设计了。软件设计的过程你早已接触过的“架构”在基于Web的架构出现之前,我们或多或少都接触到过各种“架构”,我们可以从其中找到软件架构的“影子”。“超市的多个收银台,顾客排长队”的需求可以理解为“服务器并发处理的性能和容量”;“十字路口的车辆等待转弯”的需求就像是“通过缓存cache技术来提高交通吞吐率”。在技术上,有分层结构、构件化、服务化、标准化等;也有缓存、分离/松散耦合、队列、复制、冗余、代理等技术;还有C/S、B/S、负载平衡等,这些都是与架构设计相关的课题。如何用它们解决具体软件问题,在博弈中寻求平衡(折中),就是软件架构所关注的问题。架构定义虽然新的架构层出不穷,但所遵循的基本原理都是相通的。那到底什么是“架构”?词典的定义:–Theartandscienceofdesigninganderectingbuildings(建筑学:设计和建造建筑物的艺术与科学);–Astyleandmethodofdesignandconstruction(设计及构造的方式和方法);–Orderlyarrangementofparts;structure(部件的有序安排;结构);–Theoveralldesignorstructureofacomputersystem,includingthehardwareandthesoftwarerequiredtorunit,especiallytheinternalstructureofthemicroprocessor(计算机系统的总体设计或结构,包括其硬件和支持硬件运行的软件,尤其是微处理器内部的结构)。架构定义软件架构的概念起源于建筑学的“架构”,意思是如何使用基本的建筑模块构造一座完整的建筑。这包含两个因素基本的建筑模块:砖、瓦、灰、沙、石、预制梁、柱、屋面板;建筑模块之间的粘接关系:如何把这些“砖、瓦、灰、沙、石、预制梁、柱、屋面板”有机的组合起来形成整体建筑。架构定义架构定义另一方面,计算机硬件系统的“架构”的意思是如何将设备组装起来形成完整的计算机硬件系统。这也包含两个因素:基本的硬件模块:控制器、运算器、内存储器、外存储器、输入设备、输出设备;硬件模块之间的连接关系:总线。计算机架构的风格有:以存储程序原理为基础的冯·诺依曼结构、存储系统的层次结构、并行处理机结构等等。架构定义我们得到“架构”的共性:一组基本的构成要素——构件;这些要素之间的连接关系——连接件;这些要素连接之后形成的拓扑结构——物理分布;作用于这些要素或连接关系上的限制条件——约束;质量——性能。因此,软件架构(SoftwareArchitecture,SA)的定义是:–提供了一个结构、行为和属性的高级抽象;–从一个较高的层次来考虑组成系统的构件、构件之间的连接,以及由构件与构件交互形成的拓扑结构;–这些要素应该满足一定的限制,遵循一定的设计规则,能够在一定的环境下进行演化;–反映系统开发中具有重要影响的设计决策,便于各种人员的交流,反映多种关注,据此开发的系统能完成系统既定的功能和性能需求。架构定义架构=构件+连接件+拓扑结构+约束+质量Architecture=Components+Connectors+Topology+Constraints+Performancecase:架构定义架构定义为什么要重视“软件架构”的设计?随着软件系统规模越来越大、越来越复杂;用户需求越来越复杂,变化越来越频繁;对软件质量(功能性/非功能性)的要求越来越高;如何将成百上千个功能组合起来,满足用户质量需求,变得越来越困难。此时,整个系统的结构和规格说明显得越来越重要。很多质量需求主要体现在架构中而非功能模块内部的实现中。结论:对于大规模的复杂软件系统来说,对总体的系统结构设计和规格说明比起对计算的算法和数据结构的选择已经变得明显重要得多。架构定义如果从建筑架构看起,建筑架构要回答的基本问题是:–基本的建筑单元都有哪些?–有哪些实用、美观、强度、造价合理、可复用的大粒度建筑单元,使建造出来的建筑更能满足用户的需求?–建筑模块怎样搭配才合理?–有哪些典型的建筑风格?–每种典型建筑(医院、工厂、旅馆)的典型结构是什么样子?需要什么样的构件?–如何绘制建筑架构的图纸?如何根据图纸进行质量评估?–如何快速节省的将图纸变为实物(即施工过程)?–建筑完成之后,如何对其进行恰当程度的修改?重要模块有了更改后,如何保证整栋建筑质量不受影响?架构定义由此,软件架构要回答的基本问题:–软件的基本构造单元是什么?–这些构造单元之间如何连接?–最终形成何种样式的拓扑结构?–每个典型应用领域的典型架构是什么样子?–如何进行软件架构的设计与实现?–如果对已经存在的软件架构进行修改?–使用何种工具来支持软件架构的设计?–如果对软件的架构进行描述,并据此进行分析和验证?软件架构的目标与作用软件架构的主要目标是建立一个一致的系统及其视图集,并表达为最终用户和软件设计者需要的结构形式,支持用户和设计者之间的交流与理解。软件架构作为一种“桥梁”,主要作用是:–交流的手段:在软件设计者、最终用户之间方便的交流;–可传递的、可复用的模型:对一些经过实现证明的架构进行复用,从而提高设计的效率和可靠性,降低设计的复杂度。–早期决策的体现:全面表达和深刻理解系统的高层次关系,使设计者在复杂的、矛盾的需求面前作出正确的选择;正确的架构是系统成功的关键,错误选择会造成灾难性后果。架构设计的典型质量属性质量属性分为6种:可用性、可修改性、性能、安全性、可测试性、易用性。其他的质量属性一般可纳入这几个属性中(在其他文献中为了强调常单列出来)例如,可扩充性可归入可修改性中(修改系统容量),可移植性也可以作为平台的可修改性来获得。对于未能纳入的其他质量属性,可以用下面的方法进行研究。如何描述质量属性需求呢?采用质量属性场景作为一种描述规范,它由以下6个部分组成–刺激源:生成该刺激的实体(人、计算机系统或其他激励器);–刺激:刺激到达系统时可能产生的影响(即需要考虑和关注的情况);–环境:该刺激在某条件内发生。如系统可能正处于过载情况;–制品:系统中受刺激的部分(某个制品被刺激);–响应:刺激到达后所采取的行动;–响应度量:当响应发生时,应能够以某种方式对应其度量,用于对是否满足需求的测试。如何描述质量属性需求呢?需要将一般的质量属性场景(一般场景)与具体的质量属性场景(具体场景)区别开来,前者是指独立于具体系统、适合于任何系统的一般性场景;而后者是指适合于正在考虑的某个特定系统的场景,具体场景通常是指从一般场景中抽取特定的、面向具体系统的内容。下面我们为每个质量属性提供一张表,该表中给出了质量属性场景每部分的一些可能取值,整体上形成一个一般场景的表格描述。在实际应用时,根据系统的具体情况,从该表中选取适当的值,就能变成具体场景(可读性强、可应用),可以把具体场景的集合作为系统的质量属性需求。(1)可用性及其实现战术(2)可修改性及其实现战术(3)性能及其实现战术(4)安全性及其实现战术(5)可测试性及其实现战术(6)易用性及其实现战术目录壹软件设计的基本概念贰软件设计的范畴与内容叁软件设计的质量肆软件架构的概念与范畴伍高可用设计高可用设计一提起高可用设计,很多同学立刻就会想到“冗余设计”、“故障转移”等关键词。确实,在大部分与高可用相关的描述里,这两个词往往会被重点强调。所谓“冗余设计”,是指要通过集群来替代单点服务,做好冗余备份。单点架构是高可用的大敌“把鸡蛋放在不同的篮子里”是高可用最朴实、最有效的设计思路之一;“故障转移”则是为了缩短故障时间,保证故障发生时,业务可以快速恢复。解剖高可用设计粗略地说,想做好架构设计第一步是将一个IT系统从应用层级至底层基础设施,全部拆解为一个个应用模块,我们也可以称之为“元素”或“组件”;第二步是保证各个模块间不能孤立存在,还要做好充分的协作,协作通过应用模块对外暴露的“服务”来承载,我们也可以称之为“连接”。所以说,应用模块和服务,或者叫做元素和连接,共同组成了所谓的架构。那么,要实现架构的高可用就意味着实现所有元素、连接的高可用。解剖高可用设计至此,其实我们已经得出了一点非常重要的认知,再重复一遍:真正的高可用是指实现所有元素、所有连接的高可用。只要一个元素或一个连接没有做高可用设计,都意味着风险的存在。更准确地说,所谓高可用,是要保证“业务的连续性”,即在用户眼里,业务永远是正常(或基本正常)对外提供服务的。做好决策,在很多情况下,并不意味着风险就消失了——风险始终存在。解剖高可用设计根据墨菲定律,如果事情有变坏的可能,无论概率有多小,它一定会发生。那么假设你我就是企业架构的总负责人,现在要保证企业整体业务的连续性,应该怎么办呢?有一个很通用的办法,叫做“冗余设计”。所谓“集群”、“分布式”,这些名词大体上都是在描绘“冗余设计”的概念。但冗余设计也不是万能的,它只能解决底层物理机器,也就是某一个实例的不可用问题。如果是代码逻辑出现了问题,冗余设计就失效了——一个恶性Bug在生产环境爆发,后果是所有集群都会遭殃。解剖高可用设计没钱做100%的高可用设计,又想尽量提供系统的抗风险能力。作为架构负责人,应该怎么办呢?第一个解决方案是:在风险爆发、系统出现问题的情况下,对外提供“降级服务”。也就是说,当团队没有时间去设计、测试并确保当前组件高可用时,如果因为未知原因,导致组件出现故障,我们需要提供一个逻辑相对简单,并且一定可用的服务替代原来的服务实现,实现服务对外的高可用。可这就是“降级服务”,实打实的高可用保障手段。在用户眼里,业务是连续的,只是可靠性降低了。case:降级服务解剖高可用设计其实对于架构师而言,高可用和高可靠应该是两个不同的概念,在最理想的情况下,我们既保证高可用,也保证高可靠;但出现问题时,我们优先保证高可用,其次保证高可靠。这是另一点关键认知。其实在不同领域里,有很多类似的做法。比如在流媒体领域,当用户观看直播出现严重卡顿时,很多企业的第一反应不是查服务器Log,而是为用户自动降码率。因为比起画质降低,卡的看不了显然会让用户更痛苦。如果“降级服务”还解决不了问题,应该怎么办?答案是提供“熔断服务”,让出现Bug的模块从系统中“熔断”,虽然用户会看到物流系统报错,但整个业务依然是正常响应的,不会被一个系统的Bug拖死。解剖高可用设计现在我们总结一下:高可用意味着对系统全部元素、连接都进行高可用设计,在物理实例层面主要表现为冗余和集群设计,在代码逻辑层面,方法则多种多样。当你的资源和精力不足以实现全链路高可用时,提供“降级服务”和“熔断服务”,优先保证高可用,其次保证高可靠。企业里面有些核心服务是不能降级的,对于这类服务,就一定要通过研发流程管理,确保服务的高可用、

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论