设计模式6大原则一:单一职责原则

简介:单一职责的英文名称是Single Responsibility Principle,简称市SRP。

定义:(There should never be more than one reason for a class to change.)有且仅有一个原因引起类的变更。

单一职责,的定义要求,用通俗的话说,就是一个类只会因为一个原因而导致这个会被修改。反过来说,就是一个类只负责一个职责。

我们在设计程序是,往往都需要围绕着单一职责这个原则进行设计,这是一个很平常的一个设计方式。但是,单一职责也是令人矛盾的,因为往往有些类的设计并无法完全遵守单一职责。

问题1:为什么要使用单一职责?

在新闻发布系统中,我们需要对发布文章进行管理,我们且看一下下面的类图:

Article类图

这是一个文章管理的类图,相信每个人看到这个类图都会说这个接口设计的有问题,很没水准。是的,这个接口设计的文章的属性和行文没有区分开来,这是严重的错误。用单一职责原则来衡量的话,这个文章接口负责了两个职责。这样,无论文章的信息或文章的行为发生了任何变化,都会引起这个接口的变更,而当更改了这个接口之后,那么与这个接口所关联的所有代码都需要更改,这给程序的维护带来了非常的不方便,同时也和我们之前说所的单一职责的原理相违背。我们把文章接口中的文章信息和行为分别提取出来,如下图所示:

文章类图

提取之后,原先的IArticle接口被我们拆分成两个接口,IArticleModel接口负责文章信息的属性,它的职责就是负责文章信息的收集与反馈。而IArticleService接口则负责用户的行为,它的职责是完成用户信息的维护与变更。这样使得,每一个接口都只负责一个职责,也符合了单一职责的原理。这样,当我们需要增加文章的属性或者增加文章的行为时,我们只需要对专门的接口和类进行修改就行了,这样的程序大大的节省了我们的维护成本。

问题2:单一职责为何是令人矛盾的?

为什么说单一职责是令人矛盾的呢,这就涉及到另一个术语,叫做职责扩散。

举个例子说,做过通信编程的都知道,socket通过TCP发送数据的步骤无非就是获得客户端IP然后与客户机器取得连接,发送数据,结束连接这三线一体的操作,那么我们来看一下下方服务器端代码:

public class SocketService {

	public void connectionByTCP(){
		boolean isConn = false;//如果与客户端去的连接,isConn的值为true,否则为false,默认为false
		System.out.println("获得client端IP");
		System.out.println("与客户端去的连接......");
		if(isConn){
			System.out.println("向client发送数据");
			System.out.println("关闭连接");
		}else{
			System.err.println("与客户端握手失败");
			System.out.println("关闭连接");
		}
	}
}
上面代码所描述的就是,服务器获得客户端的IP,然后与客户端连接上,连接上客户端之后发送数据并关闭连接。这描述是再正确不过了,但是我们知道,socket除了可以通过TCP连接发送数据之外,还可以用UDP方式发送数据,而UDP发送数据的方式与TCP所区别的就在于,UDP不需要去确认是否能够与client的IP连接上,它只需要把数据发送出去,至于client能不能接收到数据并不在它的管辖之内。如下代码:
public class SocketService {

	public void connectionByTCP(){
		boolean isConn = false;//如果与客户端去的连接,isConn的值为true,否则为false,默认为false
		System.out.println("获得client端IP");
		System.out.println("与客户端去的连接......");
		if(isConn){
			System.out.println("向client发送数据");
			System.out.println("关闭连接");
		}else{
			System.err.println("与客户端握手失败");
			System.out.println("关闭连接");
		}
	}
	public void connectionByUDP(){
		System.out.println("获得client端IP");
			System.out.println("向client发送数据");
			System.out.println("关闭连接");
	}
}

那么,这就使得类SocketService不单单负责TCP发送数据的职责,同时也负责了通过UDP发送数据的职责,无论TCP还是UDP发送数据时的操作有什么改变,这个类都需要被修改。这是不符合单一责任原则的,但是,我们一般设计程序是,还是无法避免的会按照上面的方式去设计。这就使得单一职责的矛盾了。

总结:

通过上面的例子我们总结了一下单一职责的优点:

1、降低类的复杂度,清晰明确的定义类的职责;

2、提高代码可读性

3、提高代码的可维护性,降低代码维护成本;

4、降低程序因变更引起的风险,提高程序的可扩展性。

其实,我们在设计程序的时候,一定要做到接口的职责单一,但是在实现类时还是需要多方面考虑的。如果没设计一个类都一定要遵守单一职责原则的话,可能会是的程序非常生硬,而过分去细分类的职责也会是的程序的复杂性大大提高,同时也会使得编码人员的工作量大大增加。合理运用才是王道。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值