面向对象设计中的单一职责原则
面向对象设计中的单一职责原则
面向对象设计中的单一职责原则一个优良的系统设计,强调模块间保持低耦合、高内聚的关系,在面向对象设计中这条规则同样适用,所以面向对象的第一个设计原则就是:单一职责原则(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面向对象基本思想(详解Python:面向对象编程)
- python中对象方法和顶级方法(Python3.5面向对象程序设计之类的继承和多态详解)
- python类继承和封装(Python面向对象程序设计类的封装与继承用法示例)
- php面向对象怎么调用属性(PHP面向对象程序设计__tostring和__invoke用法分析)
- python面向对象的介绍(Python面向对象思想与应用入门教程类与对象)
- php对象和类(PHP面向对象程序设计内置标准类,普通数据类型转为对象类型示例)
- php面向对象教程理解(PHP面向对象程序设计之构造方法和析构方法详解)
- php 面向对象与面向过程(php面向对象重点知识分享)
- php面向对象运用场景(PHP面向对象类型约束用法分析)
- python正则表达式该怎么学习(Python面向对象总结及类与正则表达式详解)
- php面向对象final怎么设置(PHP面向对象程序设计中的self、static、parent关键字用法分析)
- php面向对象编程代码(php面向对象程序设计入门教程)
- 面向对象设计中的开放封闭原则
- python支持面向对象的程序设计(Python面向对象程序设计之类的定义与继承简单示例)
- python面向对象实例教程(Python面向对象程序设计类的多态用法详解)
- 赵薇时胖时瘦 最近变美少女 原因在这里 躺着就变瘦(赵薇时胖时瘦最近变美)
- 学会这26种姿势,你就可以和兵哥哥切磋了(你就可以和兵哥哥切磋了)
- 吴彦祖陈冠希 恩怨 ,失去曾让他流泪的女友,终遇走过18年真爱(吴彦祖陈冠希恩怨)
- 痴情男神 吴彦祖 与妻子恋爱8年,结婚10年,家庭幸福美满(痴情男神吴彦祖)
- 成功破圈,小牛电动SQi强势开 跨(小牛电动SQi强势开)
- 挑战新国标电自天花板,九号机械师MMAX 110P深度体验(挑战新国标电自天花板)
热门推荐
- mysql中date_format日期格式化
- 如何在mysql中批量插入数据(MySQL如何快速批量插入1000w条数据)
- sql server2008自动备份数据(SQL Server数据库定时自动备份)
- linux命令du和df的区别(Linux系统目录大小通过du命令获取实例)
- php模块使用方法(PHP操作XML中XPath的应用示例)
- pythonide使用教程(对Python Pexpect 模块的使用说明详解)
- python的turtle库怎么进入(python的turtle库使用详解)
- 阿里云域名解析在哪里(阿里云服务器实现域名解析步骤小白教程)
- HTML中h1到h6标签
- yii2对比springboot(Yii框架函数简单用法分析)
排行榜
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9