敏捷软件开发_设计原则<三>
敏捷软件开发_设计原则
单一职责原则(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中我们把职责定义为变化的原因.如果你想到多于一个的动机去改变一个类,那么这个类就具有多于一个的职责.同时,我 ...
随机推荐
- 普通的maven项目,如何打成一个fat jar(包括了全部依赖jar包)?
1.前言 用过spring boot的同学肯定知道,现在web项目可以直接打成jar包运行,相当方便. 那么普通项目如何配置(非spring boot),才能打成一个类似的jar包呢? 2.解决方案: ...
- C++ 课程设计——电梯调度系统
这是我在本学期C++课程最后的课程设计报告,源代码将会上传到GitHub上. 一.背景 随着经济的不断发展,越来越多的摩天大楼拔地而起,而电梯作为高层建筑物种的运送人员货物的设备也越来越被广泛使用.电 ...
- 可能是最详细的UMD模块入门指南
学习UMD 介绍 这个仓库记录了一些关于javascript UMD模块规范的demo,对我学习UMD规范有了很大帮助,希望也能帮助到你. 回顾 之前也写了几篇关于javascript模块的博客,链接 ...
- zabbix 分布式监控及优化
1..zabbix分布式监控,模拟多机房实现监控? 1.有多机房时,需要用到proxy 1.网络不通 2.网络延迟 2.当监控的主机较多时,也可以用proxy来缓解压力 1.安装proxy [root ...
- SSM框架之Mybatis(7)延迟加载、缓存及注解
Mybatis(7)延迟加载.缓存及注解 1.延迟加载 延迟加载: 就是在需要用到数据时才进行加载,不需要用到数据时就不加载数据.延迟加载也称懒加载. **好处:**先从单表查询,需要时再从关联表去关 ...
- 松软科技前端课堂:JavaScript 对象
真实生活中的对象.属性和方法 在真实生活中,汽车是一个对象. 汽车有诸如车重和颜色等属性,也有诸如启动和停止的方法: 对象 属性 方法 car.name = porsche car.model = ...
- Dynamics CRM命令栏定制基础知识及手动编辑customization.xml实例
关注本人微信和易信公众号: 微软动态CRM专家罗勇 ,回复166或者20151028可方便获取本文,同时可以在第一时间得到我发布的最新的博文信息,follow me! 前面的博文:Dynamics C ...
- swift字符串截取实例
截取字符串 let deviceStr = deviceInfoLabel.attributedText?.string var device = "" if let len : ...
- iOS常用算法之单链表查找倒数第n个节点(图解)
拿到题目, 首先要先了解链表数据结构, 如下图: 常规思路: 利用数组, 遍历整个单链表, 将每个节点装入数组中, 最终拿到数组根据索引(数组长度-1-n)就得到了倒数第n个元素, 这里要注意从数组中 ...
- PHP 部分语法(一)
PHP: PHP 是一种创建动态交互性站点的强有力的服务器端脚本语言,它以 <?php 开始,并以 ?> 结束: 它还是一门弱类型语言,类型不需显式声明 变量: PHP 没有声明变量的命令 ...