“This article has participated in the good article call order activity, click to see: back end, big front end double track submission, 20,000 yuan prize pool for you to challenge!”
I. Definition of the interface isolation principle
Clients should not be forced to depend upon interfaces that they don’t use. The client depends only on the interfaces it needs; It provides the interfaces it needs and weeds out the ones it doesn’t.
The dependency of one class to another one should depend on the smallest possible interface. Dependencies between classes should be built on the smallest interface.
In other words, the interface should be as detailed as possible, with as few methods in the interface as possible
Interface isolation principle and single responsibility principle
Functionally, both the interface isolation principle and the single responsibility principle are intended to improve class cohesion and reduce coupling between classes, reflecting the idea of encapsulation. But there is a difference.
(1) From the perspective of principle constraints: The interface isolation principle pays more attention to the isolation of interface dependency; The single responsibility principle focuses more on the division of interface responsibilities.
(2) From the point of view of the degree of interface refinement: The single responsibility principle divides interfaces in a more detailed way, while the interface isolation principle focuses on the isolation of interfaces with the same function. The smallest interface in interface isolation can sometimes be multiple public interfaces for a single responsibility.
(3) The single responsibility principle is more oriented to business constraints: the interface isolation principle is more oriented to design architecture constraints. This should be easy to understand. Responsibilities are divided according to business functions, so a single principle is more business oriented; Interface isolation, on the other hand, is more for “high cohesion”, which is biased towards architectural design.
Iii. Advantages of the interface isolation principle
The interface isolation rule is designed to restrict interfaces and reduce the dependency of classes on interfaces. Following the interface isolation rule has the following five advantages.
- Decompose the bloated interface into multiple small-grained interfaces to prevent the spread of external changes and improve the flexibility and maintainability of the system.
- Interface isolation improves system cohesion, reduces external interaction, and reduces system coupling.
- If the granularity of the interface is properly defined, the stability of the system can be ensured. However, if the definition is too small, the number of interfaces will be too large and the design will be complicated. If the definition is too large, there is less flexibility to provide customized services, bringing unexpected risks to the overall project.
- The use of multiple specialized interfaces can reflect the hierarchy of objects, because the overall interface can be defined through interface inheritance.
- It can reduce code redundancy in project engineering. Large interfaces often have many different methods in them, forcing redundant code when implementing the interface.
Iv. Implementation method of interface isolation principle
When applying the interface isolation principle in detail, it should be measured against the following rules. 1) The Interface should be as small as possible to avoid Fat Interface; But to a certain extent, first of all, do not violate the single responsibility principle (no one interface for half responsibility).
2) The interface should be highly cohesive. Expose as few public methods as possible in the interface. Interfaces are commitments to the outside world, and less commitment is more beneficial to the development of the system.
3) Custom services provide only the methods that visitors need. For example, IComplexSearcher interfaces are provided for administrators and ISimpleSearcher interfaces are provided for public networks.
4) Interface design is limited to understand the environment, refuse to blindly follow. Each project or product has selected environmental factors, different environments, different criteria for interface splitting, requiring in-depth understanding of the business logic.
Recommendations on interface isolation principles
- An interface only serves one submodule or business logic;
- Compress public methods in the interface through business logic;
- The interface has been contaminated, try to modify; If the risk of change is high, adaptor pattern transformation is adopted.
- Refusing to follow blindly
V. Case study
The following takes student score management as an example to illustrate the interface isolation principle:
Analysis: Student achievement management procedures generally include query scores, new scores, delete scores, modify scores, calculate total scores, calculate average scores, print scores information and other functions, usually we will do?
One: initial design
In general, we design interfaces as follows:
public interface IStudentScore {
// Query the score
public void queryScore(a);
// Modify the score
public void updateScore(a);
// Add the score
public void saveScore(a);
// Delete the score
public void delete(a);
// Calculate the total score
public double sum(a);
// Calculate the average score
public double avg(a);
// Print the transcript
public void printScore(a);
}
Copy the code
We’re going to put all the functionality in one interface. What kind of problems does this create? First of all, the interface has many methods, which is not conducive to extension. For example: students only to view the results, print transcripts of permission, no permission to add, delete and change; The teacher has all authority. To query transcripts:
package com.lxl.www.designPatterns.sixPrinciple.interfaceSegregationPrinciple.score;
public class QueryScore implements IStudentScore{
@Override
public void queryScore(a) {
// Query the score
}
@Override
public void updateScore(a) {
// No permissions
}
@Override
public void saveScore(a) {
// No permissions
}
@Override
public void delete(a) {
// No permissions
}
@Override
public double sum(a) {
// No permissions
return 0;
}
@Override
public double avg(a) {
// No permissions
return 0;
}
@Override
public void printScore(a) {
// Print the transcript}}Copy the code
Operating report
package com.lxl.www.designPatterns.sixPrinciple.interfaceSegregationPrinciple.score;
public class Operate implements IStudentScore{
@Override
public void queryScore(a) {}@Override
public void updateScore(a) {}@Override
public void saveScore(a) {}@Override
public void delete(a) {}@Override
public double sum(a) {
return 0;
}
@Override
public double avg(a) {
return 0;
}
@Override
public void printScore(a) {}}Copy the code
To query the transcript, we only use two methods, but we have to override all of them because we implement the interface. If you add a request — send it to the parent, only the teacher has this permission, not the student. However, when you add an abstract method to an interface, all implementation classes override that method. This is a violation of the open closed principle.
2. Use the interface isolation principle
The UML diagram of the interface designed using the interface isolation principle is as follows:
public interface IQueryScore {
// Query the score
public void queryScore(a);
// Print the transcript
public void printScore(a);
}
public interface IOperateScore {
// Modify the score
public void updateScore(a);
// Add the score
public void saveScore(a);
// Delete the score
public void delete(a);
// Calculate the total score
public double sum(a);
// Calculate the average score
public double avg(a);
}
public class StudentOperate implements IQueryScore{
@Override
public void queryScore(a) {
// Query the score
}
@Override
public void printScore(a) {
// Print the transcript}}public class TeacherOperate implements IQueryScore.IOperateScore{
@Override
public void queryScore(a) {}@Override
public void updateScore(a) {}@Override
public void saveScore(a) {}@Override
public void delete(a) {}@Override
public double sum(a) {
return 0;
}
@Override
public double avg(a) {
return 0;
}
@Override
public void printScore(a) {}}Copy the code
We split an original interface. It is divided into query interface and operation interface. In this way, the student side does not need to rewrite the interface that is not relevant to it.
If it is not reasonable to put all these functions into one interface, it is correct to put them into three modules, namely input module, statistics module and print module. The class diagram is shown in Figure 1