What
就一个类(接口、结构体、方法等等)而言,应该仅有一个引起它变化的原因。
Why
软件设计真正要做的许多内容,就是发现职责并把那些职责互相分离。单一职责原则可以使类的复杂度降低,实现什么职责都有清晰明确的定义;类的可读性提高,复杂度降低(复杂度降低肯定可读性提高);可读性提高了,代码就更容易维护;变更(需求是肯定会变的,程序员都知道)引起的风险(包括测试的难度,以及需要测试的范围)降低。
How
需求:实现拍照和播放音乐,那先定义两个功能接口(参照《大话设计模式》)
//具有照相的功能的接口
interface IPhotograph
{
void Photograph();
}
//具有播放音乐功能的接口
interface IPlayMusic
{
void PlayMusic();
}
不遵循单一原则的设计,播放音乐及拍照功能的改变都会引起变化:
//实现照相、播放音乐的手机类
public class MobilePhone : IPhotograph, IPlayMusic
{
//拍照
public void Photograph()
{
Console.WriteLine("拍照片");
}
//播放音乐
public void PlayMusic()
{
Console.WriteLine("播放音乐");
}
}
class Program
{
static void Main(string[] args)
{
IPlayMusic musicPlayer;
IPhotograph photographer;
MobilePhone phone = new MobilePhone();
musicPlayer = phone;
photographer = phone;
//播放音乐
musicPlayer.PlayMusic();
//拍照
photographer.Photograph();
Console.ReadLine();
}
}
遵循单一原则的设计,引发改变的只有播放音乐功能的变化
//实现播放音乐功能的音乐播放器类
class MusicPlayer : IPlayMusic
{
public void PlayMusic()
{
Console.WriteLine("播放音乐");
}
}
遵循单一原则的设计,引发改变的只有摄像功能的变化
//实现照相功能的摄像机类
class Carmera : IPhotograph
{
public void Photograph()
{
Console.WriteLine("拍照片");
}
}
class Program
{
static void Main(string[] args)
{
IPlayMusic musicPlayer;
IPhotograph photographer;
//MobilePhone phone = new MobilePhone();
//musicPlayer = phone;
//photographer = phone;
musicPlayer = new MusicPlayer();
photographer = new Carmera();
//播放音乐
musicPlayer.PlayMusic();
//拍照
photographer.Photograph();
Console.ReadLine();
}
}
需求是拍照片和播放音乐,那么我给你一台相机还有一台音乐播放器,哪个功能需要改变你就换哪个,以后你要换的时候也不必去考虑其他功能,只需要关心引起你自己变化的原因。如果拍照
功能发生改变,我们就去改变照相机,播放音乐功能需要改变我们就去改变音乐播放器。我们不需要去考虑播放高品质音乐是不是会对拍摄高清图片的功能造成影响。