I have several DAO classes that implement an interface. In the other hand, I have Service classes that use those DAO implementations.
So far all the DAO interfaces are public and I was thinking if would it be better to make them package private and to put the service classes in the same package so they are the only ones being able to use them.
The reason is because I wouldn’t like that programmers could use DAO implementations in a Controller or a web service without using the service layer. A programmer could think for example that adding a new order is as simple as calling the addOrder dao method, ignoring that indeed there is a service method that does more than that.
What do you guys think?
First, I would suggest that you package those two independently, and just offer proper documentation as to what the purpose of each library is. It will give you more flexibility in the long run, as you might have to bypass the Service layer at some point or use the Data layer as a common-functionality library for other projects.
That being said, I agree that you should restrict access to the DAOs, specially to avoid direct manipulation of your data store. However, this applies to the concrete version of your DAOs (your question is vague on this aspect). Having the interfaces public might be useful for other developers to provide their own implementation in case they want to use another type of data storage (assuming you provide a way of injecting DAOs into your service layer). This should follow along nicely with the Open/Closed Principle.
1
I understand where you are coming from on Encapsulation point of view, and I don’t necessarily think it is a bad idea, although I question how important this ultimately is. Some important points:
Service Orientied or Component Oriented Architecture
You mention specifically that you clients of your services will somehow obtain libraries and possibly your source code. Typically this runs counter to SOA in that your clients typically will know nothing about the underlying architecture of the service (nor should they care).
Tide goes in, tide goes out. Never a missed step… you can’t explain that – Bill O’Reilly
Ideally your service consumers should be as ignorant of the specifics of your services as our dear friend Bill O’Reilly is on the tides. Request goes in, Request goes out, you can’t explain that.
On the other hand if you have a component oriented architecture in general then while consumers may physically have the component, they should never use it outside of the predesignated interfaces anyway or else you really have deeper problems.
The separation of the DAO layer should be for little more than decoupling the acquisition of data from business logic, for the sole benefit of the component and those tasked with developing and maintaining it.
Transactional Based vs Object Oriented
Transactional based systems operate on transactions and sessions of various individual requests and responses. Being as this sounds like the architecture choice you have decided on for your application, the importance of fundamental Object Oriented concepts are moot for this particular situation.
Classes denote nothing more than various behavior implementations for various functional areas of your application, however when deployed to an application server they are void of meaningful state, acting more like singletons. In fact this is typically exactly what they are if coupled with a Dependency Injection framework.
In a truly OO design and architecture, a DI framework for Data Access and Business Logic classes are more or less injecting singletons where the required behavior is, but without state is this really OO to begin with?
Certainly DI can be useful for object oriented classes that actually can be preconfigured with various state, but not here. So knowing that, the encapsulation concept is essentially moot as your DAO classes are likely being injected where they need to go with Reflection in mind anyway.