架构技巧系列之 — 单一职责原则

2014/10/2222:47:55 发表评论

今天,怀着无比兴奋的心情来和大家扯扯平时同学经常会问我的问题:


1、如何从头开始写一个大型软件?

2、如何成为一名架构师?

3、面向对象开发思想究竟有什么用?

4、我感觉学完C/C++后为什么还是不会写大型程序?

5、设计模式究竟是什么?


     其实,大型软件开发过程并不像想象中的那么神秘和困难,虽然从规模上看,大型软件开发确实够大,但是完全可以尽可能的使其过程简单化。

     如何做到呢?经验!前辈们已经给我们总结了很多的开发经验,这些经验在今天已经浓缩成了一系列可以复用的开发准则,因此,站在巨人的肩膀上必然能使我们走得更远。所以,今天就先给大家介绍一个比较简单的设计准则:单一职责原则!

      什么是单一职责原则?

英文名称为 Single Responsibility Principle ,简称 SRP ,即一个实体只做一件事,每个实体的功能是单一的比如:一个函数的功能是单一的,一个类的功能是单一的。这个原则看起来是多么的容易啊,可是事实真的如此吗? 我们通过一个例子来说明问题。

下面是一个用户接口的设计:

blob.png

这个设计看上去是那么的合情合理,虽然我的例子中的类是User但是把它换成 Student , Network 等都是可以的。所有与User相关的操作都集中在一个接口中,确实看上去挺好的,工作中也是这么做的。但是从设计的角度,这里却存在了一个非常严重的问题。因为这个接口的设计违背了 SRP 原则, User 的信息操作和 User 的行为操作被集中在了一起。

IUser接口负责了两件事:


1.Business Object Operation

2.Business Logic Operation


     如果说User是需求上下文的中的一个实体,那么单纯的User信息我们应该抽象一个接口,即:Business Object Operation。而User之间的关系,User 与其它实体间的关系(如:Role,Department 等),以及User可以执行的操作等等应该抽象出另外的接口,即:Business Logic Operation。于是,有了下面的设计:

blob.png

将职责分开后的代码示例:

blob.png

    上面将一个接口分开为两个接口的动作就是基于的 SRP 原则,那么究竟什么SRP原则呢?


      SRP的本质:有且仅有一个原因会引发类的改变。 (There should never be more than one reason for a class to change.)


为了大家更进一步的理解这个原则,我们再来看一个例子。比如下面这个接口:

blob.png

对于现代的手机来说,肯定有拨号,通话,挂机的功能,否则那也能叫手机?!因此,从实际的角度来说,这个接口设计应该算是完美的了。但,事实是这样吗?我们来分析一下,其实从功能上来说这个接口包含了两个职责:一个是通讯链路的管理,另一个是数据的传输。

对于实际情况:


1、当通讯协议不同时, dial 和 hangup 的方式不同

2、链路连通后,对于不同的数据,传输方式不同,如:文本,语音和图像的传输方式不同,但这些都可以是现代手机的聊天方式


     那么这两个职责会相互影响吗?

     链路在连接成功后即可传输数据,并且链路根本不会关心数据是以何种方式进行编码,也不会关心究竟传输的是文本,语音还是图像。对于链路而言,只负责传输二进制流。然而对于具体的数据传输而言,只要链路连通即可,不会关心是基于 TCP,  UDP 还是 CDMA,也不会关心这条链路是如何连通的。这样我们可以得出结论,这个两个职责是比较独立的,应该将接口重新设计。

blob.png

通过上面的例子,我们可以得到下面的推论:


1、接口复杂性降低,所有的接口都是清晰的单一职责定义

2、更容易适应需求变更,每个变更只影响少数相互独立的接口

3、代码可读性和代码维护性提高


      虽然上面阐述的单一性原则从理论上很完美,但是,它却依赖于我们在系统分析时必须把各个职责定义清楚。

       简单的说,我们是否可以从纷繁复杂的问题中清晰的分离出各个职责,这才是关键。另外,大家应该发现了,我上面提到的单一性原则都是用在接口上的,那么是否适用于类呢?从实际问题的角度,系统中的每个类对应现实问题中的实体,然而,现实中的每个实体只有单一的职责吗?这肯定肯定是不可能的。因此,我建议大家在做开发的时候,接口的设计一定要完全遵守SRP原则,而类的设计根据实际情况尽量遵守SRP原则即可。

To be continued…

  • 微信扫码赞助
  • weinxin
  • 支付宝赞助
  • weinxin

发表评论

您必须才能发表评论!