- 单一职责原则(Single Reponsibility Principle,SRP)
- 里氏替换原则(Liskov Substitution Principle,LSP)
- 依赖倒置原则(Dependence Inversion Principle,DIP)
- 接口隔离原则(Interface Segregation Principe,ISP)
- 迪米特法则(Law of Demeter,LOD)
- 开闭原则(Open Closed Principle,OCP)
单一职责原则 SRP:
Single Reponsibility Principle,简称:SRP
一个类只负责一项职责。换种说法,就一个类而言,应该只有一个引起它变化的原因。
问题由来:类T负责两个不同的职责:职责P1,职责P2。当由于职责P1需求发生改变而需要修改类T时,有可能会导致原本运行正常的职责P2功能发生故障。
解决方案:遵循单一职责原则。分别建立两个类T1、T2,使T1完成职责P1功能,T2完成职责P2功能。这样,当修改类T1时,不会使职责P2发生故障风险;同理,当修改T2时,也不会使职责P1发生故障风险。
单一职责的成本:类变多了;上端需要了解更多的类
衡量着使用:
- 如果类相对稳定,扩展变化少,而且逻辑简单,违背单一职责也没关系
- 一个类不要让他太“累”
- 如果不同的职责,总是一起变化,这种是一定要分开的
举例
一个简单的例子,动物的故事,代码如下:
public class Animal
{
protected string _Name = null;
public Animal(string name)
{
this._Name = name;
}
public void Action()
{
if (this._Name.Equals("鸡"))
{
Console.WriteLine($"{this._Name} flying");
}
else if (this._Name.Equals("鱼"))
{
Console.WriteLine($"{this._Name} swimming");
}
//……
}
}
动物类,呼吸方法中分别写了鸡和鱼的活动方式,鸡活动是飞、鱼活动是游泳,当出现其他动物时Action类就不稳定了,就得不断的修改此方法,不断的 if…else… 。因此,制造了不稳定性,若方法内业务复杂,容错率就非常低了。
倘若将代码改写一下。设置一个抽象类Animal。鱼类AnimalFish和鸡类AnimalChicken分别继承自动物类。类的复杂性降低了,可读性也同时提高了,最重要的是职责划分也明确了。当然,也就更容易维护了。
代码如下:
public abstract class Animal //动物类 ——— 抽象类
{
protected string _Name = null;
public Animal(string name)
{
this._Name = name;
}
public abstract void Breath();
public abstract void Action();
}
public class AnimalFish : Animal //鱼类
{
public AnimalFish(string name) : base(name)
{}
public override void Breath()
{
Console.WriteLine($"{this._Name} 呼吸水");
}
public override void Action()
{
Console.WriteLine($"{this._Name} swimming");
}
}
public class AnimalChicken : Animal //鸡类
{
public AnimalChicken(string name) : base(name)
{}
public override void Breath()
{
Console.WriteLine($"{this._Name} 呼吸空气");
}
public override void Action()
{
Console.WriteLine($"{this._Name} flying");
}
}
class Program
{
static void Main(string[] args)
{
{
Animal animal = new AnimalChicken("鸡");
animal.Breath();
animal.Action();
}
{
Animal animal = new AnimalFish("鱼");//呼吸水
animal.Breath();
animal.Action();
}
}
}