最理想的状态(或者目的)是软件中的对象(类,模块,函数等等)应该对于扩展是开放的,但是对于修改是封闭的。
1.栗子
1 public class ErrorLogger 2 { 3 private readonly string _whereToLog; 4 public ErrorLogger(string whereToLog) 5 { 6 this._whereToLog = whereToLog.ToUpper(); 7 } 8 9 public void LogError(string message) 10 { 11 switch (_whereToLog) 12 { 13 case "TEXTFILE": 14 WriteTextFile(message); 15 break; 16 case "EVENTLOG": 17 WriteEventLog(message); 18 break; 19 default: 20 throw new Exception("Unable to log error"); 21 } 22 } 23 24 private void WriteTextFile(string message) 25 { 26 System.IO.File.WriteAllText(@"C:UsersPublicLogFolderErrors.txt", message); 27 } 28 29 private void WriteEventLog(string message) 30 { 31 string source = "DNC Magazine"; 32 string log = "Application"; 33 34 if (!EventLog.SourceExists(source)) 35 { 36 EventLog.CreateEventSource(source, log); 37 } 38 EventLog.WriteEntry(source, message, EventLogEntryType.Error, 1); 39 } 40 }
2.如果需要增加一个新的日志方式(比如数据库,服务等),怎么办?当然这段代码也违背了单一职责原则。
1 public interface IErrorLogger 2 { 3 void LogError(string message); 4 } 5 6 public class TextFileErrorLogger : IErrorLogger 7 { 8 public void LogError(string message) 9 { 10 System.IO.File.WriteAllText(@"C:UsersPublicLogFolderErrors.txt", message); 11 } 12 } 13 14 public class EventLogErrorLogger : IErrorLogger 15 { 16 public void LogError(string message) 17 { 18 string source = "DNC Magazine"; 19 string log = "Application"; 20 21 if (!EventLog.SourceExists(source)) 22 { 23 EventLog.CreateEventSource(source, log); 24 } 25 26 EventLog.WriteEntry(source, message, EventLogEntryType.Error, 1); 27 } 28 }
3.如果以上述的方式进行设计,那么新的需求加入,即可如下实现。
1 public class DatabaseErrorLogger : IErrorLogger 2 { 3 public void LogError(string message) 4 { 5 // Code to write error message to a database 6 } 7 } 8 9 public class WebServiceErrorLogger : IErrorLogger 10 { 11 public void LogError(string message) 12 { 13 // Code to write error message to a web service 14 } 15 }
参考:https://www.dotnetcurry.com/software-gardening/1176/solid-open-closed-principle