1. Single responsibility principle (SRP)
(1) Concept
The single responsibility principle is defined as: there should be only one reason for the class to change, that is, a class is responsible for only one responsibility.
For example, let Class C be responsible for two different duties: the responsibility p1,p2. When Class C needs to be modified due to a change in the duties P1 requirements, it is possible that the normal functions of the P2 function fail.
(2) Example
A class about user management is designed according to the following class diagram:
Obviously, the user's attributes and behavior are not separate, according to a single responsibility principle, it should be re-opened into two interfaces: User attribute interface Iuserbo, user behavior interface iuserbiz.
The code following the distinction between responsibilities is as follows:
New UserInfo (); // manipulating the user's properties Iuserbo Userbo = (Iuserbo) Userinfo;userbo.setpassword ("123"); // behavior of the action user Iuserbiz userbiz = (iuserbiz) userinfo;userbiz.delete (Userbo);
(3) Summary
The single principle of responsibility applies to interfaces, classes, methods, and a method that accomplishes one thing as much as possible. For example, a method of changing the password, do not put it in the modification of the user information of the big way to go, otherwise the responsibility of the method is not clear. But the excessive classification of duties will artificially increase the complexity of the system, such as the behavior of a class can be implemented in a hard split into two classes, and then use the aggregation or combination of the way together, man-made trouble. Because of the single responsibility of this "responsibility" does not have a quantitative standard, so the most difficult to divide is the responsibility, this is to be based on the actual situation and personal experience to decide.
2. Richter replacement principle (LSP)
(1) Concept
The Richter substitution principle targets a subclass and parent class that have an inheritance relationship.
The Richter substitution principle is defined as long as the parent class appears where subclasses can appear, and replacing them with subclasses does not produce any errors or exceptions.
Subclasses must fully implement the method of the parent class (the method cannot be empty). That is, the method of the parent class must be a subclass of all needs, if not all necessary, it violates the LSP principle.
When calling other classes in a class, you must use the parent class or interface, and if you do not use a parent class or interface, the design of the class violates the LSP principle.
(2) Example
A company has ordinary users and VIP users, they send the process of e-mail as follows:
The analysis found that ordinary users and VIP users send mail the same process, that is, two send () methods are duplicated. New types of users may also be added in the future, in order to make the system more scalable and refactor using the Richter substitution principle:
(3) Summary
The Richter replacement principle consists of the following 4 levels of meaning:
Subclasses must fully implement the method of the parent class (the method body is not empty);
Subclasses can have their own unique methods;
When overriding a method of a parent class, the input parameter can be magnified (the precondition for overriding the parent class method in the subclass must be the same or looser than the precondition of the overridden method in the parent class);
When overriding a method of a parent class, the output can be scaled down (the return value of the overridden parent class method in the subclass must be less than or equal to the return value of the overridden method in the parent class).
Of course, if you violate the LSP principle during programming, there will be no problem at runtime, but there will be many potential problems which will cause great difficulties for future changes and maintenance work.
3. Dependency inversion principle (DIP)
(1) Concept
The dependency inversion principle is defined as: there is no direct dependency between the implementation classes, and its dependencies are generated through interfaces or abstract classes. That is, interface-oriented programming.
Implements a class-dependent interface or abstract class, and an interface or abstract class is not dependent on an implementation class.
(2) Example
The class diagram of the driver driving the Mercedes Benz is as follows:
The implementation code is as follows:
// Driver's realization class Public class Driver { publicvoid Drive (Benz Benz) { benz.run ();} }
// Mercedes-Benz car implementation class Public class Benz { publicvoid run () { System.out.println ("Mercedes Benz ...") ); }}
// scene Invocation class Public class Scene { publicstaticvoid main (string[] args) { new Driver (); New Benz (); Driver.drive (Benz); }}
It seems that there is no problem with this design, but we often say that "in times of distress", it is technically "changed to show true Kung Fu". Now the driver not only has to drive a Mercedes, but also to drive a BMW. But the driver driver only to drive the Mercedes-Benz method, but did not start the BMW car method Ah, this is unreasonable. Here just add a car class to modify the driver class, which is unstable, variable. Referring to the principle of dependency inversion, the idea design class diagram with interface-oriented programming is as follows:
The implementation code is as follows:
// driver Interface Class Public Interface Idriver { publicvoid Drive (ICar car);}
// Automotive Interface Class Public Interface ICar { publicvoid run ();}
// Driver's realization class Public class Implements idriver { @Override publicvoid Drive (ICar car) { car.run ();} }
// Mercedes-Benz car implementation class Public class Implements ICar { @Override publicvoid run () { System.out.println ( "Mercedes Benz ..."); }
// the implementation of the BMW car class Public class Implements ICar { @Override publicvoid run () { System.out.println ("BMW car departure ..."); }}
(3) Summary
The essence of the dependency inversion principle is that the implementation of each class or module is independent of each other by abstraction (interface or abstract class), and the loose coupling between modules is realized.
Each class should have as much as possible an interface or abstract class, or both.
The surface type of the variable is as far as the interface or abstract class.
The dependency inversion principle makes it possible to have independent parallel development between classes without dependencies, and unit tests of two classes can be run independently of each other.
6 Design principles Detailed (b): http://www.cnblogs.com/LangZXG/p/6242927.html
6 design principles, with common design patterns (Overview): http://www.cnblogs.com/LangZXG/p/6204142.html
Class Diagram Basics: http://www.cnblogs.com/LangZXG/p/6208716.html
NOTE: Reprint please indicate source http://www.cnblogs.com/LangZXG/p/6242925.html
6 Design principles Detailed (i.)