0

I have problems with architecture of my project application. I wanted to avoid all classes being public (it is problem of layer packaging), so I created vertical packages as shown below on the screen-shot:

packages screen-shot

But I have got a problem: My User class has to be public as well as DiagnosticResult -> there is OneToMany connection between them, also UserRepository has to be public due to it's usage in DiagnosticResult service. Here is the code:

public class User extends BaseEntityAudit {
    //some simple fields
    @OneToMany(targetEntity = DiagnosticResult.class, mappedBy = "user", fetch = FetchType.LAZY)
    private List<DiagnosticResult> resultsList = new ArrayList<>();

public class DiagnosticResult extends BaseEntityAudit {
    //some simple fields
    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "user_id")
    private User user;

class DiagnosticResultService {
    private final DiagnosticResultRepository resultRepository;
    private final UserRepository userRepository;
    DiagnosticResult saveDiagnosticResult(DiagnosticResult result, String login) {
        var retrievedUser = userRepository.findUserByLogin(login).orElseThrow(() -> new EntityNotFoundException("User with login: " + login + " does not exist in database."));
        result.setUser(retrievedUser);
        retrievedUser.getResultsList().add(result);
        userRepository.save(retrievedUser);
        return resultRepository.save(result);
    }

What is my problem? I heard that good practice is to make as many as possible classes package-private. I know how to make it - by putting diagnose classes with user classes together - but I don't want to do that. It will decrease readability plus in the future I want to learn microservices so it must be in different packages.

What can I do to make classes: User, UserRepository, DiagnosticResult package-private, but not moving them to the same package? Or maybe my packaging is wrong and it should be together? Can you give me any advice?

ps:For now I havent got facade classes but I will make them, I also heard that if enything from package must be public it is only facade and dto -> so maybe this is the clue to my architecture, but still how to make User and DiagnosticResult package-private?

viep
  • 1
  • 1
  • There is nothing wrong with domain models being public as well as common components like Repositories, Services, etc. You tend to keep private only those classes that carry internal value but have no meaning from the outside: could be util classes, helper classes or perhaps pieces of implementation details. Yet again there is no strict rule about that, just a common sense – Turkhan Badalov Apr 20 '23 at 19:03
  • @Turkhan Ok so you say that my Architecture is correctly built? What about future microservice that I want to add, users can be one and diagnose second ms. If they will be separated neither will work, because they depend on each other. How can I avoid this issue? It will also affect that these classes will turn to package-private. I am really curious how to make it but I have no idea, can you please provide some guidance? – viep Apr 20 '23 at 20:02
  • If by microservice you mean 2 different endpoints for users and diagnoses, you can import your public classes (e.g. Repositories) to each controller and query from them. Now, I am not talking about best practices to keep logic in controllers minimal – Turkhan Badalov Apr 20 '23 at 21:41

0 Answers0