Content Overview What are the six design principles of one, single responsibility principle two, the Richter substitution principle three, the dependence inversion principle four, the interface isolation principle Five, the Dimitri Law six, the open closure principle content elaboration one, the single responsibility principle
Single principle of responsibility: The English name is Responsiblity Principle, abbreviated as the SRP. Definition: There should be and only one cause for class changes.
A single responsibility principle requires that an interface or class has only one cause to change, that is, an interface or class has only one responsibility, and it is responsible for something.
Benefits of a single responsibility principle:
- The complexity of classes is reduced, and what responsibilities are defined clearly and clearly;
- Readability increases and complexity decreases, which of course improves readability;
- Maintainability is improved, readability is improved, which is of course easier to maintain;
- Change caused by the risk of reduction, change is essential, if the interface of a single responsibility to do a good job, an interface modification only to the corresponding implementation of the class has an impact on the other interfaces have no impact, which is the system's extensibility, maintainability has a great help.
Note: The single-responsibility principle presents a standard for programming, with "responsibility" or "reason for change" to measure whether an interface or class is well designed, but "responsibility" and "reason for change" are not measurable and vary from project to environment.
For a single responsibility principle, the interface must be a single responsibility, the design of the class as far as possible only one cause of change.
Second, the principle of the Richter replacement
The Richter replacement principle (Liskov Substitution PRINCIPLE,LSP) is defined in two ways:
- The first definition is also the most authentic definition: If for every object O1 of type S There is a object O2 of type T such that for all Programs P defined in ter Ms of T, the behavior of P is unchanged when O1 are substituted for O2 and S is a subtype of T. (if each object of type S is O1, there are objects of type T O 2, so that all the programs defined in T are replaced with O2 when all the objects O1, the behavior of the program P does not change, then the type S is a subtype of type T. )
- The second definition: Functions that use pointers or references to base classes must being able to use objects of derived classes without kno Wing it. (All references to base classes must be able to transparently use objects of their subclasses.) )
The second definition is clearest, and in layman's terms, whenever a subclass of the parent class appears, and the child class is replaced with no errors or exceptions, the consumer may not need to know the parent class or the child class at all. But on the other hand, there are sub-categories where the parent may not be able to adapt.
The Richter substitution principle defines a specification for good inheritance, and a simple definition contains 4 meanings:
- Subclasses must fully implement the method of the parent class;
- It is important to use the parent class or interface when calling other classes in the class, and if the parent class or interface cannot be used, the design of the class has violated the LSP principle;
- If a subclass cannot fully implement a method of the parent class, or if some of the methods of the parent class have "distorted" in the subclass, it is recommended that you break the parent-child inheritance relationship and replace the inheritance with dependencies, aggregation, composition, and so on.
- Subclasses can have their own personalities;
- Input parameters can be magnified when overriding or implementing a method of the parent class;
- If the input parameter type of the parent class is greater than the input parameter type of the subclass, where the parent class exists, the subclass may not necessarily exist, because once the handle class is passed in as a parameter, the caller is likely to enter the subclass's method category;
- The precondition of a method in a subclass must be the same as or looser than the precondition of the method being overridden in the superclass.
- The output can be scaled down when you overwrite or implement a method of the parent class.
- The return value of a method of a parent class is a type T, and the return value of the same method (overloaded or overridden) of the subclass is S, then the Richter substitution principle requires s to be less than or equal to T, that is, either s and T are the same type, or S is a subclass of T.
The purpose of using the Richter replacement principle is to enhance the robustness of the program and to maintain very good compatibility when the version is upgraded. Even if you add subclasses, the original subclasses can continue to execute.
Iii. the principle of dependency inversion
The dependency inversion principle (dependence inversion Principle,dip), the original definition is: High level modules should not depend upon low level modules. Both should depend upon abstractions. Abstractions should not depend upon details. Details should depend upon abstractions.
Contains three levels of meaning:
- High-level modules should not rely on the underlying modules, both should be dependent on abstraction;
- Abstraction should not depend on details;
- Detail should be dependent on abstraction.
High-rise modules and low-level modules are easy to understand, each logical implementation is composed of atomic logic, the indivisible atomic logic is the underlying module, the re-assembly of atomic logic is a high-level module.
In the Java language, abstract refers to an interface or abstract class, both of which are not directly instantiated, the details are the implementation of the class, implement the interface or inherit the abstract class is the result of the class is the details, which is characterized by a direct instantiation, that is, you can add a keyword new to produce an object. The dependency inversion principle behaves in the Java language:
- Dependencies between modules occur through abstraction, and there is no direct dependency between classes, and their dependencies are generated through interfaces or abstract classes;
- An interface or abstract class is not dependent on the implementation class;
- Implements a class-dependent interface or abstract class.
A more streamlined definition is one of the essences of "interface-oriented Programming"--ood (object-oriented design, object-oriented designs).
Three ways to rely:
Dependencies can be passed, a object depends on the B object, B is dependent on c,c and depends on D ... Endless, rely on more than, remember a point: as long as the abstract dependence, even multi-layered reliance on the delivery of fear!
There are three ways to pass an object's dependencies:
- The constructor passes the dependent object---in the class by declaring the dependent object through the constructor, which is called constructor injection, according to the argument of dependency injection.
- Setter methods pass dependent objects---Set setter method declaration dependencies in the abstraction, which is the setter dependency injection, according to the injected argument.
- Declaring a dependent object in the method of an interface is also called interface injection.
The essence of the dependency inversion principle is that by abstracting (interfaces or abstract classes) The implementations of each class or module are independent of each other and do not interact with each other to achieve loose coupling between modules, how do we use this rule in a project? As long as you follow these rules, you can:
- Each class has as much as possible an interface or abstract class, or abstract classes and interfaces are both available;---this is the basic requirement of dependency inversion, an interface or abstract class is abstract, and an abstraction can rely on inversion.
- The surface type of the variable is as far as the interface or abstract class;
- No class should derive from a specific class;
- Try not to overwrite the base class method;---If the base class is an abstract class and this method has been implemented, the subclass should try not to overwrite it. The dependence of the class is abstract, and the abstract method is covered, which has a certain effect on the stability of dependence.
- Combined with the Richter replacement principle. ---Interface is responsible for defining public properties and methods, and for declaring dependencies with other objects, the abstract class is responsible for the implementation of the common Construction section, implementing the class to implement the business logic accurately, and at the appropriate time to refine the parent class.
Iv. Principle of interface Isolation
The interface is divided into two types:
- Instance interface (Object Interface), declares a class in Java, and then produces an instance with the New keyword, which is a description of a type of food, which is an interface.
- Class Interface, the interface defined by the Interface keyword commonly used in Java;
- Clients should not being forced to depend upon interfaces that they don ' t use. (The client should not rely on interfaces it does not need.) )
- The dependency of one class to another one should depend on the smallest possible interface. (The dependencies between classes should be based on the smallest interface.) )
The interface isolation principle is a canonical constraint on an interface that contains the following 4-layer meanings:
- The interface should be as small as possible,---this is the core definition of the interface isolation principle, there is no bloated interface (Fat Interface), but "small" is limited, first of all, can not violate the principle of single responsibility.
- interface to high cohesion,---high cohesion is to improve the interface, class, module processing capacity, reduce external interaction. In the interface to publish the public method as little as possible, the interface is a commitment to the external, the less commitment to the development of the system more favorable, the risk of change is less, but also the more conducive to reduce costs.
- Custom Service;---a system or a module within a system is bound to have a coupling, coupled with the interface (not necessarily defined in Java interface, or a class or pure data exchange), we need to design for each visitor (that is, the client) to customize the service. Custom service is to provide an individual with excellent service. We also need to consider customizing the interface between the system or the module when we do the system design. There must be a requirement to use a custom service: only the methods that the visitor needs are provided.
- There is a limit to the design of the interface. The smaller the design granularity of the---interface, the more flexible the system, which is an indisputable fact. However, the flexibility has also brought about the complexity of the structure, the development difficulty increases, maintainability is low, this is not a project or product expected to see, so the interface design must pay attention to moderation, this "degree" how to judge? Based on experience and common sense, there is no fixed or measurable standard.
The interface isolation principle is the definition of an interface, as well as the definition of a class, where interfaces and classes are assembled using atomic interfaces or atomic classes whenever possible. However, how this atom is divided is a major problem in the design pattern, which can be measured in practice according to the following rules:
- An interface serves only one module or business logic;
- Through the business logic compression interface in the public method, the interface often to review, as far as possible to get the interface to "flesh", rather than "fat doodle" a lot of methods;
- has been contaminated with the interface, as far as possible to modify, if the risk of a large change, the use of adapter mode for conversion processing;
- Understand the environment and refuse to follow blindly. Each project or product has specific environmental factors, don't look to the master to do so you copy. Do not, the environment is different, interface split standards are different. In-depth understanding of business logic, the best interface design comes from your hands!
V. The law of Dimitri
The Dimitri rule (law of Demeter, LoD) is also known as the least-knowledge principle (Least knowledge principle,lkp), although the names are different, but the same rule is described: An object should have minimal knowledge of other objects. In layman's words, a class should know the least about the classes that it needs to be coupled or called, and how complex the internals of your (coupled or called classes) are to me, that's your business, and I know that you provide so many public methods that I call so much that the rest of me doesn't care.
The Dimitri Law provides a clear requirement for low coupling of classes, which contains the following 4 meanings:
- Communicate with friends only---the Dimitri Law also has an English explanation: only conversation to your immedate friends (communicates only with direct friends. What is a direct friend? Each object is bound to have a coupling relationship with other objects, and the coupling between two objects becomes a friend, and there are many types of relationships, such as composition, aggregation, dependency, and so on. The definition of a friend class: The class that appears in the member variable, the input and output parameters of the method is called the member Friend class, and the class that appears inside the method body does not belong to the friend class. Note: A class only communicates with friends, does not communicate with unfamiliar classes, does not appear geta (). GETB (). GetC (). GETD () This situation (in an extreme case allows such access, that is, the return type is the same after each point), the relationship between classes and classes is built between classes , not between methods, so a method tries not to introduce objects that do not exist in a class, except, of course, the classes provided by the JDK API.
- There's a distance between friends, too.---A class exposes more public properties or methods, the larger the area involved in the modification, the greater the risk spread caused by the change. Therefore, in order to maintain the distance between friends, the design needs to be repeatedly measured: whether the public methods and properties can be reduced, whether it can be modified to private, package-private (package type, without access to classes, methods, variables, the default is the package type), Protected such as access, whether you can add the final keyword, and so on. Note: Dimitri Law requires the class "shy" point, try not to publish too many public methods and non-static variables, as far as possible introverted, more use of private, package-private, protected and other access rights.
- It's your own---. If a method is placed in this class, that is, the relationship between classes is not increased, and the class is not negatively affected, it is placed in this class.
- Careful use of serializable
The core concept of Dimitri Law is the decoupling between classes, weak coupling, and the reuse rate of classes can be improved only after weak coupling. The result of the request is that a large number of relays or jump classes are produced, which leads to the complexity of the system and the difficulty of maintenance.
The Dimitri rule requires decoupling between classes, but there is a limit to decoupling, unless it is the smallest unit of the computer-binary 0 and 1. That is the complete decoupling, in the actual project, need to consider this principle moderately, do not use the principle to do the project. The principle is only for reference, if violates this principle, the project also may not fail, this needs everybody in the adoption principle to measure repeatedly, does not follow is not correct, strictly executes is "the overkill".
Vi. the principle of open closure
Definition of the Open closure principle: Software entities like classes, modules and functions should is open for extension but closed for modifications. (a software entity such as classes, modules, and functions should be open to extensions and closed for modification.) The implication is that a software entity should be extended to achieve change. Soft entities include the following sections:
- A module divided by a certain logical rule in a project or software PRODUCT;
- Abstraction and class;
- Method.
As long as a software product changes in the life cycle, since change is an established fact, we should try to adapt to these changes in design so as to improve the stability and flexibility of the project, and truly realize "embrace change". The open closure principle tells us that we should try to achieve change by extending the behavior of the software entity, rather than modifying the existing code to complete the change, which is a principle of constraining the current development design for the future events of the software entity.
Open closure principle of open, to modify the closed, does not mean that no changes, low-level module changes, must have high-layer modules to be coupled, otherwise is an isolated meaningless code fragment. We can sum up the following three types of changes:
- Logical change---only one logic is changed, not other modules, such as the original algorithm is a*b+c, now needs to be modified to a*b*c, can be modified by the method in the original class, the precondition is that all the dependencies are handled according to the same logic.
- Sub-module changes,---A module change, will affect other modules, in particular, a low-level module changes are bound to cause the change of the high levels of the module, so in the expansion to complete the changes, high-level module modification is inevitable.
- Visible view Changes---visible view is provided to customers using the interface, such as JSP program, swing interface, and so on, this part of the changes will generally cause a chain reaction (especially in the domestic project, do the European and American outsourcing projects generally will not affect too much). If only the interface buttons, text rearrangement is simple, the most common is the business coupling change, what meaning? A list of display data, according to the original demand is 6 columns, suddenly one day to add 1 columns, and this column to cross n tables, processing m logic to show out, such a change is more scary, but still can be extended to complete the change, it depends on our original design is flexible.
Why should we adopt the principle of open closure:
Every thing's birth has its existence necessity, exists namely is reasonable, that the opening and closing principle existence is also reasonable, why say so?
First, the open and close principle is so well-known, as long as the object-oriented programming, no matter what language, Java or C + +, or Smalltalk, in the development will mention the opening and closing principle.
Second, the open and close principle is the most basic principle, the principle is described in the opening and closing principle of the specific form, that is to say the first five principles is to guide the design of tools and methods, and closed-closed principle is its spiritual leader. In other words, according to the Java language appellation, the opening and closing principle is abstract class, the other five principles are concrete realization class, the opening and closing principle in the field of object-oriented design is similar to Newton's first law in mechanics, tick the law of the geometry, mass energy equation in the special theory of relativity, its status no one can.
Finally, the open and close principle is very important, can be understood by the following aspects of its importance.
1. The effect of opening and shutting principle on testing
All the code that has been put into production is meaningful and is subject to the rules of the system, so that the code goes through the "thoroughly tempered" test process, not only to ensure that the logic is correct, but also to ensure that the harsh conditions (high pressure, anomalies, errors) do not produce "toxic Code (poisonous)", So when there is a change, we need to consider whether the original robust code can be changed without modification, just by extending it. Otherwise, it is necessary to return the original test process, the need for unit testing, functional testing, integration testing and even acceptance testing, although in the vigorous promotion of automated testing tools, but still can not replace the manual testing work.
2. The principle of opening and closing can improve the reusability
In object-oriented design, all logic is composed of atomic logic, rather than implementing a business logic independently in a class. Only then can the code be reused, the smaller the granularity, the greater the likelihood of being reused. Then why re-use it? Reduce the amount of code, avoid the same logic scattered in multiple corners, to avoid the future maintenance staff in order to modify a minor flaw or add new features to the entire project to find the relevant code, and then issued a sense of "extreme disappointment" to the developer. How can we improve the rate of reuse? Reduce the logical granularity until a logical is no longer split.
3. The opening and closing principle can improve maintainability
After a software is put into production, maintenance personnel work not only to maintain the data, but also to extend the program, the maintenance staff is most willing to do is to expand a class, rather than modify a class, don't care how good the original code is written or how bad, so that the maintenance personnel read the code of the original code, and then modify, is a very painful thing, do not let him in the original code in the sea after the end of the tour and then modify, it is a maintenance of the staff of a torture and destruction.
4, object-oriented development requirements
Everything is object, we need to abstract all things into objects, and then operate on the object, but all things are moving, there are changes in motion, there will be a change of strategy to deal with, how to respond quickly? This requires taking into account all possible changes at the beginning of the design, and then leaving the interface, waiting for "possible" to turn into "reality".
How to use the open and closed principle
1. Abstract constraints
Abstract is a general description of a set of things, no specific implementation, it can be a lot of possibilities, can follow the changes in demand changes. Thus, an interface or an abstract class can constrain a set of potentially changing behaviors and be able to open up to the extension, which contains three meanings: first, the extension is bounded by an interface or abstract class constraint, and the public method that does not exist in the interface or abstract class is not allowed; second, the parameter type, Reference objects use interfaces or abstract classes as much as possible, rather than implementing classes; Thirdly, the abstraction layer remains as stable as possible, and modifications are not allowed once determined.
2. Meta data (metadata) control module behavior
Programming uses metadata to control program behavior and reduce duplication of development. Data used to describe the environment and data, in layman's terms, configuration parameters, parameters can be obtained from the file, can also be obtained from the data library.
3. Develop the project charter
In a team, it is very important to establish a project charter, because the regulations specify the conventions that all personnel must abide by, and the agreement is better than the configuration for the project. Believe that you have done the project, you will find that a project will produce very many configuration files. As an example of SSH project development, there is a lot of bean configuration files in a project and management is cumbersome. If you need to expand, you need to add subclasses and modify the Springcontext file. However, if you specify such a regulation in your project: All beans are automatically injected, assembled using annotation, extended, even with only one class written, and then generated by the persistence layer, the others do not need to be modified, which requires in-project constraints, which each member of the project must follow, This method requires a team to have a high degree of self-awareness, need a long time to run, once the project members are familiar with such rules, more than through the interface or abstract class constraints more efficient, and no less extensibility.
4. Package Changes
The package of changes contains two meanings: first, the same changes are encapsulated in an interface or abstract class, and secondly, different changes are encapsulated in different interfaces or abstract classes, and there should not be two different changes appearing in the same interface or abstract class. Package changes, which are protected changes (protected variations), identify the points that are expected to change or are unstable, we create a stable interface for these points of change, which is precisely the possible change in encapsulation, and once the predicted or "Sixth sense" detects a change, it can be encapsulated, Each of the 23 design patterns is encapsulated from different angles, and we will step through each of these patterns.
PYTHON6 Large Design Principles