Announcement Announcement Module
No announcement yet.
Where to put business needs not related to specific entities? Page Title Module
Move Remove Collapse
Conversation Detail Module
  • Filter
  • Time
  • Show
Clear All
new posts

  • Where to put business needs not related to specific entities?

    Hi Ben,

    where would you suggest putting business methods not related to one specific entity, especially when also hitting the persistance layer?

    In detail, would you introduce a new business layer next to or on top of the domain layer, and what if this business method has to get data from the persistance layer (e.g. a database view) for calculations or anything else?

    Thank you in advance,

  • #2
    It's very easy to add a service layer with Roo. Just create a new Java source file, annotate it with @Service, and you're done. (Ideally you also want to create an interface.)

    I would adopt the most natural design approach. Which would probably be a Service class in this case. Roo doesn't constrain your architectural choices; just use the simplest path for the most common requirements.


    • #3
      Rod is absolutely correct: Roo does NOT stop you from creating a stock-standard class and treating it as a services layer.

      If writing a services layer, I recommend you consider annotating it with Spring's @Service stereotype annotation so it is picked up during classpath scans and dependency injected. I also recommend declaring an interface, using constructor injection for mandatory collaborators (although that's just my preference as opposed to a strong recommendation) and using the @Transactional annotation to ensure transactional units of work exist for invocations to your services layer methods.

      As an aside, one reason we use interfaces with services layers generally with Spring is because it facilitates the creation of a JDK dynamic proxy object, which is useful for Spring AOP (you can work around it with CGLIB, but then you have incompatibilities with "final" types and methods). As Roo projects use AspectJ, this technical motivation for an interface is diminished. However it's still a good idea to write an interface so you can support mocking in your tests and encourage separation of design and implementation. I just thought I'd mention it in case you're wondering what reasons still exist for an interface and whether Roo changes any of that (ie it eliminates one of the technical requirements, but they're still recommended).

      Finally, Roo allows you to create interfaces and classes from the Roo shell, which is useful in scripts. The "class" and "interface" commands are what you might wish to use (although personally I'd just use an IDE/text editor given you'll need to write the body of the types anyway). There's also the "enum type" command if you'd like an enum to be created via the Roo shell.


      • #4
        Hi Rod and Alex,

        thank you very much for your explanations. You are right, one should always use interfaces because one never knows what's behind the next corner ;-)

        I was just wondering what implications will occur using a DDD approch that Roo is imposing on the project initially. Using AJ leaves the visual domain objects clean from setters/getters and other non business stuff so why no use these entities for business purposes which I never liked before because it overloads the objects and mixes responsibilities (persistance and business logic). Right?

        But in this case why not use the entities as domain objects as a rich domain layer, very interesting idea. That's what I like here. It's simple and natural as Rod mentioned before.

        What I just wondering is, where to put other (not persisted) business objects like services? But you said there will be a service layer, so that's how it always was and will be. But doesn't that mixes business responsibilities to the domain and the service layer? Or let's say where to put which business methods? The last thing is that I normally don't like persistance methods and business methods mixed up in one object, because one doesn't know what is what and it IMO breaks the rule "one class for only one responsibility". Testing should work because of the interface and mock objects but maybe the objects get overloaded by the time.

        What do you think?

        Greetings Fireball


        • #5
          If your business logic deals with only a single entity, or it deals with multiple entities and those multiple entities are accessible by following associations from some sort of root entity, it is generally desirable to put the business logic in the entity. If on the other hand your business logic involves multiple entities and those entities are not available via the associations of some root entity, that's when a services layer becomes useful as there is no particular logical home for the business logic within a given entity. A services layer is also useful if you need to collaborate with infrastructure objects (eg sending an email). I tend to avoid the entity layer depending on anything except other entities and persistence APIs, as that keeps it light and flexible in the future. The persistence API is sometimes debated, but I think it's fair enough given it's JPA and evolves gradually (and is quite lightweight anyway, and taken care of in a separate ITD layer at a compilation unit level).