软件开发设计原则.docx_第1页
软件开发设计原则.docx_第2页
软件开发设计原则.docx_第3页
软件开发设计原则.docx_第4页
软件开发设计原则.docx_第5页
已阅读5页,还剩2页未读 继续免费阅读

下载本文档

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

文档简介

软件开发设计原则类图: 这幅图清晰地表达了六大设计原则,但仅限于它们叫什么名字而已,它们具体是什么意思呢?下面我将从原文、译文、理解、应用,这四个方面分别进行阐述。基本设计原则1、单一职责原则(Single Responsibility Principle - SRP)原文:There should never be more than one reason for a class to change。译文:永远不应该有多于一个原因来改变某个类。理解:对于一个类而言,应该仅有一个引起它变化的原因。说白了就是,不同的类具备不同的职责,各施其责。这就好比一个团队,大家分工协作,互不影响,各做各的事情。应用:当我们做系统设计时,如果发现有一个类拥有了两种的职责,那就问自己一个问题:可以将这个类分成两个类吗?如果真的有必要,那就分吧。千万不要让一个类干的事情太多!2、开放封闭原则(Open Closed Principle - OCP)原文:Software entities like classes, modules and functions should be open for extension but closed for modifications。译文:软件实体,如:类、模块与函数,对于扩展应该是开放的,但对于修改应该是封闭的。理解:简言之,对扩展开放,对修改封闭。换句话说,可以去扩展类,但不要去修改类。应用:当需求有改动,要修改代码了,此时您要做的是,尽量用继承或组合的方式来扩展类的功能,而不是直接修改类的代码。当然,如果能够确保对整体架构不会产生任何影响,那么也没必要搞得那么复杂了,直接改这个类吧。3、里氏替换原则(Liskov Substitution Principle - LSP)原文:Functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it。译文:使用基类的指针或引用的函数,必须是在不知情的情况下,能够使用派生类的对象。理解:父类能够替换子类,但子类不一定能替换父类。也就是说,在代码中可以将父类全部替换为子类,程序不会报错,也不会在运行时出现任何异常,但反过来却不一定成立。应用:在继承类时,务必重写(Override)父类中所有的方法,尤其需要注意父类的 protected 方法(它们往往是让您重写的),子类尽量不要暴露自己的 public 方法供外界调用。该原则由麻省理工学院的 Barbara Liskov 女士提出,她是美国第一位获取计算机博士学位的女性,曾经也获得过计算机图灵奖。4、最少知识原则(Least Knowledge Principle - LKP)原文:Only talk to you immediate friends。译文:只与你最直接的朋友交流。理解:尽量减少对象之间的交互,从而减小类之间的耦合。简言之,一定要做到:低耦合,高内聚。应用:在做系统设计时,不要让一个类依赖于太多的其他类,需尽量减小依赖关系,否则,您死都不知道自己怎么死的。该原则也称为“迪米特法则(Law of Demeter)”,由 Ian Holland 提出。这个人不太愿意和陌生人说话,只和他走得最近的朋友们交流。5、接口隔离原则(Interface Segregation Principle - ISP)原文:The dependency of one class to another one should depend on the smallest possible interface。译文:一个类与另一个类之间的依赖性,应该依赖于尽可能小的接口。理解:不要对外暴露没有实际意义的接口。也就是说,接口是给别人调用的,那就不要去为难别人了,尽可能保证接口的实用性吧。她好,我也好。应用:当需要对外暴露接口时,需要再三斟酌,如果真的没有必要对外提供的,就删了吧。一旦您提供了,就意味着,您将来要多做一件事情,何苦要给自己找事做呢。6、依赖倒置原则(Dependence Inversion Principle - DIP)原文:High level modules should not depends upon low level modules。 Both should depend upon abstractions。 Abstractions should not depend upon details。 Details should depend upon abstractions。译文:高层模块不应该依赖于低层模块,它们应该依赖于抽象。抽象不应该依赖于细节,细节应该依赖于抽象。理解:应该面向接口编程,不应该面向实现类编程。面向实现类编程,相当于就是论事,那是正向依赖(正常人思维);面向接口编程,相当于通过事物表象来看本质,那是反向依赖,即依赖倒置(程序员思维)。应用:并不是说,所有的类都要有一个对应的接口,而是说,如果有接口,那就尽量使用接口来编程吧。将以上六大原则的英文首字母拼在一起就是 SOLID(稳定的),所以也称之为 SOLID 原则。只有满足了这六大原则,才能设计出稳定的软件架构!但它们毕竟只是原则,只是四人帮给我们的建议,有些时候我们还是要学会灵活应变,千万不要生搬硬套,否则只会把简单问题复杂化,切记!补充设计原则1、组合/聚合复用原则(Composition/Aggregation Reuse Principle - CARP) 当要扩展类的功能时,优先考虑使用组合,而不是继承。这条原则在 23 种经典设计模式中频繁使用,如:代理模式、装饰模式、适配器模式等。可见江湖地位非常之高!2、无环依赖原则(Acyclic Dependencies Principle - ADP) 当 A 模块依赖于 B 模块,B 模块依赖于 C 模块,C 依赖于 A 模块,此时将出现循环依赖。在设计中应该避免这个问题,可通过引入“中介者模式”解决该问题。3、共同封装原则(Common Closure Principle - CCP) 应该将易变的类放在同一个包里,将变化隔离出来。该原则是“开放-封闭原则”的延生。4、共同重用原则(Common Reuse Principle - CRP) 如果重用了包中的一个类,那么也就相当于重用了包中的所有类,我们要尽可能减小包的大小。5、好莱坞原则(Hollywood Principle - HP) 好莱坞明星的经纪人一般都很忙,他们不想被打扰,往往会说:Dont call me, Ill call you。 翻译为:不要联系我,我会联系你。对应于软件设计而言,最著名的就是“控制反转”(或称为“依赖注入”),我们不需要在代码中主动的创建对象,而是由容器帮我们来创建并管理这些对象。其他设计原则1、不要重复你自己(Dont repeat yourself - DRY) 不要让重复的代码到处都是,要让它们足够的重用,所以要尽可能地封装。2、保持它简单与傻瓜(Keep it simple and stupid - KISS) 不要让系统变得复杂,界面简洁,功能实用,操作方便,要让它足够的简单,足够的傻瓜。3、高内聚与低耦合(High Cohesion and Low Coupling - HCLC) 模块内部需要做到内聚度高,模块之间需要做到耦合度低。4、惯例优于配置(Convention over Configuration - COC) 尽量让惯例来减少配置,这样才能提高开发效率,尽量做到“零配置”。很多开发框架都是这样做的。5、命令查询分离(Command Query Separation - CQS) 在定义接口时,要做到哪些是命令,哪些是查询,要将它们分离,而不要揉到一起。6、关注点分离(Separation of Concerns - SOC) 将一个复杂的问题分离为多个简单的问题,然后逐个解决这些简单的问题,那么这个复杂的问题就解决了。难就难在如何进行分离。7、契约式设计(Design by Contract - DBC) 模块或系统之间的交互,都是基于契约(接口或抽象)的,而不要依赖于具体实现。该原则建议我们要面向契约编程。8、你不需要它(You arent gonna need it - YAGNI) 不要一开始就把系统设计得非常复杂,不要陷入“过度设计”的深渊。应该让系统足够的简单,而却又不失扩展性,这是其中的难点。敏捷开发模式的修炼之道关于高内聚低耦合什么是耦合度 软件设计中通常用耦合度和内聚度作为衡量模块独立程度的标准。划分摸块的一个准则就是高内聚低耦合。 耦合度(Coupling)是对模块间关联程度的度量。耦合的强弱取决与模块间接口的复杂性、调用模块的方式以及通过界面传送数据的多少。 模块间的耦合度是指模块之间的依赖关系,包括控制关系、调用关系、数据传递关系。模块间联系越多,其耦合性越强,同时表明其独立性越差。降低模块间的耦合度能减少模块间的影响,防止对某一模块修改所引起的“牵一发动全身”的水波效应,保证系统设计顺利进行。 内聚和耦合密切相关,同其它模块存在强耦合关系的模块常意味这弱内聚,强内聚常意味着弱耦合。耦合度就是某模块(类)与其它模块(类)之间的关联、感知和依赖的程度,是衡量代码独立性的一个指标,也是软件工程设计及编码质量评价的一个标准。耦合的强度依赖于以下几个因素:(1)一个模块对另一个模块的调用;(2)一个模块向另一个模块传递的数据量;(3)一个模块施加到另一个模块的控制的多少;(4)模块之间接口的复杂程度。耦合按从强到弱的顺序可分为以下几种类型:非直接耦合:两模块间没有直接关系,之间的联系完全是通过主模块的控制和调用来实现的数据耦合:一个模块访问另一模块,彼此间通过简单数据参数来交换输入、输出信息。这里 的简单数据参数不同于控制参数、公共数据结构或外部变量。标记耦合:如一组模块通过参数表传递记录信息,就是标记耦合。这个记录是某一数据结构 的子结构,不是简单变量。 控制耦合:一个模块通过传递开关、标志、名字等控制信息,明显的控制选择另一模块的功 能。外部耦合:一组模块都访问同一全局简单变量而不是同一全局数据结构,而且不是通过参数 传递该全局变量的信息 公共耦合:一组模块都访问同一个公共数据环境。该公共数据环境可以是全局数据结构、共 享的通信区、内存的公共覆盖区等。 内容耦合:一个模块直接修改另一个模块的数据,或直接转入另一个模块内聚度是指内部各 元素之间联系的紧密程度,模块的内聚种类通常可分为7种,按其内聚度从低到高的次序依此为:偶然内聚、逻辑内聚、瞬时内聚、过程内聚、通信内聚、顺序内聚、功能内聚。二、为什么要低耦合 了解什么是耦合及耦合的分类后,我想大家对为什么要降低耦合度已经有一定的认识,并且多数开发人员也大概尝尽了高耦合带来的苦头。道理很简单,耦合度很高的情况下,维护代码时修改一个地方会牵连到很多地方,如果修改时没有理清这些耦合关系,那么带来的后果可能会是灾难性的,特别是对于需求变化较多以及多人协作开发维护的项目,修改一个地方会引起本来已经运行稳定的模块错误,严重时会导致恶性循环,问题永远改不完,开发和测试都在各种问题之间奔波劳累,最后导致项目延期,用户满意度降低,成本也增加了,这对用户和开发商影响都是很恶劣的,各种风险也就不言而喻了。 为了预防这些问题的发生,其中一个重要手段就是降低代码的耦合度。但也不可能有绝对的零耦合,比如基于J2EE编程那就必须和JDK耦合,而且高耦合也不是一无是处,如果在设计前期预料到某功能后期基本不用修改,那么即使高耦合了也关系不大。 但是,在还没有能力设计出基本不用修改的代码前,还得要求以低耦合为标准。那么怎样才能最大限度地降低耦合度呢?下面介绍降低耦合度的几种方法。三、降低耦合度的方法1、少使用类的继承,多用接口隐藏实现的细节。 java面向对象编程引入接口除了支持多态外, 隐藏实现细节也是其中一个目的。2、模块的功能化分尽可能的单一,道理也很简单,功能单一的模块供其它模块调用的机会就少。(其实这是高内聚的一种说法,高内聚低耦合一般同时出现,为了限制篇幅,我们将在以后的版期中讨论)。3、遵循一个定义只在一个地方出现。4、少使用全局变量。5、类属性和方法的声明少用public,多用private关键字,6、多用设计模式,比如采用MVC的设计模式就可以降低界面与业务逻辑的耦合度。7、尽量不用“硬编码”的方式写程序,同时也尽量避免直接用SQL语句操作数据库。8、最后当然就是避免直接操作或调用其它模块或类(内容耦合);如果模块间必须存在耦合,原则上尽量使用数据耦合,少用控制耦合,限制公共耦合的范围,避免使用内容耦合。内聚: 故名思议,表示内部间聚集、关联的长度,那么高内聚就是指要高度的聚集和关联。高内聚: 类与类之间的关系而定,高,意思是他们之间的关系要简单,明了,不要有很强的关系,不然,运行起来就会出问题。一个类的运行影响到其他的类。由于高内

温馨提示

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

评论

0/150

提交评论