SOLID 学习笔记 - 单一职责
六大设计原则
单一责任原则:
一个类应该只做一件事,而且只做一件事。
错误示例:
copy public class CsvFileProcessor { public void Process(string filename) { TextReader tr = new StreamReader(filename); tr.ReadToEnd(); tr.Close(); var conn = new SqlConnection("server=(local);integrated security=sspi;database=SRP"); conn.Open(); string[] lines = tr.ToString().Split(new string[] {@"\r\l"}, StringSplitOptions.RemoveEmptyEntries); foreach( string line in lines) { 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(); } } 这个类做了三件事: 1. 读取 CSV 文件 2. 解析 CSV 文件 3. 存储数据 这样做如果数据验证和错误记录,该怎么办?该怎么对它进行单元测试。一般情况下我们使用代码重构修改此例子; |
copy 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或其他东西是什么? 你可以用接口来解决这个问题。 copy public interface IContactDataProvider { string Read(); } 我们使用读取、解析和写入的通用方法名称,因为我们不知道将获得什么类型的数据。 现在,我们可以很容易地对这段代码进行单元测试。 我们还可以轻松修改解析代码,如果我们引入新的错误,它不会影响读取和写入代码。 另一个好处是,我们已经松散地耦合了实现。 所以,你有它。我们采用了相当常见的程序代码,并使用单一责任原则对其进行了重构。 |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
2018-05-18 常用Js笔记,以后可能用得上