[spb_text_block pb_margin_bottom=”no” pb_border_bottom=”no” width=”1/1″ el_position=”first last”] Yesterday I had an interesting design discussion about organising MVC applications with one of my friends and Founder of VeloxCore, Vinit Yadav. [pullquote]What is the better way of organising your typical MVC web-application or REST services – Repository or Dao or DataAccess, Service and Controller classes. [/pullquote]
Context – ways of organising MVC application’s Services & Repository
You may have few 10s of tables or entities. Most of these co-relating with your Repository classes or interfaces (in case of SpringData). You have approximately 5-10 modules from for which you would need your REST services or Controllers. How to make these modules talk with the repositories. Note: It is assumed that Repository i.e. DataAccess layer i.e. dumb layer with primary responsibility to encapsulate DB specific logic ONLY. Service layer i.e. business logic layer. Here are several options for organisations.
- Service per Module: Create a Service interface & class per module, which will inject all the dependent repositories. Services will inject repositories – NOT other services.
- Service per Repository: Create a Service interface & class for each repository. REST controller will typically inject many service implementations. Services will inject Repository it is responsible for or it MAY in inject other services. And of course, any other reusable components like EmailService, ImageProcessor, Indexer and so on.
[/spb_text_block] [spb_single_image image=”9756″ image_size=”medium” frame=”borderframe” intro_animation=”none” full_width=”no” lightbox=”yes” link_target=”_self” caption=”D1 – Approach 1″ width=”1/3″ el_position=”first”] [spb_text_block pb_margin_bottom=”no” pb_border_bottom=”no” width=”1/2″ el_position=”last”] Service per Module: Consider that you have Products belonging to multiple Categories. If the category already exists with the same name, link it with the product being created, create new otherwise. You may have separate module to perform Category CRUD as well. Approach 1 implementation for this is shown in – really rough – diagram on left. This approach may have possible code duplications in different services. Another side-effect is, for complex applications, you will end up in in injecting too many Repository implementations and complex logic in service classes. [/spb_text_block] [spb_text_block pb_margin_bottom=”no” pb_border_bottom=”no” width=”1/2″ el_position=”first”] Service per Repository: Not necessarily always. But typically – as needed. This should not be confused with exact same – just delegation to repository – kind of service classes. Remember, createProduct() doesn’t necessarily mean saveProduct(). Create product could mean – do basic validations of the data, create category if required or link the correct category, send mail to few, do required indexing for search operations. Wherein saveProduct() in Repository layer would just take the Product instance and dump it to the database. As part of createProduct, you need to create category if required. This task naturally belongs to Category. ProductService is not supposed to carry out this task. Natural place for doing this operation would be CategoryService – even if you don’t have any module from UI for doing CRUD of Category. ProductService can then inject CategoryService to carry-out Category-specific tasks. [/spb_text_block] [spb_single_image image=”9757″ image_size=”medium” frame=”borderframe” intro_animation=”none” full_width=”no” lightbox=”yes” link_target=”_self” caption=”Service-per-repository” width=”1/3″ el_position=”last”] [spb_text_block pb_margin_bottom=”no” pb_border_bottom=”no” width=”1/1″ el_position=”first last”] In Summary, I would say Service layer is a business layer. It should talk in terms of Business. If your service methods don’t make sense to BA, it is a design smell. Then use these service layer as a building blocks to develop higher layer services and facades to provide simpler interface to consumers. Please share your thoughts about how you think we can organise MVC application in more maintainable and readable way. Will talk more about the similar stuff for REST controller and Service layer in further posts soon. By the time, enjoy and happy coding! [/spb_text_block]