面向对象设计中的单一职责原则
面向对象设计中的单一职责原则
面向对象设计中的单一职责原则一个优良的系统设计,强调模块间保持低耦合、高内聚的关系,在面向对象设计中这条规则同样适用,所以面向对象的第一个设计原则就是:单一职责原则(SRP,Single Responsibility Principle)。如果一个类承担的职责过多,就等于把这些职责耦合在了一起。当其中一个职责变化时,可能影响其他职责的运作。
单一职责,强调的是职责的分离,在某种程度上对职责的理解,构成了不同类之间耦合关系的设计关键,因此单一职责原则或多或少成为设计过程中一个必须考虑的基础性原则。
在软件编程中,谁也不希望因为修改了一个功能导致其他的功能发生故障。而避免出现这一问题的方法便是遵循单一职责原则。虽然单一职责原则如此简单,并且被认为是常识,但是即便是经验丰富的程序员写出的程序,也会有违背这一原则的代码存在。为什么会出现这种现象呢?因为有职责扩散。所谓职责扩散,就是因为某种原因,职责P被分化为粒度更细的职责P1和P2。
一、遵循单一职责原的优点有:
1、可以降低类的复杂度,一个类只负责一项职责,其逻辑肯定要比负责多项职责简单的多;
2、提高类的可读性,提高系统的可维护性;
3、变更引起的风险降低,变更是必然的,如果单一职责原则遵守的好,当修改一个功能时,可以显著降低对其他功能的影响。
4、需要说明的一点是单一职责原则不只是面向对象编程思想所特有的,只要是模块化的程序设计,都适用单一职责原则。
二、关于单一职责原则,我们的建议是:
1、一个类只有一个引起它变化的原因,否则就应当考虑重构。
2、 SRP由引起变化的原因决定,而不由功能职责决定。虽然职责常常是引起变化的曲线,但是有时却未必,应该审时度势。
3、 测试驱动开发,有助于实现合理分离功能的设计。
4、 可以通过Facade模式或Proxy模式进行职责分离。
5、我们会自然地把职责结合在一起。如果能想到多于一个动机去改变一个类,那么这个类就具有多于一个的职责,就应该考虑类的职责分离。
6、接口一定做到单一职责,类的设计尽量做到只有一个原因引起变化。
7、分层架构模式实际上也体现了这一原则,它将整个系统按照职责的内聚性分为不同的层,层内的模块与类具有宏观的内聚性,它们关注的事情应该是一致的。例如,领域逻辑层就主要关注系统的业务逻辑与业务流程,而数据的持久化与访问则交由数据访问层来负责。
三、以订单的管理为例,我们在领域逻辑层中定义如下的类OrderManager
public class OrderManager { private IOrderRepository repository = RepositoryFactory.CreateOrderRepository(); public void Place(Order order) { if (order.IsValid()) { repository.Add(Order); } else { throw new InvalidOperationException("Order can't be placed. "); } } public void Cancel(Order order) { if (order.IsValid() && order.CanCancel(DateTime.Now)) { repository.Remove(Order); } else { throw new InvalidOperationException("Order can't be canceled. "); } } } public static class RepositoryFactory { public static IOrderRepository CreateOrderRepository() { return new OrderRepository(); } }
OrderManager类的实现体现了单一职责原则的思想。首先,OrderManager类中的Place()和Cancel()方法均属于订单管理的业务逻辑,与领域逻辑层关注的事情是一致的。在这两个方法的实现中,我们需要检验订单的正确性(检验订单是否包含了必要的信息,如联系人、联系地址与联系电话),以及判断当前时间是否在允许取消订单的时间范围内。虽然它们仍然属于订单处理的业务逻辑,但拥有这些检查信息的是Order对象,而不是OrderManager,即Order对象是检查订单的信息专家 。因此,IsValid()和CanCancel()方法应该被定义在Order类中。至于添加和移除订单的操作,虽然保证了下订单和取消订单的业务逻辑实现,但其实现却属于数据访问层的范畴,因而该职责被委派给了OrderRepository类 。至于RepositoryFactory类,则是负责创建OrderRepository对象的工厂类。
这些类的职责以及协作关系如图所示:
将数据访问的逻辑从领域对象中分离出去是有道理的,因为数据访问逻辑的变化方向与订单业务逻辑的变化方向是不一致的,引起职责发生变化的原因也不相同。这也是单一职责原则的核心思想。遵循该原则,就能够有效地分离对象的变与不变,将变化的职责以抽象的方式独立于原对象之外,原对象就更加稳定。我们对访问Order数据表的逻辑进行了封装与抽象,以隔离数据访问逻辑的变化,即使数据访问逻辑发生变化,它影响到的只是OrderRepository类而已。
- vue基础语法对象(浅析从面向对象思维理解Vue组件)
- python对象创建流程(Python3.5面向对象与继承图文实例详解)
- python内置函数一览表(Python面向对象程序设计构造函数和析构函数用法分析)
- python学生信息管理系统教程(学生信息管理系统Python面向对象版)
- php如何继承多个类(PHP面向对象程序设计子类扩展父类子类重新载入父类操作详解)
- php语言程序设计基础面向对象(PHP面向对象程序设计之对象的遍历操作示例)
- php面向对象编程代码(php面向对象程序设计入门教程)
- php面向对象教程理解(PHP面向对象程序设计之构造方法和析构方法详解)
- javascript对象添加方法(详解JavaScript面向对象实战之封装拖拽对象)
- python面向对象的介绍(Python面向对象思想与应用入门教程类与对象)
- php使用面向对象如何写好代码(PHP面向对象程序设计模拟一般面向对象语言中的方法重载overload示例)
- php对象和类(PHP面向对象程序设计内置标准类,普通数据类型转为对象类型示例)
- php面向对象3大特征(PHP面向对象程序设计重载overloading操作详解)
- python核心编程和python基础教程(从0开始的Python学习014面向对象编程推荐)
- 面向对象设计中的开放封闭原则
- php面向对象运用场景(PHP面向对象类型约束用法分析)
- 十二星座爱情支配欲指数(十二星座爱情支配欲指数)
- 虐待儿童是发泄支配欲的愚蠢行为(虐待儿童是发泄支配欲的愚蠢行为)
- 你或许不知道你隐藏的支配欲望(你或许不知道你隐藏的支配欲望)
- 把宽体丰田86卖了,换成7.5代高尔夫GTI玩起姿态与性能并存的改装(把宽体丰田86卖了)
- 大众推出了第五代高尔夫GT(大众推出了第五代高尔夫GT)
- 换代在即,现在是抄底 7.5代 高尔夫的最佳时机吗(换代在即现在是抄底)
热门推荐
- tomcat环境配置教程(Tomcat服务器的安装配置图文教程推荐)
- css3支持多重背景吗(真正了解CSS3背景下的@font face规则)
- dedecms文章内容页调用自定义字段(DEDECMS教程:上/下一篇文章标题长度的截取方法)
- ubuntu内核升级指定版本(Ubuntu12.04建立内核树实现过程详解)
- thinkphp数据库使用(thinkphp3.2同时连接两个数据库的简单方法)
- h5页面快速制作方法(h5网页水印SDK的实现代码示例)
- php启用curl(php使用curl伪造浏览器访问操作示例)
- TortoiseSVN客户端更改用户名和密码
- python基础编程函数参数(详解Python 函数如何重载?)
- css3渐变背景教程(css3实现背景图片颜色修改的多种方式)
排行榜
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9