敏捷软件开发_设计原则

单一职责原则(single responsibilities principle,SRP)

  • 原理:一个类应该只有一个变化
  • 分离职责:如果不耦合的职责那么很简单,如果两个职责耦合,将两个职责抽象为接口,通过继承两个接口将依赖关系抽离处理啊

开放封闭原则(open close principle,OCP)

  • 软件实体(类,模块,函数等)应该是可以扩展的,但是不可修改
  • 对扩展开放:当需求改变时,对模块可以扩展。
  • 对修改封闭:对模块进行扩展时,不必改动模块的源代码或则二进制代码,
  • 仅仅抽象出容易变化的部分。

里氏替换原则(liskov substitution principle,LSP)

  • 子类型必须能够替换掉它的基类型。

依赖倒置原则(dependence inversion principle,DIP)

  • 高层模块不应该依赖于底层模块,二者都应该依赖抽象
  • 抽象不应该依赖细节,细节应该依赖抽象

为什么叫倒置,在传统软件开发中,总倾向于创建一些高层模块依赖底层模块,策略依赖细节的软件结构。一个良好的面向对象程序,对传统设计结构而言就被倒置了。

其实就是都依赖接口编程,高层依赖接口,细节依赖接口,这样模块的改动不会影响其他模块。比较好的模块设计:

模块和模块间的依赖都是依赖接口。

  • 倒置不仅仅是依赖关系的倒置,也是接口所有权的倒置,通常会认为工具库应该拥有自己的接口,但其实应该是客户拥有接口,而它们的服务者应该是接口的派生。著名的 holly wood原则:“Don't call us, we'll call you”不要调用我们,我们会调用你,低层模块实现在高层模块中声明并被高层模块调用的接口

  • 程序所有的依赖关系都应该终止与抽象
  • 任何变量都不应该持有一个指向具体类的引用
  • 任何类都不应该从具体类派生
  • 任何方法都不应该重写它的任何基类中已经实现的方法。

接口隔离原则(interface segregation principle,ISP)

接口会被污染:

当借口的职责不再单一时,接口就很容易受到污染。

一个常见的例子:一个门,可能是关着也可能是开着,而且门类知道只是是开着还是关着。

常见的接口设计,现在需要实现自动报警,当门开着超过一定的时间就进行报警。常见的方法是关联timer类,实现报警。

这种方案就造成了接口污染,所有的门都必须依赖timeclient,同时还会出现门检测到时间超时,还未报警时,门关闭了,然后又被打开了,门变成了错误的报警

通过增加一个报警id,来区别每一次报警和客户端。

  • 接口隔离原则:不应该强迫客户程序依赖并未使用的方法。

隔离接口

  • 通过适配器原则,实现timer类对door类的引用隔离doorclient.这样仅仅增加了一个类,而将引用关系倒置。

创建一个派生自timer的timerclient对象,并把该对象请求委托给timerdoor。

这样就实现了timer和door的隔离,即使对timer进行更改也不会影响到door。timerdoor也不需要和timerclient一样的接口,

  • 另一种方法是使用timerdoor来多重继承,door和timerclient,

这种方案没有多余的开销,只有当doortimeradapter对象所做的转换是必须的时候或则不同的时候需要不同的转换的时候,才需要使用适配器方法。

例子:

AMT的一个例子,输出信息要转换成不同的语言,输出信息要显示在桌面上,


把不同的事务处理方法封装在transaction上,这样每个事务的修改都会造成UI的修改,如果把接口分解成不通的单独接口,就可以避免

打包原则

大型系统的设计非常依赖于好的组件设计,这样每个团队只要关注于单个组件而不需要关注整个系统。

但类经常会和其他类发生依赖关系,这些依赖关系也会跨越组件的边界。

  • 在向组件中分配类时应该依据什么原则
  • 应该使用什么设计原则来管理组件之间的关系
  • 组件的设计应该先于类(自顶而下),还是设计应该先于组件(自底而上)
  • 组件的实体以什么方式存在
  • 组件创建好后,用于何种目的

组件和组件间的依赖关系:不能依赖具体类。只能是具体依赖抽象,抽象依赖抽象。这样就可以将影响将至最低。

前三个原则来指导如何将类划分到包中,后三个原则来管理包之间的耦合(稳定)。组件之间的耦合越稳定就越好

重用发布等价原则(reuse release equivalence principle,REP)

重用粒度就是发布粒度:一个组件的重用粒度和发布粒度一样大,重用的任何东西必须被同时发布和跟踪,

重用性必然是基于组件的,所以可重用的组件必须包含可重用的类,因至少某些组件应该由一组可重用的类组成

一个类中的组件要么都是可重用的,要么都是不可重用的。

共同重用原则(common reuse principle , crp)

一个组件中所有的类都应该是共同重用的,如果重用了组件中的一个类,那么就要重用组件中的所有类。

这个原则可以帮助我们确定哪些类应该在一个组件中,相互之间没有紧密联系的类不应该在同一个组件中。

共同封闭原则(common closure principle,ccp)

组件中所有的类对同一种性质的变化应该是共同封闭的,一个变化若对一个封闭的组件产生影响,则将对该组件中所有的类产生影响,而对其他组件不产生影响。类似于单一职责原则。

无环依赖原则

在组件的关系图中不允许存在环。

解除依赖环的方法:提取抽象接口,通过实现接口来替换关联。关联和实现的依赖关系相反。

稳定依赖原则

朝着稳定的方向进行依赖。

被依赖的越多,该组件就越不可能改动,则越稳定。

稳定性度量:

稳定抽象原则

组件的抽象程度与其稳定性。

中间连接线称为主序列。

到主序列的距离:

越为0 越好

有了度量和标准就让我们划分组件吧!!!

敏捷软件开发_设计原则<三>的更多相关文章

  1. 敏捷软件开发_实例1<二>

    敏捷软件开发_实例1 这本书的实例非常好,给了我非常多的启发.主要讲了两个实例,咖啡机和薪水支付实例,咖啡机实例比较简单并没有用什么设计模式,薪水支付实例用了很多设计模式,包括后面的打包等. 咖啡机实 ...

  2. 敏捷软件开发_实例2<四>

    敏捷软件开发_实例2 上一章中对薪水支付案例的用例和类做了详细的阐述,在本篇会介绍薪水支付案例包的划分和数据库,UI的设计. 包的划分 一个错误包的划分 为什么这个包是错误的: 如果对classifi ...

  3. 敏捷软件开发_UML<一>

    敏捷软件开发_UML  所看书籍是:敏捷软件开发_原则.模式与实践_C#版(美)马丁著,这本书写的非常棒,感谢作者.该归纳总结的过程按照我读的顺序写. UML  在建造桥梁,零件,自动化设备之前需要建 ...

  4. 敏捷软件开发:原则、模式与实践——第14章 使用UML

    第14章 使用UML 在探索UML的细节之前,我们应该先讲讲何时以及为何使用它.UML的误用和滥用已经对软件项目造成了太多的危害. 14.1 为什么建模 建模就是为了弄清楚某些东西是否可行.当模型比要 ...

  5. 敏捷软件开发:原则、模式与实践——第12章 ISP:接口隔离原则

    第12章 ISP:接口隔离原则 不应该强迫客户程序依赖并未使用的方法. 这个原则用来处理“胖”接口所存在的缺点.如果类的接口不是内敛的,就表示该类具有“胖”接口.换句话说,类的“胖”接口可以分解成多组 ...

  6. 敏捷软件开发:原则、模式与实践——第10章 LSP:Liskov替换原则

    第10章 LSP:Liskov替换原则    Liskov替换原则:子类型(subtype)必须能够替换掉它们的基类型(base type). 10.1 违反LSP的情形 10.1.1 简单例子 对L ...

  7. 敏捷软件开发:原则、模式与实践——第8章 SRP:单一职责原则

    第8章 SRP:单一职责原则 一个类应该只有一个发生变化的原因. 8.1 定义职责 在SRP中我们把职责定义为变化的原因.如果你想到多于一个的动机去改变一个类,那么这个类就具有多于一个的职责.同时,我 ...

  8. 【Scrum】-NO.40.EBook.1.Scrum.1.001-【敏捷软件开发:原则、模式与实践】- Scrum

    1.0.0 Summary Tittle:[Scrum]-NO.40.EBook.1.Scrum.1.001-[敏捷软件开发:原则.模式与实践]- Scrum Style:DesignPattern ...

  9. 敏捷软件开发——第8章 SRP:单一职责原则

    第8章 SRP:单一职责原则 一个类应该只有一个发生变化的原因. 8.1 定义职责 在SRP中我们把职责定义为变化的原因.如果你想到多于一个的动机去改变一个类,那么这个类就具有多于一个的职责.同时,我 ...

随机推荐

  1. go语言变量作用域

    Go 语言变量作用域 作用域为已声明标识符所表示的常量.类型.变量.函数或包在源代码中的作用范围. Go 语言中变量可以在三个地方声明: 函数内定义的变量称为局部变量 函数外定义的变量称为全局变量 函 ...

  2. ASP.NET Repeater与Button 以及viewState 和 hyperLink

    例如Repeater重复项 我们要在一个表里作删除以及修改 我们可以在Repeater中添加button控件前台代码:button有属性commandName 以及commandArgument 我们 ...

  3. 自学_数据库<三>

    数据库 数据库概述 DBMS(DataBase Management System,数据库管理系统)和数据库.平时谈到"数据库"可能有两种含义:MSSQLServer.Oracle ...

  4. zookeeper启动失败,但是状态显示已启动的原因

    今天在起zookeeper集群的时候,其他两台机子都能起起来,只有这一台机子起不起来: 对比了 这个路径下的 文件后发现多了一个这个文件 根据名字推测应该是放进程id.突然明白这个应该是上次非正常退出 ...

  5. json对象中的变量存在空格的取值办法

    写一个json对象,但需求需要是带空格的键,定义的话很容易定义,只需要双引号引起来即可,但取值的时候怎么取,直接写 会报错,所以就有了下边的办法 <el-form-item label=&quo ...

  6. 利用Azure虚拟机安装Dynamics 365 Customer Engagement之五:安装SQL Server

    我是微软Dynamics 365 & Power Platform方面的工程师罗勇,也是2015年7月到2018年6月连续三年Dynamics CRM/Business Solutions方面 ...

  7. wireshark和tcpdump抓包TCP乱序和重传怎么办?PCAP TCP排序工具分享

    点击上方↑↑↑蓝字[协议分析与还原]关注我们 " 介绍TCP排序方法,分享一个Windows版的TCP排序工具." 在分析协议的过程中,不可避免地需要抓包. 无论抓包条件如何优越, ...

  8. Playbook剧本初识

    目录 1.Playbook剧本初识 2.Playbook变量使用 3.Playbook变量注册 4.Playbook条件语句 5.Playbook循环语句 6.Playbook异常处理 7.Playb ...

  9. 43-安装 Docker Machine

    前面我们的实验环境中只有一个 docker host,所有的容器都是运行在这一个 host 上的.但在真正的环境中会有多个 host,容器在这些 host 中启动.运行.停止和销毁,相关容器会通过网络 ...

  10. java8-01-初识Lambda表达式

    为什么用 Lambda表达式          在java8之前  java语言 方法调用  无法将函数作为一个参数      也无法声明返回一个函数          对比 javaScript是典 ...