敏捷软件开发_设计原则<三>
敏捷软件开发_设计原则
单一职责原则(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 这本书的实例非常好,给了我非常多的启发.主要讲了两个实例,咖啡机和薪水支付实例,咖啡机实例比较简单并没有用什么设计模式,薪水支付实例用了很多设计模式,包括后面的打包等. 咖啡机实 ...
- 敏捷软件开发_实例2<四>
敏捷软件开发_实例2 上一章中对薪水支付案例的用例和类做了详细的阐述,在本篇会介绍薪水支付案例包的划分和数据库,UI的设计. 包的划分 一个错误包的划分 为什么这个包是错误的: 如果对classifi ...
- 敏捷软件开发_UML<一>
敏捷软件开发_UML 所看书籍是:敏捷软件开发_原则.模式与实践_C#版(美)马丁著,这本书写的非常棒,感谢作者.该归纳总结的过程按照我读的顺序写. UML 在建造桥梁,零件,自动化设备之前需要建 ...
- 敏捷软件开发:原则、模式与实践——第14章 使用UML
第14章 使用UML 在探索UML的细节之前,我们应该先讲讲何时以及为何使用它.UML的误用和滥用已经对软件项目造成了太多的危害. 14.1 为什么建模 建模就是为了弄清楚某些东西是否可行.当模型比要 ...
- 敏捷软件开发:原则、模式与实践——第12章 ISP:接口隔离原则
第12章 ISP:接口隔离原则 不应该强迫客户程序依赖并未使用的方法. 这个原则用来处理“胖”接口所存在的缺点.如果类的接口不是内敛的,就表示该类具有“胖”接口.换句话说,类的“胖”接口可以分解成多组 ...
- 敏捷软件开发:原则、模式与实践——第10章 LSP:Liskov替换原则
第10章 LSP:Liskov替换原则 Liskov替换原则:子类型(subtype)必须能够替换掉它们的基类型(base type). 10.1 违反LSP的情形 10.1.1 简单例子 对L ...
- 敏捷软件开发:原则、模式与实践——第8章 SRP:单一职责原则
第8章 SRP:单一职责原则 一个类应该只有一个发生变化的原因. 8.1 定义职责 在SRP中我们把职责定义为变化的原因.如果你想到多于一个的动机去改变一个类,那么这个类就具有多于一个的职责.同时,我 ...
- 【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 ...
- 敏捷软件开发——第8章 SRP:单一职责原则
第8章 SRP:单一职责原则 一个类应该只有一个发生变化的原因. 8.1 定义职责 在SRP中我们把职责定义为变化的原因.如果你想到多于一个的动机去改变一个类,那么这个类就具有多于一个的职责.同时,我 ...
随机推荐
- mkdir函数 (创建文件夹函数)
mkdir函数 #include <stdio.h> int main(){ mkdir("C:\\Users\\admin\\desktop\\test"); ; }
- mysql分布式
一,复制,对数据进行备份,实现搞可用,提高吞吐量,实现高性能. 1,主从架构 2,多主架构 3,主主从从 4,主备 (实际用得多) 二,分片/分库分表 () 1,垂直拆分 1,垂直分表 2,垂直分库 ...
- ASP.NET Core 2.2 WebApi 系列【八】统一返回格式(返回值、模型验证、异常)
现阶段,基本上都是前后端分离项目,这样一来,就需要前后端配合,没有统一返回格式,那么对接起来会很麻烦,浪费时间.我们需要把所有接口及异常错误信息都返回一定的Json格式,有利于前端处理,从而提高了工作 ...
- 在Python中反向遍历序列(列表、字符串、元组等)的五种方式
1. reversed() a = [1, 2, 3, 4] for i in reversed(a): print(i) 2. range(len(a)-1, -1, -1) a = [1, 2, ...
- Assign a Custom Image 设置自定义图标
In this lesson, you will learn how to associate a business class with a custom image. This image wil ...
- .Net Core MVC中过滤器简介
在.Net Framework MVC 中有四种过滤器,授权过滤器(Authorize).Action 过滤器.结果过滤器(Result).异常过滤器(Exception)四种过滤器.在.Net Co ...
- 利用jquery实现前端同步请求---判断姓名是否为空并设置事件
<%@ page contentType="text/html;charset=UTF-8" language="java" %><html& ...
- ES6-字符串模板
es6字符串模板 // es5 let ananiah = "大诶呀"; let blog = "我要忘了你的样子"+ ananiah; console.log ...
- Django使用xadmin集成富文本编辑器Ueditor(方法二)
一.xadmin的安装与配置1.安装xadmin,其中第一种在python3中安装不成功,推荐第二种或者第三种 方式一:pip install xadmin 方式二:pip install git+g ...
- HTML Rendering Error
刚下载的markdown弹窗提示html渲染错误 去官网 http://markdownpad.com/faq.html#livepreview-directx 页面搜索 This view h ...