This is the 20th day of my participation in the More text Challenge. For more details, see more text Challenge
👉 Design mode directory
Design mode is a specific way to realize the seven design principles. In actual development, the design mode should not be mechanically applied, but should be learned and applied to reflect the seven design principles. In the final analysis, design mode is the seven design principles.
In practical application, we should choose the appropriate design pattern according to the requirements, not for the sake of using the design pattern. It is suggested that if there is no suitable design pattern at the beginning, we can consider not using the design pattern, but must abide by the seven design principles. It is also important to avoid overdesigning, not to hardcopy the design pattern and make the program very complex. It is also important to reduce the complexity of the program.
Not only can we learn the classic 23 design patterns to have a more profound understanding of the seven design principles, but also can learn the design patterns and the seven design principles through excellent open source code, and accumulate development experience in the accumulated programming
Seven Design Principles
The purpose of the seven design principles is to improve the system’s reusability, reliability, readability, scalability, and finally achieve low coupling and high cohesion.
Do you think you’ve seen it somewhere?
Yes, I’ve written about the purpose of design patterns, and the seven Design principles are rules around these purposes.
preface
This period of time is also relatively free, so I want to learn to improve themselves.
I’ve always heard that there are seven design principles, and five or six, but they’re all the same, just more or less. The predecessors seven design principles are summed up of object-oriented development experience, but also the root of the 23 design patterns, I think is very necessary to study, I believe that after learning about the improvement of their own programming, and determine the future direction of a big help, before also has been ignored, actually to learn design patterns, a little put the cart before the horse.
My personal interview answers are provided at the end of the article, which can be dropped to the bottom.
Open and closed principle
The Open Closed Principle (OCP) was proposed by Bertrand Meyer, In his 1988 book Object Oriented Software Construction, he argued that Software entities should be open to extension but closed to modification.
Software entity:
- The modules that are divided into a project
- Classes and interfaces
- methods
concept
Software entities should be open to extension, but closed to modification. This means that software entities should implement changes by extending new code, rather than modifying existing code.
purpose
- Reduce the impact on software testing. Following the open and closed principle, only new extensions need to be tested each time new code is added.
- Reduce development risks. Each new requirement or system change can be accomplished by adding a different code, rather than modifying the original code, which can be used in case of an error.
- ** Improve the reliability and scalability of software. ** Abide by the open and closed principle, easier to expand and maintain.
- Improved code reusability.
implementation
To use the open closed principle, try using the following rules:
- Abstract constraints, closed changes
If you want to implement the open closed principle in Java (an object-oriented language), you can do so by using the rule “Abstract constraints, close changes.”
“Change” abstract constraints, and closed it is specific, define a stability (no longer) of the abstract class or interface, used to expand the boundary limit, then write details changes to implementation class, there are new changes will create a new entity class, you want to use these implementations use interface or abstract class as reference object.
In this case, class C only accesses the reference object of the interface, and the actual implementation of the application object is implemented by classes A and B.
These are entities for classes and interfaces.
- According to demand analysis
In the module design, should consider that those inside the module do not need to be modified, do not need to be modified are some low-level code, these are nothing to say, well written on the line; Design ahead of time for extensions that are possible in the short term or that are cheap to extend, adding manageable extension points, for example, through configuration file extensions (for example, write a new processing class if you want to switch to another processing class), Then modify the configuration file), extend by passing in parameters (using parameters to call different processing classes), etc. (this depends on my level of development, which is just my experience here), and minimize changes to the original code.
This is for modules and methods.
conclusion
All of the other design principles are aimed at the open and closed principle, that is, the realization of the other principles, the realization of the open and closed principle. The open and closed principle is also the goal of all software design — to get the business done without changing the code, which of course needs to be changed and added before the software is ready.
Richter’s substitution principle
The Liskov Substitution Principle, LSP was proposed by Ms. Liskov of MIT Computer Science Laboratory in an article Data Abstraction and Hierarchy published at OOPSLA in 1987, She asked: Inheritance should ensure that any property proved about supertype objects also holds for subtype Objects).
Inheritance: In object-oriented languages, inheritance is the ability of a child class to inherit member properties, member methods, and constructors from its parent class.
Advantages of inheritance:
- Realize code sharing and improve code reuse
- To improve the extensibility of the code, subclasses can have their own features
Inherited faults:
- Inheritance is intrusive; a child class has the properties and methods of its parent class, and the child class is constrained to some extent, which reduces the flexibility of the code
- Added coupling, so that once the superclass method is changed, the subclass method may need to be changed
concept
The Richter substitution principle is mainly about the principles of inheritance, and by studying the Richter substitution principle, you can also learn when to use inheritance and when not to use inheritance.
In general terms, the Richter substitution principle means that a subclass can extend the function of its parent class, but cannot change the original function of its parent class.
The subclass can replace the parent class without any impact, that is, the subclass can be used directly to replace the parent class, and vice versa.
purpose
- ** Improves code reusability. ** The Richter substitution principle overcomes the disadvantage of reusability caused by overwriting the parent class by inheritance.
- The Richter substitution principle gives the proper use of inheritance without introducing new errors into the system as classes are extended.
- The reliability and maintainability of the program are strengthened.
implementation
The use of the Richter substitution principle:
- A child class may implement abstract methods of its parent class, but it cannot override non-abstract methods (public methods) of its parent class.
- Subclasses can add their own unique methods.
- When a subclass overloads a method of the superclass, the input parameters of the method are looser than those of the superclass (looser means that the interface can be used instead of the class).
- When a child class implements an abstract method of the parent class, the return value of the method is stricter or equal to that of the parent class (strict means using a concrete implementation class instead of an interface or abstract class).
So many rules are used in order to satisfy the ** program in the parent class can be replaced by a child class, but the child class can not be replaced by the parent class. ** also has to comply with the above four rules to be able to use inheritance, otherwise you have to consider using other ways to implement.
conclusion
In my opinion, the Richter substitution principle limits the use of polymorphism and reduces unnecessary polymorphism, thus reducing the complexity of using inheritance.” A child class may implement an abstract method of its parent class, but it cannot override a non-abstract method of its parent class. “Personally, I think this rule is also important. This rule reduces the degree of coupling between the subclass and the superclass. If you do not follow this rule, the subclass and the superclass will be treated like two unrelated classes.
Principle of dependence inversion
concept
The original definition of the dependency inversion principle is: high level modules should not depend on low level modules, both should depend on their abstractions; Abstractions should not depend on details; details should depend on abstractions. The idea is to program to interfaces, not implementations.
Low-level modules are generally those that are called, such as connecting to a database, sending network requests, and operating IO modules. The high level is the module that calls the low level to implement the business logic.
The dependency inversion principle is advocating interface oriented programming.
purpose
- Reduced coupling between classes. Using an interface or abstract class as a reference object is a good substitute for other subclasses.
- Reduce the risks of parallel development. Using interfaces or abstract classes as reference objects can reduce the contradiction of multi-person parallel development.
- ** Improves code readability. ** After we see an interface, we can know what the object referenced by the interface is, and we don’t have to go into the bottom of it.
- The scalability of the system is improved. If you use an interface as a declared object, you can refer to objects under that interface.
implementation
Rules for the use of the dependency inversion principle:
- Each class implements an interface, an abstract class, or both.
- ** Use an interface or abstract class to declare variables. ** Do not directly point the declaration to the implementation class in case you want to switch to another type of object later.
- Follow the Richter substitution principle when using inheritance.
conclusion
Dependency inversion is similar to Richter substitution in that it promotes programming towards interfaces, whereas Richter substitution makes some provision for the use of inheritance. Dependency inversion uses the Richter substitution principle and later the interface isolation principle.
My personal feeling is that the rule “use interfaces and abstract classes for variable declarations” can make our modules or methods more applicable to more than just one implementation class, reducing the degree of coupling between classes.
Single responsibility principle
The Single Responsibility Principle (SRP), also known as the Single function Principle, was developed by Robert C. Robert C. Martin in Agile Software Development: Principles, Patterns, and Practices. There should never be more than one reason for a class to change. The single responsibility principle states that a class should never have more than one reason for a class to change.
concept
The official definition is that a class should have one and only one cause for changes.
In other words, the responsibilities of a class (what it does) should be single, not multiple responsibilities for a class. The division of responsibilities here is very important, and I don’t think the concept of this principle needs to be said.
purpose
- Reduce class complexity and coupling, improve class cohesion and reusability.
- Improve class readability.
- Improve code reliability.
- Reduce the risk of code changes.
implementation
The single responsibility principle is simple to say, but very difficult to apply in practice. To use the single responsibility principle, in a word, define the responsibilities of classes and modules, and control the granularity of responsibilities. The division of responsibilities requires designers to have some experience and analysis of requirements, and try to arrange a class to do only one thing.
As an example from my experience, we all need to connect to the database and do the business logic. If we arrange these two things on one class, the operation of connecting to the database will not be reused, and every time we change the business logic, it will become very troublesome. The separation of database and middleware is also to ensure that each thing only does one thing. The database only manages data, and the middleware like Kafka only does message queues, which makes them very reusable and powerful.
conclusion
My personal feeling is that this single responsibility principle makes the class or method and module internal more independent, reducing the possibility of changing the class as requirements change. But to use the single responsibility principle well, you have to rely on your own development experience. Every time you design the structure of a class, you have to think about how can you make a class do everything in one area? Does this make development more difficult?
Interface isolation Rule
In 2002, Robert C. Martin defined the “interface isolation principle” as: Clients should not be forced to depend on methods they do not use. There is another definition of this principle: The dependency of one class to another should depend on The smallest possible interface. The dependency of one class to another should depend on The smallest possible interface.
An interface can be used as a reference object in Java, and then the reference object provides only the abstract methods declared in the interface.
concept
A class’s dependency on another class should be based on the smallest interface, and a client program should not rely on interface methods it does not need. In short, provide the user with the methods he or she will use, and try to block out the ones he or she won’t use.
purpose
- The complexity of the interface is reduced, the cohesion of the interface is improved, and the coupling degree of the system is reduced.
- Improve class readability, extensibility, and reusability.
- Reduce redundant code. Reduce forced implementations caused by interface oversize.
implementation
Rules that use the interface isolation rule:
- Interfaces should not be too large. An interface should be defined to do a certain type of method.
- Customize the interface to provide only the methods that the caller wants.
- Improve cohesion so that interfaces can fulfill requirements with a minimum of methods.
Try to assign the same type of operation to an interface; an interface does not need to provide many operations.
Here’s how interfaces are separated:
- ** Separate interfaces using delegates. ** This is not quite clear to me, but I think it should be determined by which interface to use in delegate.
- ** Separate interfaces using multiple inheritance. ** This is a simple way to divide an interface into multiple interfaces, which are grouped together using Java’s interface multiple inheritance.
conclusion
The interface isolation principle is similar to the single responsibility principle. Interface isolation is for interfaces, and single responsibility is for classes. However, interface isolation plays a role in single responsibility to some extent. Interface isolation constrains the class that implements this interface and the overall interface to the system, while a single responsibility constrains the class’s implementation.
In general, interface isolation, Richter substitution, and single responsibility define the implementation of interfaces, inheritance, and classes, respectively. Dependency inversion promotes interface programming, and these three principles are complementary to each other.
Demeter’s law
The Law of Demeter (LoD), also known as the Least Knowledge Principle (LKP), A 1987 research project at Northeastern University called Demeter, proposed by Ian Holland and popularized by Booch, one of the founders of UML, Later, it was widely mentioned in The classic book “The Pragmatic Programmer.”
concept
Law of Demeter: Talk only to your immediate friends. One object should know as little about another as possible. Don’t talk to strangers. That is, **, a software entity should interact with other entities as little as possible ** (calling other entities’ methods).
An emphasis on reducing coupling, minimizing interactions and dependencies between classes, can also improve class reusability.
purpose
- Reduce coupling and dependencies between classes and increase the degree of class independence. Modules are also applicable.
- Improve class reusability and system extensibility.
implementation
Demeter’s law emphasizes that a class should talk to “friends,” which are the member variables, the input and the input parameters of a method, and not the “friends” inside the body of a method.
Rules using Demeter’s law:
- In class design, the priority should be to create a class that will never change.
- Weakly coupled classes should be created to increase class independence. Consider applying the single responsibility principle.
- Reduced access to class member methods. Provide only the necessary methods for other classes to use.
- Provide get and set methods without exposing member attributes. Reduce the number of situations where you communicate directly with strangers over your friends.
- Reduce the number of references to other objects.
conclusion
Demeter is at the heart of to reduce each kind of dependence on other classes, that is a kind of tooling may most rely on a few “friend”, and then these “friends” class will go to rely on its “friends” class, rather than a class directly dependent on multiple classes, this can let each class to form a small module, has the certain independence.
Excessive use of Demeter may lead to a middle class is too much, can lead to system is complicated, and reduce the efficiency of communication between modules, so when use should be appropriate to consider the needs of the business, in the promise not to increase system complexity, makes the relationship between modules clearer to use of Demeter.
Principle of composite reuse
concept
Composite Reuse Principle (CRP) is also called Composition/Aggregate Reuse Principle (CARP). It requires that in software reuse, we should first use the association relationship such as composition or aggregation, and then consider the inheritance relationship.
purpose
- Improves the encapsulation and cohesion of the system. Because inheritance exposes the member variables and method implementations of the parent class to the subclass, if the parent class changes, the subclass also has to change.
- Make the system more flexible and reduce the degree of coupling between classes. The coupling between classes is not high. If you want to use it, you can create it, if you don’t need it, you can delete it. You don’t need to change the logic of the class.
- Improved class reusability.
implementation
The principle of composite reuse does not have too many rules. Only the existing objects need to be used as member objects to achieve reuse. When creating member objects, the principle of dependency inversion should be followed.
conclusion
Reuse is divided into inheritance reuse and composition reuse.
Inheritance reuse is to reuse methods and member attributes in the parent class by inheritance. Synthetic reuse is achieved by directly calling an existing object.
Inheritance is a very intrusive way. The degree of coupling between the parent class and the child class is greatly improved. If the parent class changes, the child class also changes, and the methods and member attributes of the parent class are exposed to the child class, breaking encapsulation and reducing flexibility.
And synthetic reuse can reduce the invasion, but also is not to say do not use inherited, or in some cases using inheritance will be appropriate, for example, some of the same methods need to be used in certain classes, members may attribute to also want to use, these classes are in the same module, this case USES the inherited way will be more convenient, If synthetic reuse is adopted, it may increase the programming difficulty. But the use of inheritance must be followed by the Richter substitution principle.
The last
This is the introduction to the seven design principles. The ultimate purpose of these principles is to reduce the coupling between objects, improve the cohesiveness of classes, and increase the reliability, readability, and extensibility of programs. The 23 design patterns are all based on the seven design principles. When I study design patterns later, I can see more of these seven principles.
This is a memory formula I saw from the Internet.
Memory formula: access restrictions, frugal functions, not allowed dependencies, dynamic interfaces, abstract superclasses, extensions do not change.
While in the process of development is to keep the seven principles of software design basis, but want to be in the actual development process in full compliance with the seven principles may bring greater cost to develop, so we should comprehensive practical development scenarios, combined with the cost, not the pursuit of perfect follow the seven principles, have taken, These seven principles can help us design more elegant code structures that are more appropriate for today.
Among the seven design principles, the Richter substitution principle and the dependency inversion principle must be observed. Neither of these two principles need to be weighed. Richter substitution is used when inheritance is used, so the weighing is whether inheritance is needed, not whether this principle is used. Other principles require some tradeoffs and development experience. In my opinion, the open and Closed principle and the interface isolation principle are best to follow. There is nothing to trade off, but the specific implementation needs some development experience. The principle of single responsibility, Demeter’s law and the principle of composite reuse need to be determined according to the specific business to determine whether to comply with the degree of compliance, and also need some development experience. It can be said that in addition to the Richter substitution principle and the reliance on inversion, all the others need to be learned in the daily development, which requires us to keep an eye on the daily development.
Here I make a list of the properties of each of the seven principles, with + for yes and – for no.
The principle of | reusability | reliability | readability | scalability | Low coupling and high cohesion | The complexity of the |
---|---|---|---|---|---|---|
Open and closed principle | + | + | – | + | + | + |
Richter’s substitution principle | + | + | – | + | – | – |
Principle of dependence inversion | + | + | + | + | + | – |
Single responsibility principle | + | + | + | – | + | – |
Interface isolation Rule | + | + | + | + | + | – |
Demeter’s law | + | – | – | + | + | + |
Principle of composite reuse | + | + | – | + | + | + |
The interview template
Here is a sample interview answer that you can change and use. I probably interviewed nearly 30 times, that is one encounter, you can also take this as a summary, this is just my personal answer, there are better answer template can also be sent out to discuss.
Interviewer: What do you know about the seven Design Principles?
A:
The seven design principles I’ve read aim to reduce coupling between objects and increase reusability, extensibility, and maintainability. It can be said that the object oriented programming must abide by the seven principles.
The seven design principles include the open and Closed principle, which is open for extension and closed for modification. This means that you do not modify the code already written, but only write new code to extend new functions, which can reduce the risk of each change to the system. The Richter substitution principle, the subclass can extend the function of the superclass, but can not change the original function of the superclass, the specific use is that the subclass should not override the method in the superclass, it stipulates the use method of inheritance, can reduce the abuse of polymorphism, but also reduce the coupling degree of the parent class. The dependency inversion principle is that high-level modules should not depend on low-level modules, both should depend on their abstractions; Abstractions should not depend on details, details should depend on abstractions; In short, it encourages us to use interfaces, which reduce the degree of coupling between classes and facilitate code upgrades and extensions. The single responsibility principle, that a class should have one and only one cause for change, that is, a class should only do one thing, improves code reading and improves class independence. The principle of interface isolation, where a class’s dependency on another class should be based on the smallest interface; A client program should not rely on methods of interfaces that it does not need. That is, an interface should be simplified and a complex interface should be broken down into smaller interfaces, which can reduce the complexity of the interface and thereby improve the cohesion of the interface and implementation classes. Demeter’s law, also known as the least knowledge law, states that a software entity should interact with as little as possible with other entities. Each class should rely only on member attributes, method input parameters, and return values, and no other class should directly rely on them. Composite reuse principle, it demands on the software reuse, try to use combination or aggregation relationships first, then consider using inheritance to achieve, as inheritance reuse is increases the coupling degree of two classes, and synthesis of reuse will not increase the coupling degree, more flexible, and can lower the coupling degree of code. (The introduction of the previous can be said, is really need to back some things)
While it is best to follow these seven design principles during the development process, the actual application depends on the business needs and actual scenarios.
The last of the last, I was unexpectedly seven design principles took me nearly five days, may do a little more content, and also haven’t write an article for a long time, so a bit slow progress, it’s a bit beyond my expectations, in the back when studying design patterns, I will also speed up, get in a month, then you can open my trip to source.