设计模式七大原则—单一职责原则
基本介绍
在程序设计编写某个类时,应当要求某个类结合业务情况只负责一项职责。如果将多个职责融合在一个类中,那么某个职责的改动,很可能会造成其他职责出现错误。
例如,你将订单和商品的处理写在了同一个A类中,当你去针对订单需求变更改动A类时,那么很可能你的某个改动会影响到商品的某些功能,并且这个影响错误往往在编码时很难发现,直到你程序运行时发现,就为时已晚。所以基于“单一职责原则”,我们应该将负责订单和负责商品的部分,分解为两个单独的类。
通过“单一职责原则”来思考不同代码示例下的表现情况
示例1
1 //盒子类 2 class Box 3 { 4 /// <summary> 5 /// 将物品放入盒子 6 /// </summary> 7 /// <param name="stuff">物品</param> 8 public void Lay(string stuff) 9 { 10 Console.WriteLine($"将{stuff}放入盒子里"); 11 } 12 } 13 14 internal class Program 15 { 16 static void Main(string[] args) 17 { 18 Box box = new Box(); 19 box.Lay("碗"); 20 box.Lay("书"); 21 box.Lay("锤子"); 22 } 23 }
从上面的简单代码例子来看,定义的盒子类不仅仅只能安放某一种物品,他是可以安放多种物品(碗、书、锤子),以及后续可能会出现的更多种类。因此,从这个示例的层面来看,这个盒子类实际上就违反了“单一职责原则”。我们来分析下具体原因:
1.盒子负责存放的物品是多种的,这就代表了盒子类出现了多职责的情况;
2.如果某天需要盒子放入鸡蛋,并且为了保护鸡蛋不破损,你将在格子里进行分割一个个小格子,那么此时就会发现,因为要放鸡蛋改造了盒子,却导致书放不进盒子了。
示例2
1 //碗盒 2 class BowlBox 3 { 4 public void Lay(string Bowl) 5 { 6 Console.WriteLine($"将{Bowl}放入碗盒里"); 7 } 8 } 9 10 //工具盒 11 class ToolBox 12 { 13 public void Lay(string Tool) 14 { 15 Console.WriteLine($"将{Tool}放入工具盒里"); 16 } 17 } 18 19 //书盒 20 class BookBox 21 { 22 public void Lay(string book) 23 { 24 Console.WriteLine($"将{book}放入书盒里"); 25 } 26 } 27 28 29 internal class Program 30 { 31 static void Main(string[] args) 32 { 33 BowlBox bowlBox = new BowlBox(); 34 bowlBox.Lay("饭碗"); 35 ToolBox ToolBox = new ToolBox(); 36 ToolBox.Lay("锤子"); 37 BookBox bookBox = new BookBox(); 38 bookBox.Lay("书"); 39 } 40 }
接着示例1的背景,示例2根据每种物品都声明了不同的盒子,直观上来看示例2是符合了“单一职责原则”,因为每个盒子只装一种类型物品。从示例的业务体量来看,我们的实际需要是很小的,就是将一个盒子里放几件东西,但是我们要针对每种物品创建一个类,并且在调用端要针对不同物品声明不同类进行处理,那么对于这个示例的需求体量而言,代码开销是比较大的。
示例3
1 //盒子类 2 class Box 3 { 4 public void LayBowlGrid(string bowl) 5 { 6 Console.WriteLine($"将{bowl}放入盒子里的碗格"); 7 } 8 public void LayToolGrid(string tool) 9 { 10 Console.WriteLine($"将{tool}放入盒子里的工具格"); 11 } 12 public void LayBookGrid(string book) 13 { 14 Console.WriteLine($"将{book}放入盒子里的书格"); 15 } 16 } 17 18 19 internal class Program 20 { 21 static void Main(string[] args) 22 { 23 Box box = new Box(); 24 box.LayBowlGrid("饭碗"); 25 box.LayToolGrid("锤子"); 26 box.LayBookGrid("书"); 27 } 28 }
示例3从抽象层面你可以想象,你根据预先要放入的物品,将一个盒子分割为多个存放物品的格子,对应到代码就是将物品分别通过不同的方法放入,每个方法只负责存在某一种类型的物品。
示例3从类的角度来看并不符合“单一职责原则”,但是它从方法的角度来看是符合“单一职责原则”的。

分解职责的考量
结合以上三个示例的分析情况,实际上在遵守“单一职责原则”,针对类进行多个职责分解时,需要考量到分解后代码消耗的成本,并对比业务功能的体量。如果和本文中的示例情况一样,分解后消耗比较大,并且功能体量不大(类中成员不多),那么我们可以将分解范围从类下层到方法级别,在方法上遵守“单一职责原则”即可。
总结
遵守“单一职责原则”主要可以有以下好处:
1.可以降低类的复杂度,一个类只针对一项职责展开具体的实现。
2.提高类的可读性,可维护性。
3.降低代码变更带来的风险。
“单一职责原则”理解起来并不是很难,难在编程过程中如何时刻警惕自己遵守这个原则,大多数人在实际的工作中,为了更快的交付,往往忽略了“单一职责原则”,这里的“单一职责原则”往往更像是衡量一个程序员品性的标准。

浙公网安备 33010602011771号