目录
一、思想理解
1.原则背景
面向对象五个基本原则SOLID,单一职责原则就是其中之一。它规定一个类应该只有一个发生变化的原因。该原则由罗伯特·C·马丁于《敏捷软件开发:原则、模式与实践》一书中给出的。马丁表示此原则是基于汤姆·狄马克和Meilir Page-Jones的著作中的内聚性原则发展出的。
2.原则理解
如果一个类有多于一个的动机/原因被改变,那么这个类就具有多于一个的职责。职责可以暂且理解为这个类要负责的功能。
而单一职责原则就是指一个类或者模块应该有且只有一个改变的原因。
就一个类而言,应该仅有一个引起它变化的原因。应该只有一个职责。可以将每个职责理解为一条线,如果一个类有一个以上的职责,这些职责就像线一样耦合在了一起。这会导致当一个职责发生变化时,可能会影响其它的职责。这是软件开发要避免的。而如果想要避免这种现象的发生,就要尽可能的遵守单一职责原则。此原则的核心就是解耦和增强内聚性。
3.存在原因
单一职责原则就是因为在软件开发时会出现以下类似场景:
T类负责两个不同的职责:职责A,职责B。当由于职责A需求发生改变而需要修改类T时,有可能会导致原本运行正常的职责B功能发生故障。也就是说职责A和B被耦合在了一起。
其实很多耦合常常发生在不经意之间,其原因就是:
职责扩散:因为某种原因,某一职责被分化为更细多个职责了。
3.应用原则
遵守单一职责原则,将不同的职责封装到不同的类或模块中。
二、代码实现讲解
这里使用的是类似电话联系人的功能开发↓
因为后期可能会对每个功能进行扩展,并且接口具有一旦定义方法就要实现的特性(这会有利于后期开发的代码维护),所以使用的是接口实现方法的方式,首先定义接口和对应接口内的功能
//定义需要扩展方法的接口集合
//拨打电话
public interface IDial
{
void DialNumber(string phone_number);
}
//挂断电话
public interface IHangUp
{
void HangUpNumber(string phone_number);
}
//发送消息
public interface ISendMessage
{
void SendMessage(string message);
}
//接收消息
public interface IReceiveMessage
{
void ReceiveMessage(string message);
}
之后定义类_Mth继承接口,并且具体实现接口中的功能
//定义类实现接口功能--绝对分工
//拨打电话
public class DialMth : IDial
{
public void DialNumber(string phone_number)
{
Debug.Log("拨打电话:" + phone_number);
}
}
//挂断电话
public class HangUpMth : IHangUp
{
public void HangUpNumber(string phone_number)
{
Debug.Log("挂断电话:" + phone_number);
}
}
//发送消息
public class SendMessageMth : ISendMessage
{
public void SendMessage(string message)
{
Debug.Log("发送" + message);
}
}
//接收消息
public class ReceiveMessageMth : IReceiveMessage
{
public void ReceiveMessage(string message)
{
Debug.Log("接收" + message);
}
}
接着定义PhoneMthList类,去包含所有的接口(功能),分别设置PowerOn函数创建所有功能实例(在程序运行时调用),DialPhoneNum等这样的方法去包装起来接口的功能实现。这样就将功能包装了起来,也就是如果PhoneMthList要发生改变,只有可能是需求中要单独加一个功能,其他的操作都不会影响PhoneMthList(原则:一个类应该只有一个发生变化的原因)。而且接口中内部功能的具体实现更加不会影响到其他的功能
//实现功能的实现
public class PhoneMthList
{
private IDial _IDial;
private IHangUp _IHangUp;
private ISendMessage _ISendMessage;
private IReceiveMessage _IReceiveMessage;
public void PowerOn()
{
_IDial = new DialMth();
_IHangUp = new HangUpMth();
_ISendMessage = new SendMessageMth();
_IReceiveMessage = new ReceiveMessageMth();
}
//方法已经对应了每一个接口
public void DialPhoneNum(string phone_number)
{
_IDial.DialNumber(phone_number);
}
public void HangUpNum(string phone_number)
{
_IHangUp.HangUpNumber(phone_number);
}
public void SendMessage(string message)
{
_ISendMessage.SendMessage(message);
}
public void ReceiveMessage(string message)
{
_IReceiveMessage.ReceiveMessage(message);
}
}
最后可以将这些代码用流程图的方式体现,如图可以看见,每一个类(图上显示的是方法,但其实这些方法对应了继承了接口的类,所以其实就是类在实现具体的功能)都各自实现着自己的功能,互不干扰