My file structure is as follows:
`
I chose to separate DTO and ModelA (DTO is empty and only extends A-DTO) to keep separation between data representation and persistence representation. I don't know how to represent this List of ModelA in EntityB so far, I don't want a separate table and I'm out of options. Is it good practice to separate Model, DTO and Entites as such? Could I have just been using the DTO? I don't want to repeat myself.
Moreover, what would be the general best practice for file structure in such a project ?
I expect to have a clean implementation of EntityB with reference to a list of ModelA and a clean way to architecture relation between the Model referenced in the entity and the DTO. And moreover about the global file structure.
There are no strictly defined package layouts. It depends on complexity of your project and conventions established in your team. But there are some principles you may follow - keep the similar things together, support low coupling and high cohesion, be intuitive understandable and readable. In practice we can meet two widespread layouts described below.
This structure is not the best but recommended in many tutorials. Typically we have 3 layers - controller, responsible for interaction with frontend, persistent - responsible for database interaction and service layer which is a glue for the former and contains almost all business logic. Often we have a separate package model which contains classes described business model. High level packages would be
- controller
- service
- persistent
- model
Note there is no package exception. Exceptions should be somewhere close to classes/packages where they happen. Also there is no package security. Instead we might introduce two extra packages
- common
- config
The last package will contain configuration classes including application and security config. You may define any sub packages what you like inside this structure. ** The main thing - there should not be circular package dependency** You can verify it with this tool http://www.dependency-analyzer.org/
- controller
- ControllerA.java
- ControllerB.java
- service
- ServiceA.java
- ServiceB.java
- persistence
- RepositoryA.java
- RepositoryB.java
- model
- ModelA.java
- ModelB.java
- EntityA.java
- EntityB.java
This is the preferable way for packaging project, see http://www.javapractices.com/topic/TopicAction.do?Id=205 Typical structure will be
- common
- config
- features
- model if it's classes used by many features
Inside the package features will be separate packages for every business feature. This approach has many advantages
- we can have **public** methods in controller only.
These methods implements contract between backend and frontend. All other methods can be package private
- we can delete a feature simply deleting a feature package
- all feature logic is easy observable
- it is easy extended when a new feature arrives
- common
- config
- SecurityConfig.java
- features
- a_feature
- ControllerA.java
- RepositoryA.java
- EntityA.java
- b_feature
- ControllerB.java
- RepositoryB.java
- EntityB.java
- model
- ModelA.java
- ModelB.java
ModelA and ModelB may be used as DTO. Note that features files not divided to further packages so we can use package private access to their methods.
It seems you have only one feature named plan. If we follow packaging be feature your layout might be
- config
- SecurityConfig.java
- features
- plan
- PlanRequest.java
- PlanResponse.java
- PlanService.java
- PlanController.java
- PlanRepository.java
- EntityB.java
- PlanException.java
- model
- ModelA.java
- ModelB.java
Also see the related question at Are there best practices for (Java) package organization?