Author: Structural thinking

toutiao.com/i6882356844245975563

Is it really necessary to add interfaces to each class in the Service and Dao layers? This question, briefly answered before a wave, gives the view that “depends”!

Now combine my involvement in the project and read some project source code. If your project uses a dependency injection framework like Spring, you don’t need interfaces!

Let’s start with why we can use dependency injection frameworks without interfaces!

Reasons for not needing an interface

I sorted out the reasons for adding interfaces to the Service layer and the Dao layer, and summarized three:

  • You can write upper-level code, such as a Controller call to a Service, without implementing specific Service logic
  • Spring implements AOP by default based on dynamic proxies, which require interfaces
  • Multiple implementations of services are possible

In fact, none of these three reasons hold water!

Let’s start with the first reason: “The upper layer can code without the lower logic being implemented”! Interface oriented programming typically decouples layers from one another as if there were no problems.

This development mode is suitable for different modules that are developed by different people or project teams, because the cost of communication is relatively high. At the same time to avoid due to the difference between the project team development schedule and mutual influence.

But let’s think back to how many project teams in a typical project are split into layers. In fact, most projects are divided by function. Even with the separation of the front and back ends, pure back-end development is divided by functional modules, with one person responsible for the complete logical processing from the Controller layer to the DAO layer.

In this case, each layer defines an interface before implementing the logic, in addition to increasing the developer’s workload (of course, if the amount of code counts into the workload, developers should not be too hostile to interfaces!). In fact, it is of no use.

If a developer wants to develop the upper-level logic before the lower-level logic is complete, he can write empty methods of the lower-level classes to complete the upper-level logic first.

Here is one of my favorite development processes, the top-down coding process:

  • Write the logic in the Controller layer first, and write the calling code directly where you need to delegate Service invocation. Complete the Controller layer process first
  • Then use IDE auto-completion to generate the corresponding classes and methods for the code just called below and add TODO to them
  • After all the classes and methods are completed, the logic is improved one by one according to the above process based on TODO.

This approach gives you a better understanding of the business process.

As for the second argument, it doesn’t work at all. Spring is based on dynamic proxies by default, but can be configured to implement AOP using CGLib. CGLib does not require an interface.

The final reason is “multiple implementations of services are possible.” This is not a good reason, or does not consider the context. In fact, in most cases there is no need for multiple implementations, or there are alternatives to interface-based multiple implementations.

In addition, for many projects that use interfaces, the project structure is also open to debate! Next, we combine the project structure to illustrate.

Project structure and interface implementation

The general project structure is divided into layers, as follows:

  • Controller
  • Service
  • Dao

In cases where no more implementations are needed, interfaces are not needed. The above project structure will suffice.

For cases where multiple implementations are required, either now or later. In this case, it looks like you need an interface. The project structure at this point looks like this:

  • Controller
  • Service
  • —- interface is in a package
  • Impl – Implementation is in another package
  • Dao

For the above structure, let’s consider the case of multiple implementations, what to do?

The first way is to add a package to the Service, write the new logic in it, and then modify the configuration file to use the new implementation as an injection object.

  • Controller
  • Service
  • —- interface is in a package
  • Impl – Implementation is in another package
  • Impl2 – The new implementation is in a different package
  • Dao

The second way is to create a new Service module and write new logic in it. Since both Service modules need to be loaded at the same time, if the package name and class name are the same, the class fully qualified name of both modules will be the same! , and then modify the configuration file to use the new logic as an injection object.

  • Controller
  • Service
  • —- interface is in a package
  • Impl – Implementation is in another package
  • Service2
  • Impl2 – The new implementation is in a different package
  • Dao

The first approach is actually a bit simpler, focusing only on the package level. The second approach focuses on both module and package levels. In addition, both approaches actually result in the inclusion of unnecessary logical code in the project. Because old logic goes into the bag.

However, from a structural point of view, the actual structure of approach two is clearer than that of Approach one, because the logic can be differentiated from modules.

Is there a way to combine the best of both? The answer is yes, and it’s not complicated to operate!

First, separate the interface and implementation as a separate module:

  • Controller
  • Service – Interface module
  • ServiceImpl
  • Impl – Implementation is in another package
  • ServiceImpl2
  • Impl2 – The new implementation is in a different package
  • Dao

Second, adjust the packaging configuration. Choose ServiceImpl or ServiceImpl2. Since ServiceImpl and ServiceImpl2 are the two choices, the package structure of ServiceImpl and ServiceImpl2 can be the same. The package structure is the same, so dependency injection configuration does not need to be adjusted once dependencies are adjusted. After adjustment, the project structure looks like this:

  • Controller
  • Service – Interface module
  • ServiceImpl
  • Impl – Implemented in another package
  • ServiceImpl2
  • Impl – New implementation and honest are now in the same package
  • Dao

The package structure and class names in the ServiceImpl and ServiceImpl2 modules are now the same. Do we still need interface modules?

Suppose we remove the Service interface module and the structure looks like this:

  • Controller
  • Service1 — Old implementation
  • Service2 — New implementation
  • Dao

Can multiple implementations of services be achieved simply by adjusting module dependencies? Is the answer obvious?

Disadvantages of not using interfaces

The reasons for not using interfaces are given above. However, not using interfaces is not without its drawbacks. The main problem is that there is no strong interface specification for multiple implementations. That is, you can’t quickly generate framework code through an IDE by implementing an interface. The IDE can also provide error alerts for interfaces that are not implemented.

A less elegant solution is to copy the code from the original module into the new module and implement the new logic based on the old code.

So, if a project requires multiple implementations, and there are a lot of them (although projects typically don’t have multiple implementations), interfaces are recommended. Otherwise, no interface is needed.

conclusion

This paper points out the reason why an interface is needed for the Service layer. As well as personal views on this issue, I hope to be of some help to you.


Recommend 3 original Springboot +Vue projects, with complete video explanation and documentation and source code:

Build a complete project from Springboot+ ElasticSearch + Canal

  • Video tutorial: www.bilibili.com/video/BV1Jq…
  • A complete development documents: www.zhuawaba.com/post/124
  • Online demos: www.zhuawaba.com/dailyhub

【VueAdmin】 hand to hand teach you to develop SpringBoot+Jwt+Vue back-end separation management system

  • Full 800 – minute video tutorial: www.bilibili.com/video/BV1af…
  • Complete development document front end: www.zhuawaba.com/post/18
  • Full development documentation backend: www.zhuawaba.com/post/19

【VueBlog】 Based on SpringBoot+Vue development of the front and back end separation blog project complete teaching

  • Full 200 – minute video tutorial: www.bilibili.com/video/BV1af…
  • Full development documentation: www.zhuawaba.com/post/17

If you have any questions, please come to my official account [Java Q&A Society] and ask me