Single responsibility is the guiding ideology of reducing coupling, which is applicable to a micro service, a type and a method.
Micro service layer:
Microservices are generally divided according to business areas: Pharmacy microservices are pharmacy businesses, and nurse station microservices are nurse station businesses. In a broad sense, there is no problem, but for some shared businesses, it is difficult. Which microservices are placed in? Or merge two microservices? In fact, it is single here. If the shared services are separated, they may not be made into another micro service. They can be unified into a class library for two micro services to call. If there are subtle differences in business, the heterogeneous situation can be flexibly solved through design patterns.
Type:
Types here generally refer to complex types, such as structs, interfaces, abstract classes, instantiated classes, and records. Within this type, important members have attributes and methods. It is the planning of these members that determines whether these types have single responsibilities.
For example, for the following user types, this definition is not wrong. For some small projects, this definition is the most economical.
/// <summary> /// user /// </summary> class User { /// <summary> /// user name /// </summary> public string UserName { get; set; } /// <summary> /// password /// </summary> public string Password { get; set; } /// <summary> /// Sexual name /// </summary> public string Name { get; set; } /// <summary> /// Gender true Male, false For female /// </summary> public bool Sex { get; set; } /// <summary> /// post /// </summary> public string Position { get; set; } /// <summary> /// birthday /// </summary> public DateTime Birthday { get; set; } }
If considering a single responsibility, this category can be divided into three categories, as follows:
/// <summary> /// user /// </summary> class User { /// <summary> /// user name /// </summary> public string UserName { get; set; } /// <summary> /// password /// </summary> public string Password { get; set; } } /// <summary> /// Personnel position /// </summary> class Position { /// <summary> /// Title /// </summary> public string PositionName { get; set; } } /// <summary> /// personnel /// </summary> class Person { /// <summary> /// Personnel number /// </summary> public string PersonNo { get; set; } /// <summary> /// Sexual name /// </summary> public string Name { get; set; } /// <summary> /// Gender true Male, false For female /// </summary> public bool Sex { get; set; } /// <summary> /// Age /// </summary> public int Age { get; set; } /// <summary> /// user /// </summary> public User User { get; set; } /// <summary> /// post /// </summary> public Position[] Positions { get; set; } }
After separation, although the code increases, the role of each class is single. Users are users and personnel are personnel. When jobs are separated, other types will not be affected when they are expanded.
method:
The lower the level, the more difficult it is to grasp a single responsibility. Especially when writing a method, the single unit is very vague. How can it be single?
For example, writing a sending data module is mainly divided into two parts: organizing data and sending data, which correspond to two methods, BuildData and SendData. It may be found that some data have to be converted when organizing data, such as time and type. At this time, it can be converted in BuildData. Of course, the conversion part can also be separated to form a TransformData. The tangle is, Sometimes the conversion of data requires only one line of code, which should be separated according to the idea of single responsibility, but the separated code is not satisfactory. Is there a standard?
Here I give my own standards (only on behalf of my own understanding):
1. When struggling with whether to disassemble a method, the first consideration is the unity of the business
2. If the current state of some businesses is unified, we should associate it with the next state or the next stage. Whether this state lasts or not (don't care when this state comes in reality)
3. Use more classic design patterns to isolate the methods from each other without interference