Single responsibility principle
Single Responsibility Principle, SRP.
define
A class, interface, or method only does one thing, and there should be one and only one reason for a class to change. Difficulty: The most difficult part of the principle of single responsibility is responsibility, which does not have a quantitative standard.
advantages
2. Improved readability 3. Improved maintainability 4. Reduced risk caused by change. Interface modification only affects the corresponding implementation class, but has no impact on other interfaces
The sample
This is a user class, but it does not follow the single responsibility principle. The user information should be extracted into a BO (Business Object) and the behavior into a Biz (Bussiness Logic).
application
The single responsibility principle is difficult to implement in a project, because it leads to a proliferation of classes, and over-categorization of responsibilities artificially increases the complexity of the system. Besides, the division of responsibilities is different for everyone, which is not a quantitative standard, so it needs to be considered in many aspects during the design.
A single responsibility applies to interfaces, classes, methods, etc. The method definition below is not a good one
The responsibilities of the defined method are not clear, and the parameters are diverse, which will be very troublesome for others to maintain later.
code
The following code is an employee class. When we add new requirements, we often add related methods to the class, so that the class takes on extra work and does more than one thing
@ interface Employee: NSObject / / = = = = = = = = = = = = initial requirements = = = = = = = = = = = = @ property (nonatomic, copy) nsstrings * name; @property (nonatomic, copy) NSString *address; @property (nonatomic, copy) NSString *employeeID; / / / / employee ID = = = = = = = = = = = = new demand = = = = = = = = = = = = / / calculate salary - (double) calculateSalary; @endCopy the code
A new accounting department class should be created to separate out the methods
#import "Employee. H "@interface FinancialApartment: NSObject // calculateSalary - (double)calculateSalary:(Employee *) Employee; @endCopy the code
If the future needs of employees are divided into multiple types, including senior employees, intermediate employees and low-level employees, some of them may be subclasses of three new employee classes, while others may be added an attribute, which depends on the specific needs and whether the employees have other distinctions. Of course, the first one will have better scalability and conform to the principle of single responsibility in the future. Accordingly, The class FinancialApartment also needs multiple methods to calculate salary, instead of distinguishing by type and so on. However, in general work development, we tend to complete in the second way, so that the change at that time is the most convenient and fast, but later system expansion will be more troublesome.
Richter’s substitution principle
Liskov Substitution Principle, LSP.
define
If for every object o1 of type S, there is object O2 of type T, such that the behavior of all programs P defined by T does not change when all objects o1 are substituted for O2, then type S is a subtype of type T. In layman’s terms, subclasses can appear wherever a parent can, and replacing them with subclasses does not generate any errors or exceptions. The user may not need to know whether it is a parent or a subclass at all. However, the reverse is not true. Where there are subclasses, the parent class may not be able to adapt.
The principle of specification
1. Subclasses must fully implement the methods of their parent class. 2, Subclasses can have their own personality, Richter’s substitution principle can be used, but not the other way around. 3. Input parameters can be amplified when overwriting or implementing methods of the parent class. 4. The output can be reduced when overwriting or implementing methods of the parent class.
Inherit the advantage
1. Code sharing reduces the amount of class creation. Each subclass has the methods and attributes of its parent class. 2. Improve code reuse. 3. A subclass may resemble but differ from its parent. 4. Make your code more extensible. 5. Improve the openness of products and projects.
application
When we write programs, try to avoid overloading or rewrite the parent class is implemented, the method of abstract methods unrealized so it can override, because rewrite the superclass method realized may change the original behavior of the parent class, this will appear problem, replace the principle of 3, 4, also for subclasses can be replace the parent class, but such rewriting problems easily, So be careful. Richter’s replacement principle is to avoid people’s abuse of inheritance, check whether the inheritance relationship is really in line with, and consider whether the inheritance system can support future demand changes.
Dependency inversion principle
Dependence Inversion Principle,DIP.
The principle of specification
1. High-level modules should not depend on low-level modules; both should depend on their abstractions. 2. Abstraction should not depend on details. 3. Details should depend on abstraction.
The right approach: Abstract A depends on Abstract B, and implement detail B implements Abstract B
The dependency inversion principle is based on the fact that abstract things are much more stable than details. An architecture based on abstraction is much more stable than one based on detail. The realization of every logic is composed of atomic logic. The indivisible atomic logic is the low-level module, and the reassembly of atomic logic is the high-level module. In Objective-C, abstraction refers to delegation, and details are concrete implementation classes. The purpose of using interfaces or abstract classes is to establish specifications and contracts without involving any concrete operations, leaving the task of presenting details to their implementation classes.
benefits
The dependency inversion principle can reduce the coupling between classes, improve the stability of the system, reduce the risk caused by parallel development, and improve the readability and maintainability of code.
The sample
Bad design:
@interface BMW : NSObject - (void)BMWstart; @implementation BMW - (void) implementation BMWstart {NSLog(@" BMW is running "); } @end @interface Benz : NSObject - (void)Benzstart; @implementation Benz - (void)Benzstart {NSLog(@" Benz is running "); } @endCopy the code
We designed the BMW and Benz classes, each with a boot method, so that the design creates strong dependencies and does not use dependency inversion.
Good design:
@protocol CarProtocol <NSObject> - (void)start; @implementation BMW - (void)start {NSLog(@" BMW is running "); } @interface Benz: NSObject<CarProtocol> @end @implementation Benz - (void)start {NSLog(@" Mercedes-Benz "); } @endCopy the code