SRP

时刻提醒自己是否这个类或者方法符合SRP,我们需不需要把其分成小份的?

single responsibility principle states that every class should have a single responsibility, and that responsibility should be entirely encapsulated by the class. All its services should be narrowly aligned with that responsibility.

View Code
 1 using System;

 2 using System.Collections.Generic;

 3 using System.Linq;

 4 using System.Text;

 5 using System.Threading.Tasks;

 6 

 7 namespace ConsoleApplication4

 8 {

 9     class Person

10     {

11         public int Id { get; private set; }

12         public string Name { get; private set; } //constracter给property赋值,比较下面

13         public Person(int id, string name)

14         {

15             Id = id;

16             Name = name;

17         }

18     }

19     

20     class People

21     {

22         private Dictionary<int, Person> _people;

23         public People() //constracter给filed赋值

24         {

25             _people = new Dictionary<int,Person>();

26         }

27         public void AddPerson(Person person)

28         {

29             _people.Add(person.Id, person);

30         }

31         public Person GetPersonById(int id)

32         {

33             return _people[id]; //如果希望throw exception用这个

34 

35          /* 如果不希望找不到key后throw exception,用这个这不到的话返回null,person可以是null

36           * 

37             Person person;

38             if (_people.TryGetValue(id, out person))

39             {

40                 return person;

41             }

42             return null;

43           */

44         }

45         public void DisplayPeople()

46         {

47             foreach (var person in _people)

48             {

49                 Console.WriteLine("{0} - {1}", person.Key, person.Value.Name);

50             }

51         }

52     }

53 

54     class Program

55     {

56         static void Main(string[] args)

57         {

58             var people = new People();

59              people.AddPerson(new Person(423, "Nelson"));

60              people.AddPerson(new Person(233, "shawn"));

61              people.AddPerson(new Person(443, "chris"));

62              people.AddPerson(new Person(133, "rebecca"));

63              people.AddPerson(new Person(533, "mandy"));

64              people.DisplayPeople();

65              Console.Write("Selected People:");

66              var selectedId = int.Parse(Console.ReadLine());

67              var person = people.GetPersonById(selectedId);

68              Console.WriteLine("You selected {0}", person.Name);

69              Console.ReadLine();

70         }

71         

72     }

73 }

上面例子的people类有两个功能,第一个存储person的信息,第二个显示每一个person,不符合SRP,一步步的把上面的code拆分,最后得到下面的code

View Code
 1 using System;

 2 using System.Collections.Generic;

 3 using System.Linq;

 4 using System.Text;

 5 using System.Threading.Tasks;

 6 

 7 namespace ConsoleApplication4

 8 {

 9     class Person

10     {

11         public int Id { get; private set; }

12         public string Name { get; private set; }

13         public Person(int id, string name)

14         {

15             Id = id;

16             Name = name;

17         }

18     }

19     

20     class Peoples

21     {

22         public Dictionary<int, Person> People { get; private set; } //其实这样不是很好,因为外界通过62行

23         //改成public的property向外透露,private

24         //的原因是外界不能直接set,全部由内部的constractor来set

25         public Peoples() 

26         {

27             People = new Dictionary<int, Person>();

28         }

29         public void AddPerson(Person person)

30         {

31             People.Add(person.Id, person);

32         }

33         public Person GetPersonById(int id)

34         {

35             return People[id]; 

36         }

37     }

38     

39     class PeopleView    //好处程序用同一个People类的Data,但不同的PeopleView(like unity, wpf)

40     {

41         private Peoples _people;

42         public PeopleView (Peoples people)

43         {

44             _people = people;

45         }

46         public void DisplayPeople()

47         {

48             foreach (var person in _people.People)

49             {

50                 Console.WriteLine("{0} - {1}", person.Key, person.Value.Name);

51             }

52         }

53         public Person SelectedPerson()

54         {

55             DisplayPeople();

56             Console.Write("Selected People:");

57             var selectedId = int.Parse(Console.ReadLine());

58             return _people.GetPersonById(selectedId);

59         }

60         public void DisplayPerson(Person person)

61         {

62             Console.WriteLine("Person: {0} is named {1}", person.Id, person.Name);

63         }

64     }

65 

66 

67     class Program

68     {

69         static void Main(string[] args)

70         {

71             

72             var people = new Peoples();

73             //people.People.Add(333, "hahaha");

74             var view = new PeopleView(people); //习惯使用var而不是下面

75             //PeopleView view = new PeopleView(people);

76              people.AddPerson(new Person(423, "Nelson"));

77              people.AddPerson(new Person(233, "shawn"));

78              people.AddPerson(new Person(443, "chris"));

79              people.AddPerson(new Person(133, "rebecca"));

80              people.AddPerson(new Person(533, "mandy"));

81              var selectedPerson = view.SelectedPerson();

82              view.DisplayPerson(selectedPerson);

83              

84              Console.ReadLine();

85         }

86         

87     }

88 }

 继续我们可以换成interface,这样更通用,可以有多种不同view的方法实现

View Code
  1 using System;

  2 using System.Collections.Generic;

  3 using System.Linq;

  4 using System.Text;

  5 using System.Threading.Tasks;

  6 

  7 namespace ConsoleApplication5

  8 {

  9     class Person

 10     {

 11         public int Id { get; private set; }

 12         public string Name { get; private set; }

 13         public Person(int id, string name)

 14         {

 15             Id = id;

 16             Name = name;

 17         }

 18     }

 19     class People

 20     {

 21         public Dictionary<int, Person> PeopleCollection { get; private set; }

 22         //计算是private setter也不是最好的implementation

 23         public People()

 24         {

 25             PeopleCollection = new Dictionary<int, Person>();

 26         }

 27         public void AddPerson(Person person)

 28         {

 29             PeopleCollection.Add(person.Id, person);

 30         }

 31         public Person GetPersonById(int id)

 32         {

 33             return PeopleCollection[id];

 34         }

 35         

 36     }

 37     interface IPeopleView

 38     {

 39         void DisplayPeople();

 40         Person SelectedPerson();

 41         void DisplayPerson(Person person);

 42     }

 43     class ConsolePeopleView:IPeopleView

 44     {

 45         private People _people;

 46         public ConsolePeopleView(People people)

 47         {

 48             _people = people;

 49         }

 50         public void DisplayPeople()

 51         {

 52             foreach (var person in _people.PeopleCollection)

 53             {

 54                 Console.WriteLine("{0} - {1}", person.Key, person.Value.Name);

 55             }

 56         }

 57         public Person SelectedPerson()

 58         {

 59             DisplayPeople();

 60             Console.Write("Select People: ");

 61             var selectedId = int.Parse(Console.ReadLine());

 62             return _people.GetPersonById(selectedId);

 63         }

 64         public void DisplayPerson(Person person)

 65         {

 66             Console.WriteLine("Person {1} name is {0}", person.Id, person.Name);

 67         }

 68     }

 69     /*class InterfaceGUIPeopleView : IPeopleView

 70     {

 71         ......

 72     }

 73     class UnityGUIPeopleView : IPeopleView

 74      {

 75      ......

 76 

 77      }

 78     */

 79     class Program

 80     {

 81         static void RunProgram(People model, IPeopleView view)

 82         //Runprogramm不知道它会得到什么view,

 83         //只要是继承自IPeopleView的view都可以

 84         //interface的好处,进来任何的view都有同样的逻辑,选择一个peoson,display它

 85         {

 86             

 87             model.AddPerson(new Person(123, "Shawn"));

 88             model.AddPerson(new Person(927, "Baba"));

 89             model.AddPerson(new Person(453, "Tutu"));

 90             

 91             var selectedPerson = view.SelectedPerson();

 92             view.DisplayPerson(selectedPerson);

 93         }

 94 

 95         static void Main(string[] args)

 96             

 97         {

 98             var people = new People();

 99             var view = new ConsolePeopleView(people);

100 

101             RunProgram(people, view);

102             Console.ReadLine();

103         }

104     }

105 }

这部分代码更像是Unit Test,因为simulate了用户的输入,但是其实我们程序应该不知道用户输入的是什么。

我们可以日后改成:

 

 

考虑这个是否break SRP?

其实没有,因为每一个类执行了自己被要求做的事情,虽然ThinggyRepository里的Add方法访问了DataBase。就想是个manager一样,我要这件事被做!!

 

 

你可能感兴趣的:(r)