开闭原则 The Open/Closed Principle (OCP)
开闭原则规定「软体中的对象(类,模块,函数等等)应该对于扩展是开放的,但是对于修改是封闭的」,这意味着一个实体是允许在不改变它的原始码的前提下变更它的行为。该特性在产品化的环境中是特别有价值的。
简单来说 : 当对原有程式进行扩展时,在不更动到原始码的前提完成扩展。
开 : 开放扩展
闭 : 封闭修改
如果要写一只複用性高的程式,或是将软体产品化,遵守开闭原则将会轻鬆很多。
以下範例
//产品:三角形 public class Triangle { public static void Show() { Console.WriteLine($"这是一个 Triangle "); } } //产品:方形 public class Square { public static void Show() { Console.WriteLine($"这是一个 Square "); } } //实作方法 public class Display { public void ShowTheSharp(string sharp) { if (sharp == "Square") { Square square = new Square(); square.Show(); } else if (sharp == "Triangle") { Triangle triangle = new Triangle(); triangle.Show(); } } }
现在的实作方法是在Display中做判断,此时当要新增一个新的形状(圆形)时,就必须修改实作类别,而之后每次新增一个形状就要再改一次。如下图
//新增 产品:圆形 public class Circle { public static void Show() { Console.WriteLine($"这是一个 Circle "); } } //实作方法 public class Display { public void ShowTheSharp(string sharp) { if (sharp == "Square") { Square square = new Square(); square.Show(); } else if (sharp == "Triangle") { Triangle triangle = new Triangle(); triangle.Show(); } //////新增判断////// else if (sharp == "Circle") { Circle circle = new Circle(); circle.Show(); } } }
这样的情形就违反了开闭原则,所以维护起来也相对费力。
而解决方法呢,就是使用依赖注入(DI)的方法来重构此程式,为了满足开闭原则,需要对系统进行抽象化(abstract)设计。
抽象化是开闭原则的关键而依赖注入则是实现开闭原则的方法。
新增一个抽象类别Sharp并让其他形状类别继承此抽象类别。而实作方法Display则直接调用Sharp,让Client端决定要输入哪种形状。这样就达到开闭原则了,往后就算再新增形状也不需要修改实作方法。
public abstract class Sharp { public virtual void Show() { } } public class Triangle : Sharp { public override void Show() { Console.WriteLine($"这是一个 Triangle "); } } public class Square : Sharp { public override void Show() { Console.WriteLine($"这是一个 Square "); } } public class Circle : Sharp { public override void Show() { Console.WriteLine($"这是一个 Circle "); } } public class Display { public Sharp sharp; //依赖注入 public void SetSharp(Sharp _sharp) { this.sharp = _sharp; } public void ShowTheSharp() { this.sharp.Show(); //if (sharp == "Square") //{ // Square square = new Square(); // square.Show(); //} //else if (sharp == "Triangle") //{ // Triangle triangle = new Triangle(); // triangle.Show(); //} //else if (sharp == "Circle") //{ // Circle circle = new Circle(); // circle.Show(); //} } }
总结
遵守开闭原则,是为了更有效的因应变化,未来的需求一定会不断增加,而遵守开闭原则能降低维护的複杂度。
资料参考
https://blog.csdn.net/lovelion/article/details/7537584
https://zh.wikipedia.org/wiki/%E5%BC%80%E9%97%AD%E5%8E%9F%E5%88%99
https://www.zhihu.com/question/32108444