设计模式6大原则-单一职责原则
定义:一个类应该只有一个引起变化的原因。一个类只负责一项职责
如果一个类有多个职责,这些职责耦合在一起,当一个职责发生变化时,可能影响其他的职责。
如:
一个类有 A、B、C 等职责,当职责A 需求变化而需要修改类时,有可能导致原本运行正常的类无法运行。
看一个手机模型类设计
手机属性和功能包括如下
手机型号名、手机屏幕尺寸、打电话、发短信、玩游戏、看视频
设计一个手机接口 IPhone如下
IPhone 接口中包含手机的属性以及不同功能(通讯、娱乐)的所有接口,如果添加属性或者功能,则需要修改 这个接口,则所有继承于 IPhone接口的类都需要修改,如果用单一职责如何优化呢?
单一职责解决如下:
将IPhone 分解成 三个职责不同的接口
IPhoneInfo:手机属性接口,包含 手机型号名、屏幕尺寸
ICommunicateTool : 通讯工具接口,包含 打电话、发短信
IAmusementTool:娱乐工具接口,包含 玩游戏、看视频
如下图
分解接口后,如果一个接口发生变化,不会影响其他两个接口
代码实现如下
// 手机属性信息
public interface IPhoneInfo
{
// 赋值手机型号
void SetName(string name);
// 获取手机型号
string GetName();
// 赋值屏幕尺寸信息
void SetScreenSizeInfo(string screenSize);
// 获取屏幕尺寸信息
string GetScreenSizeInfo();
}
// 通讯工具
public interface ICommunicateTool
{
// 打电话
void Call();
// 发短信
void SendMessage(string msg);
}
// 娱乐工具
public interface IAmusementTool
{
// 玩游戏
void PlayGame();
// 看视频
void WatchVideo();
}
手机类继承三个接口
class Phone : IPhoneInfo, ICommunicateTool, IAmusementTool
{
private string _name;
private string _screenSize;
// 赋值手机型号
public void SetName(string name)
{
_name = name;
}
// 获取手机型号
public string GetName()
{
return _name;
}
// 赋值屏幕尺寸信息
public void SetScreenSizeInfo(string screenSize)
{
_screenSize = screenSize;
}
// 获取屏幕尺寸信息
public string GetScreenSizeInfo()
{
return _screenSize;
}
// 打电话
public void Call()
{
Console.WriteLine("打电话 \n");
}
// 发短信
public void SendMessage(string msg)
{
Console.WriteLine("发短信 \n");
}
// 玩游戏
public void PlayGame()
{
Console.WriteLine("玩游戏 \n");
}
// 看视频
public void WatchVideo()
{
Console.WriteLine("看视频 \n");
}
}
调用如下
public class Client
{
public Client()
{
Phone phone = new Phone();
IPhoneInfo phoneInfo = phone;
// 赋值手机型号
phoneInfo.SetName("iphone11");
// 获取手机型号
string name = phoneInfo.GetName();
// 赋值屏幕尺寸信息
phoneInfo.SetScreenSizeInfo("6.1英寸");
// 获取屏幕尺寸信息
string size = phoneInfo.GetScreenSizeInfo();
ICommunicateTool communicateTool = phone;
// 打电话
communicateTool.Call();
// 发短信
communicateTool.SendMessage("发短信");
IAmusementTool amusementTool = phone;
// 玩游戏
amusementTool.PlayGame();
// 看视频
amusementTool.WatchVideo();
}
}
优点:
(1) 类的复杂度降低,实现什么职责都有清晰明确的定义
(2) 可读性提高
(3) 可维护性提高
(4) 变更引起的风险降低,变更是不可避免的,如果接口的单一职责设计的比较好,一个接口修改只对相应的实现类有影响,对其他接口无影响,这对系统的扩展性、维护性都有非常大的帮助