- Maximize reuse.
- Increase cohesion/decrease coupling.
- Increase flexibility.
- Avoid circular references among business components.
These premises complemented with a Model2, component-based structure, help us define a fairly appropriate way of defining components, along with their dependencies.
The following organization is only adecuate for domain-driven business components, meaning that it should only be used for components created to handle operations related to a single domain-driven entity. For example, if you were developing an e-commerce site your domain model would include entities such as Cart, LineItem, Product, etc. If you were organizing your business logic in a domain-driven fashion, probably a component for each domain model would exist.
The above mentioned strategy is described in the following illustration:
The elements in Figure 1 are:
- EntityModificationComponent. This element would be in charge of any modification logic (CUD of the CRUD). This element has a dependency from EntityValidationComponent since it would often need to validate the create/delete/update operations before performing them. A usual validation could be that the entity name must not already exist in order to be created or updated, or verify the entity is not being referenced from any other place in the system for us to be able to delete it. A dependency to EntityListComponent exists because normally any modification logic needs a number of queries before performing them.
- EntityValidationComponent. This element performs validation logic on a particular entity. It should contain any restrictions or rules regarding the update, delete, or create operations on the specified entity.
- EntityListComponent. All queries related the entity should be defined here. A separate element is defined because it normally does not reference any other bean, making it highly reusable. Another advantage of placing all queries in a different component, is that other beans depend on it, but it does not depend on any other bean, avoiding circular references that would come up if modification and query logic was placed in the same component.
- EntityFacadeComponent. This element should contain any logic you wish to share/publish to an external client. It is ideal if you want to expose some web services focused on the manipulation of a particular entity. Naturally, the contract exposed by this component should be compatible with the canonical data model in your enterprise or any other application you want to interact with.
I have found this organizational pattern very handy when the overall functional architecture is not stable but the domain model is. As the requirements are specified and the functional requirements become more stable, you realize that you have already done most of the job with the chance to add or update functionality quite easily.
Hope you enjoyed this post.