I was wondering if anyone could suggest the best approach for simplicity, maintainability, and extensibility on the below scenario.
Overview
I am building a service application that will be used for both a web and a mobile interface. This is not very important to the question I have, however it may give a more complete understanding of the scenario.
On the core layer i have the below modules:
The reason I separated the above to different modules is that in the future there will be additional functionality that will only need to interact with the entities of the Project_CS (and new modules) and not the entities under the Plan_CS module.
The UI layer will need to consume both these modules and the Plan_CS module will need to consume the Project_CS.
Scenario A
I thought of creating a business logic (Execution_BL) module to contain the complex calculation that will be responsible for deciding the data that would populate some of the entities of the Plan_CS module, but then it seemed like the solution will become more complex as it will create one more module that will be consumed by the UI (Projects_CS, Plan_CS, and Execution_BL) while both Plan_CS and Execution_BL will consume the Projects_CS.
Scenario B
Since, the above became a bit complicated my second thought was to have the Execution_BL to consume the other 2 modules and the UI to only consume the Execution_BL, which will mean that the Execution_BL will be the one responsible for both the reading and editing of the data on the other two modules. This seems cleaner and simpler, but I am not sure that makes sense to have a "bridge" module for reading the data.
Question
I believe that neither of the above scenarios violates the 4 Layer Architecture, but I am not totally sold on either of them, so I was hoping someone will have a better approach. What is the best way to architect the above solution? Do I really need the Execution_BL, how complex a calculation must and what other factors will be a good determiner of whether a BL module should be created?
S. wrote:
Jorge Martins wrote:
Hi S.
Scenario 2. is feasible but requires an extra layer of abstraction, as anything used by the UI needs to be defined in Execution_BL, which means it will have to define Structures to "hide" the entities in Plan_CS that are manipulated in the UI.
How your Plan_CS entities are instantiated seems to be an integral part of the Plan functionality itself, no? Have you considered Scenario 3., where you put the "complex calculation that will be responsible for deciding the data that would populate some of the entities of the Plan_CS module" directly on the Plan_CS (instead of your current Execution_BL)? A *_CS module can contain entities and business logic that are closely related, it doesn't have to be just entities and wrapper actions.
Thanks for the response Jorge!
I have thought about the scenario 3 you mention above and after reading your reply and Geraldins I am leaning more towards it. To answer your question on the begin of your second paragraph is yes.
You mentioned creating Structure to "hide" entities from Plan_CS and I was wondering if you could provide some further details or point me to any reading material to better understand how that is accomplished.
Like, is it possible to make the UI modules to only be able to consume the Execution_BL module and not be able to add the Project_CS and Plan_CS as a dependency?
Given your positive answer, I'd say Scenario 3. is definitely the one you want to follow. It will simplify your development without negative impact on your architecture.
As for the Scenario 2. implementation approach I mention:
Hope this helps.
The complex solutions can sit on their CS modules already (since this will contain their Services (OS11) to create update, delete, etc.).
Another solution is to create a service for each entity so as to ensure scalability and lessen monolithic services. You can break down the Plan_CS into different services and if a project and plan needs to be referenced, you cna create a ProjectPlan_CS service.
Geraldine Ablaza wrote:
Hi Geraldine,
If I understand correctly the scenario you mention in the second paragraph (creating a service module) the solution you propose will be to have the 2 core modules Project_CS and Plan_CS to hold the entities and perhaps some business logic. Then create a Service Module ProjectPlan_API (I added the API prefix to distinguish it from the other Core Modules) which will be exposing all the CRUD functions any UI module or external application that needs to interact with the data on the two core modules (Project_CS and Plan_CS). This will be similar to scenario B with converting the Execution_BL to a service module (API).
I like the idea and have few follow up questions:
Thanks for your help!
I don't know how much logic is in the Project_CS module, but I get the idea that it's basically a database module. You could separate the Plan_CS module into a database module and a business logic module (Plan_BL), and create a new module on the same level which holds the new logic (Execution_BL).
With this option you could visually represent the Project_CS and Plan_CS modules as a bottom layer, with Plan_BL and Execution_BL in an additional layer on top. It seems sound to me in terms of the 4-layer architecture seeing as you've only got vertical communication, and it frees up possibilities to reuse the entities in Project_CS and Plan_CS with more modules later on without creating horizontal references (or references you could define as 'it's complicated').
I'm very curious to read other solutions to this topic, I really like the question.
Monique de Vos wrote:
Thanks, Monique
What you describe above is similar to scenario B but you introduced a new business logic module (Plan_BL). Couldn't the Execution_BL handle anything that will be on the Plan_BL? What logic or functions would you have inside the Plan_BL?
Thank you all for your responses.
I decided to go with scenario 3 and having the complex login in the Plan_CS module without creating the Execution_BL module. In the future and depending on how this application will grow I may create an API module and have the UI applications (Web, Mobile, external) interact with the core modules through an API interface.