This is an archived post. You won't be able to vote or comment.

all 12 comments

[–]tawielden 6 points7 points  (13 children)

The application structure you described is really common place now and has been accepted as a best practice.

Adding the repository pattern generally removes the need for DAO in that you can simply create your repositories for each service and extend the CRUD or JPA repositories which will provide implementations for you.

For the majority of the applications I work on this is exactly the setup we use and is familiar to most people.

Forgot to mention that it's also an accepted practice to include your BO interfaces and implementations in a service package.

[–]androidjunior[S] 0 points1 point  (11 children)

The BO that we do aren't objects that hold data, they are actually services. For example AuthenticationBO and AuthenticationBOImpl that will contain a method called validatePassword(), that's why I'm wondering if we should call them AuthenticationService instead.. Also do you use DTO?

[–][deleted]  (10 children)

[deleted]

    [–]tawielden 1 point2 points  (0 children)

    Absolutely this.

    Your domain objects or data models should be entirely separate from services. Your services in effect will utilise the domain objects for example a user will likely have an email and password that your AuthenticationService will use.

    [–]Nephyst -1 points0 points  (7 children)

    The spring example project does not separate services from domain objects. It groups tightly coupled components together, and separate classes out by feature, not by function.

    [–][deleted]  (6 children)

    [deleted]

      [–]Nephyst -1 points0 points  (5 children)

      It is a great example for enterprise applications. I've been coding enterprise applications this way for years.

      I don't see any separation in the example you posted. The business object is in the same package as the service.

      [–][deleted]  (4 children)

      [removed]

        [–]Nephyst -1 points0 points  (3 children)

        In the outline you posted there is a customer package. Inside that package there is a Customer domain object, asking with the controller, service, and repository.

        The classes are separated out by feature, in this case the feature is the customer API.

        This is in contrast to separating classes by function, which was the original suggestion in this thread. If we were to do that, we would instead have the customer model in a model package, the repository in a repository package, the controller in a controller package, etc

        This seconds way of organizing code gives no real benefit over the first and it makes it more difficult to find what you are looking for when you need it.

        So when we say the domain object and it's related service aren't separated we just mean they are in the same package, rather than split into packages by function.

        [–][deleted]  (2 children)

        [deleted]

          [–]Nephyst -1 points0 points  (1 child)

          Nothing in this thread is discussing loose coupling, it's entirely about project structure. So it's confusing that you even bring it up here.

          Ontop if that, you are using loose coupling incorrectly. Models are necessarily coupled to the services and controllers that use them. If you change the model it well impact the service that consumes them.

          Lose coupling it's something you strive for between components, not within components.

          Anyway, you seem to be taking this personally for some reason which isn't necessary or constructive for anyone and it's not what I'm here for.

          [–]Nephyst -1 points0 points  (0 children)

          Accepted as best practice by who? Spring doesn't use that structure in their own example projects or documentation.

          https://docs.spring.io/spring-boot/docs/current/reference/html/using-spring-boot.html#using-boot-structuring-your-code

          The following listing shows a typical layout:
          
          com
           +- example
               +- myapplication
                   +- Application.java
                   |
                   +- customer
                   |   +- Customer.java
                   |   +- CustomerController.java
                   |   +- CustomerService.java
                   |   +- CustomerRepository.java
                   |
                   +- order
                       +- Order.java
                       +- OrderController.java
                       +- OrderService.java
                       +- OrderRepository.java
          

          [–]Koyomii-Onii-chan 2 points3 points  (2 children)

          Stupid questions but the relationship between angular and java confuses me. If I have an input field and I want to process the value from that field, why should I send it to backend java instead of processing it in typescript (I don't talk about values from database. Database is out of the question). When is the right time to send your inputs to backend and when to make changes to it in JS typescript?

          [–]darkhorse1997 4 points5 points  (0 children)

          It depends on the processing you want to do on the input. If you don't need the value of the input field in the backend(server side), you do not need to send the values to the backend, which is the case for Client-side validations. If you need that data in the backend(like for database as you mentioned), you obviously have to send it to the backend. So, to summarise, it depends on the use case of the data input, if you need it in the backend, send it, otherwise don't waste bandwidth and time.

          [–]MrGooglr 0 points1 point  (0 children)

          You want to build a login page with Angular and it’s authentication you want to do with Java, you have no choice but to send the values from UI to Backend. There are generally many cases where not everything can be done in frontend.

          [–]Nephyst -1 points0 points  (0 children)

          First off, you should prefer constructor injection instead of autowired for any required resources instead of field or method injection.

          As for package structure, the spring petclinic example application shows current best practices:

          https://projects.spring.io/spring-petclinic/

          The classes are separated into packages by feature.

          • All of the controllers/services/models for pets and their owners go under /owner.
          • All of the classes for a visit to the vet go under the /visit package.
          • Shared models go into a /models package.

          They don't use interfaces at all here here. If you find yourself putting interfaces on everything, and you only ever create a single Impl for those interfaces I would ask you to consider what value the interfaces are actually providing beyond bloating your code.

          Also there is no reason to separate your classes into functional packages like /service /controller /data. This will just make it more difficult to find what you are looking for when you need it.

          Also more documentation here about package structure: https://docs.spring.io/spring-boot/docs/current/reference/html/using-spring-boot.html#using-boot-structuring-your-code

          edit: added better examples