Do You Really Need Interfaces for Service and DAO Layers in Spring?
This article examines whether defining separate interfaces for Service and DAO layers is necessary in Spring projects, debunks common justifications, proposes a bottom‑up development workflow, and outlines project structures for single and multiple implementations, highlighting both benefits and drawbacks.
Why Interfaces Are Often Considered Unnecessary with DI
When a project uses a dependency injection framework like Spring, you can skip defining separate interfaces for Service and DAO layers because the framework can inject concrete classes directly.
Common Arguments for Adding Interfaces
Allows writing upper‑layer code (e.g., Controllers) before the lower‑layer implementation is ready.
Spring’s AOP is based on dynamic proxies, which traditionally require interfaces.
Supports multiple implementations of a Service.
All three reasons are weak in typical projects.
Why the First Argument Falls Short
In most teams a feature is developed end‑to‑end by a single developer, so defining an interface adds extra work without real benefit. If you need to code against an unfinished implementation, simply create a stub method in the concrete class.
Suggested Bottom‑Up Development Flow
Write the Controller logic first, inserting calls to Service methods as needed.
Let the IDE generate the missing Service class and methods, marking them with TODO.
After all classes and methods are generated, fill in the business logic based on the TODOs.
This approach helps you understand the overall workflow early.
Why the Second Argument Is Invalid
Spring’s default proxy mechanism can be switched to CGLIB, which works without interfaces.
When Multiple Implementations Matter
If you truly need several Service implementations, you can organize the code in one of two ways.
Approach 1: Separate Packages for Each Implementation
Controller → Service (interface) → impl1, impl2 packages → DAO.
Approach 2: Add a New Service Module
Create a second Service module (Service2) with its own implementation package, keeping the original Service module unchanged.
Approach 1 is simpler; Approach 2 provides clearer module separation but introduces duplicate code.
Combining Both Advantages
Extract the interface and its implementations into an independent module. Then configure the build so that either ServiceImpl or ServiceImpl2 is included, keeping package structures identical and avoiding extra configuration changes.
Drawbacks of Not Using Interfaces
Without interfaces, IDE assistance such as code generation and compile‑time checks for missing methods is lost, and handling multiple implementations becomes harder. In projects that require many implementations, interfaces remain the recommended choice.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
IT Architects Alliance
Discussion and exchange on system, internet, large‑scale distributed, high‑availability, and high‑performance architectures, as well as big data, machine learning, AI, and architecture adjustments with internet technologies. Includes real‑world large‑scale architecture case studies. Open to architects who have ideas and enjoy sharing.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
