SOLID 學習筆記 - 單一職責
阿新 • • 發佈:2022-05-18
六大設計原則
單一責任原則:
一個類應該只做一件事,而且只做一件事。
錯誤示例:
public class CsvFileProcessor { public void Process(string filename) { TextReader tr = new StreamReader(filename); tr.ReadToEnd(); tr.Close(); 這個類做了三件事: 1. 讀取 CSV 檔案 2. 解析 CSV 檔案 3. 儲存資料 這樣做如果資料驗證和錯誤記錄,該怎麼辦?該怎麼對它進行單元測試。一般情況下我們使用程式碼重構修改此例子; |
public class CsvFileProcessor { public void Process(string filename) { var csvData = ReadCsv(filename); var parsedData = ParseCsv(csvData); StoreCsvData(parsedData); } public string ReadCsv(string filename) { TextReader tr = new StreamReader(filename); tr.ReadToEnd(); tr.Close(); return tr.ToString(); } public string[] ParseCsv(string csvData) { return csvData.ToString().Split(new string[] { @"\r\l" }, StringSplitOptions.RemoveEmptyEntries); } public void StoreCsvData(string[] csvData) { var conn = new SqlConnection("server=(local);integrated security=sspi;database=SRP"); conn.Open(); foreach (string line in csvData) { string[] columns = line.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries); var command = conn.CreateCommand(); command.CommandText = "INSERT INTO People (FirstName, LastName, Email) VALUES (@FirstName, @LastName, @Email)"; command.Parameters.AddWithValue("@FirstName", columns[0]); command.Parameters.AddWithValue("@LastName", columns[1]); command.Parameters.AddWithValue("@Email", columns[2]); command.ExecuteNonQuery(); } conn.Close(); } } 我們在 ParseCsv() 方法中將 CSV 檔案解析為行,但在 StoreCsvData() 方法中進行了額外的解析,以使每行成為列。 解決此問題的方法是使用儲存每行資料的 ContactDTO。 下一步是新增 DTO,但我會跳過一個步驟,並將每個方法分解為自己的類。 但我也會在這裡提前考慮。如果資料未以 CSV 格式提供,該怎麼辦?它的XML或JSON或其他東西是什麼? 你可以用介面來解決這個問題。 public interface IContactDataProvider { string Read(); } 我們使用讀取、解析和寫入的通用方法名稱,因為我們不知道將獲得什麼型別的資料。 現在,我們可以很容易地對這段程式碼進行單元測試。 我們還可以輕鬆修改解析程式碼,如果我們引入新的錯誤,它不會影響讀取和寫入程式碼。 另一個好處是,我們已經鬆散地耦合了實現。 所以,你有它。我們採用了相當常見的程式程式碼,並使用單一責任原則對其進行了重構。 |