2

Im currently trying to design an architecture for my new webapp project that has this kind of concept :

  • consists of several big modules that are independent from one another, but can still communicate and affecting one another.
  • For example, i could enable the purchasing module along with production module in my webapp, and let's assume the modules could communicate with one another.
  • But then i could activate only the purchasing module, but disabling production module in the webapp, just from configuring it, without changing any of the code., and the purchasing module will still work fine (independent from the production module)

Here's what i've been thinking about for the architectural layers to support this kind of application :

  1. The UI Layer

    • JSF 2.0 + Primefaces widgets
    • Requestscoped ManagedBean + Flash object to transfer data between pages
    • The ManagedBean will deal with the UI states, UI validations, but not with the business logic operations
    • The ManagedBean also has access to the service layer, injected by Spring
    • ManagedBean could have simple fields (like string, integer, etc), or view models (to encapsulate some related fields), or even the Entity models, which should be a transient object in the beginning, and becoming a detached object once having get in and persisted and get out of a transaction.
    • These fields combinations could be used based on the situation, and the validations, for example, like the @Required, will be placed in the ManageBean's setter method. The Entity model could have @NotNull or @Size within the fields.
    • The entities in my thinking is only JPA POJOs with the JPA annotations defining the relationships between the entities, without any behaviours, except those validations defined by the the annotations also.
  2. The Service Layer

    • This layer will handle the business logic validations and operations
    • Modularity : Could also call other service layer for other modules where he other modules could be non-existent, if disabled via configuration. Perhaps this can be achieved via nother layer for the communication between modules, or perhaps i could use Spring to inject empty implementations for the disabled modules ?
    • Input : It can accept Entity models, or plain variables, or view models
    • Output : The return value could vary from void, Entity, a list of Entities (to be displayed later in a datatable in JSF), and could be plain variables like boolean, string, integer, etc.
    • In the future, this layer will also provide web services for mobile devices or other kind of language that support web service (i still dont know how, but i think this is possible, even if the method accept objects or entities as the parameters)
    • Each service object will have DAO instance injected by Spring, and will call the DAO for data operations, like CRUD operations, querying, etc
  3. The DAO Layer

    • Will have the data operations like CRUD operations, querying (jpql, named query, criteria query, native sql query, stored proecure calls) etc
    • Input : It can accept Entity models, or plain variables, or view models
    • Output : The return value could vary from void, Entity, a list of Entities (to be displayed later in a datatable in JSF), and could be plain variables like boolean, string, integer, etc.
    • Having one DAO for each entity is the norm, but when dealing with multiple tables in a single data operation, i'd have to introduce new DAOs.
    • Will have the EntityManager injected by Spring

These are the things i have in mind, and with this, i tried doing some googling around these topics, and found out many other stuffs like :

  • Doman Driven Design (DDD), where the entities could have persisting logics in them ? I think this is also the active record pattern ? Spring roo seems to be generating this kind of model also. It seems to be the opposite of Anemic Domain Model.
  • The data transfer object (DTO), encapsulating the communication data between layers, avoiding the lazy initialization problems with the unloaded fetchtype lazy hierarchies when using JPA ? Open Session in the View seems to be have it's own PROs and CONs also in solving the lazy exception.
  • And some would say you dont need the DAO anymore, as described in the spring roo documentation

And with all these matters, please share your thinking my current design when it comes to these :

  • Speed of development, with me thinking about having less boilerplate because being able to make use of the Entities, converting to-and-from DTOs
  • Ease of maintenance, with me thinking about having clear separation between ui state/logic, business process logic, data operations layer
  • Support for the modularization, perhaps using maven with each module as one artifact, depending one another as needed ? <-- this is where it's all very foggy for me
  • Webservice in the future. I have never tried webservices before, but i can just assume, public methods in the service layers could be exported as webservices, so they could be called from mobile devices, or any other platforms that support webservice call ?

Could you please share your experience in this matter ?

Community
  • 1
  • 1
Bertie
  • 17,277
  • 45
  • 129
  • 182

1 Answers1

0

Find an OR Mapper you like and don't devote any more attention to the data layer. That is mostly a solved problem, and most of the attention you devote to that will be reinventing the wheel. Very people write applications whose CRUD needs are so unique that they obviate ORM use these days.

Some of the same advice for the UI - find tools and frameworks rather than spending too much time on all of that, there's a lot of good development wealth in place there.

So, concentrate on the service layer, where the unique nature of your application is really expressed. But we can't really validate or critique your service layer because we don't know anything about the problem you're trying to solve. All of the things you've listed are certainly good approaches for certain problems, certain sets of trade-offs, etc. Without knowing more about what matters (performance / development time / configurability / robustness / clarity), nobody can tell you what the right set of choices is.

On your "output" item - other devices can support communication with your app as long as everything serializes down to a common format, usually XML. Then you just send it over the wire, and rehydrate it on the other end.

Software development, when it is non-trivial is a Wicked Problem. It is likely that much advice that you get would need to be thrown out halfway through your project. I don't generally believe in grand architectures - focus on solving particular problems as well as you can, and if you're lucky, a pattern will emerge that you can take advantage. Anything more is generally hubris.

Chris B. Behrens
  • 6,255
  • 8
  • 45
  • 71
  • Hello, thank you for you thoughts on this. It is my intention to use OR Mapper like hibernate in the form of JPA in the DAO layer, and to make use of existing widgets of Primefaces/JSF2 without reinventing the wheel. But my concern is the best practice to communicate between layers, like should we use DTO or is it problematic to use Entities instead in the method parameters. Or is DAO still needed or we could replace the functionalities in each in the Entities model ? And about how to achieve modularity with those features described above. – Bertie Jan 17 '11 at 16:09
  • For that specific question, I think the pertinent factor is "to what degree do you require location independence of the layers?" That is, is it fine to require intraprocess communication? Intrabox? Beyond intrabox, everything is pretty much the same. – Chris B. Behrens Jan 17 '11 at 16:12
  • Im sorry .. Did you mean independence of modules or layers ? If you meant layers, i think the current layers are quite allright, we can see the separation of concerns. It is my inexperience passing around the JPA entities or DTOs between layers that makes me questioning the viability of it. And if u meant about modules, each module will have it's own sets of ui pages,services,and DAOs. The services within a single module can communicate with each other, and can also call the services on other modules. Sorry i dont really understand what u meant by the beyond intrabox thing .. – Bertie Jan 17 '11 at 17:39