单一职责原则 Single Responsibility Principle(SRP)

时间:2022-07-20 19:36:13

最理想的状态(或者目的)是一个类应该做一件事或者只做一件事。

1.典型代码(Csv文件处理程序)

 1 public class CsvFileProcessor
 2 {
 3     public void Process(string filename)
 4     {
 5         TextReader tr = new StreamReader(filename);
 6         tr.ReadToEnd();
 7         tr.Close();
 8  
 9         var conn = new SqlConnection("server=(local);integrated security=sspi;database=SRP");
10         conn.Open();
11  
12         string[] lines = tr.ToString().Split(new string[] {@"\r\l"}, StringSplitOptions.RemoveEmptyEntries);
13         foreach( string line in lines)
14         {
15             string[] columns = line.Split(new string[] {","}, StringSplitOptions.RemoveEmptyEntries);
16             var command = conn.CreateCommand();
17             command.CommandText = "INSERT INTO People (FirstName, LastName, Email) VALUES (@FirstName, @LastName, @Email)";
18             command.Parameters.AddWithValue("@FirstName", columns[0]);
19             command.Parameters.AddWithValue("@LastName", columns[1]);
20             command.Parameters.AddWithValue("@Email", columns[2]);
21             command.ExecuteNonQuery();
22         }
23         conn.Close();
24     }
25 }
函数 void Process(string filename)使用中用到了太多的类,但是分析其核心功能仅有读取,转换以及存储。
2.由此进行下一步改造
 1 public class CsvFileProcessor
 2 {
 3     public void Process(string filename)
 4     {
 5         var csvData = ReadCsv(filename);
 6         var parsedData = ParseCsv(csvData);
 7         StoreCsvData(parsedData);
 8     }
 9  
10     public string ReadCsv(string filename)
11     {
12         TextReader tr = new StreamReader(filename);
13         tr.ReadToEnd();
14         tr.Close();
15         return tr.ToString();
16     }
17  
18     public string[] ParseCsv(string csvData)
19     {
20         return csvData.ToString().Split(new string[] { @"\r\l" }, StringSplitOptions.RemoveEmptyEntries);
21     }
22  
23     public void StoreCsvData(string[] csvData)
24     {
25         var conn = new SqlConnection("server=(local);integrated security=sspi;database=SRP");
26         conn.Open();
27         foreach (string line in csvData)
28         {
29             string[] columns = line.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
30             var command = conn.CreateCommand();
31             command.CommandText = "INSERT INTO People (FirstName, LastName, Email) VALUES (@FirstName, @LastName, @Email)";
32             command.Parameters.AddWithValue("@FirstName", columns[0]);
33             command.Parameters.AddWithValue("@LastName", columns[1]);
34             command.Parameters.AddWithValue("@Email", columns[2]);
35             command.ExecuteNonQuery();
36         }
37         conn.Close();
38     }
39 }

现在看上去好多了,但是依旧没有能达到目标(比如:如果文件不是Csv格式,亦或Xml?Json?等等),设计不够牢靠。

3.再次改进

 1 public interface IContactDataProvider
 2 {
 3     string Read();
 4 }
 5 public interface IContactParser
 6 {
 7     IList<ContactDTO> Parse(string contactList);
 8 }
 9 public interface IContactWriter
10 {
11     void Write(IList<ContactDTO> contactData);
12 }
13 
14 public class ContactDTO
15 {
16     public string FirstName { get; set; }
17     public string LastName { get; set; }
18     public string Email { get; set; }
19 }
20 
21 public class ContactProcessor
22 {
23     public void Process(IContactDataProvider cdp, IContactParser cp, IContactWriter cw)
24     {
25         var providedData = cdp.Read();
26         var parsedData = cp.Parse(providedData);
27         cw.Write(parsedData);
28     }
29 }
30 public class CSVContactDataProvider : IContactDataProvider
31 {
32     private readonly string _filename;
33  
34     public CSVContactDataProvider(string filename)
35     {
36         _filename = filename;
37     }
38      
39     public string Read()
40     {
41         TextReader tr = new StreamReader(_filename);
42         tr.ReadToEnd();
43         tr.Close();
44         return tr.ToString();
45     }
46 }
47  
48 public class CSVContactParser : IContactParser
49 {
50     public IList<ContactDTO> Parse(string csvData)
51     {
52         IList<ContactDTO> contacts = new List<ContactDTO>();
53         string[] lines = csvData.Split(new string[] { @"\r\l" }, StringSplitOptions.RemoveEmptyEntries);
54         foreach (string line in lines)
55         {
56             string[] columns = line.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
57             var contact = new ContactDTO
58             {
59                 FirstName = columns[0],
60                 LastName = columns[1],
61                 Email = columns[2]
62             };
63             contacts.Add(contact);
64         }
65  
66         return contacts;
67     }
68 }
69  
70 public class ADOContactWriter : IContactWriter
71 {
72     public void Write(IList<ContactDTO> contacts)
73     {
74         var conn = new SqlConnection("server=(local);integrated security=sspi;database=SRP");
75         conn.Open();
76         foreach (var contact in contacts)
77         {
78             var command = conn.CreateCommand();
79             command.CommandText = "INSERT INTO People (FirstName, LastName, Email) VALUES (@FirstName, @LastName, @Email)";
80             command.Parameters.AddWithValue("@FirstName", contact.FirstName);
81             command.Parameters.AddWithValue("@LastName", contact.LastName);
82             command.Parameters.AddWithValue("@Email", contact.Email);
83             command.ExecuteNonQuery();
84         }
85         conn.Close();
86  
87     }
88 }
至少现在看上去完美了,以后呢???
参考:https://www.dotnetcurry.com/software-gardening/1148/solid-single-responsibility-principle