193
Views
6
Comments
Best architecture refactoring of a monolithic Business Layer module

On AI Mentor Studio it's been flagged that a Business Layer has become a monolith.

On the OutSystems architecture best practices documentation examples there is only ever one Business Layer module per end user application - so I haven't found any examples about what to do if this Business Layer module becomes too big.

I have some idea about what to do. But am curious as to how others may have tackled this in the past and what was learned through it.

2 techniques I can think of are:

1. To split it into side by side Business Layer modules that handle different core modules but still for the same end user application. The issue here is that your end user module now has to tie these Business Layers together if it requires actions from both in one flow.

2. To have levels of Business Layers. I.e. one overarching/orchestration one that consumes a few smaller and more specific Business Layer modules which in turn consume the core modules (i.e option 1 but with an orchestration BL). This removes the issue of the end user having to tie multiple Business Layer modules together, but I have never seen anyone do this.

Open to ideas and comments.

2018-06-05 16-54-03
Maria da Graça Peixoto

Hi! 

I think the option 2 is easiest to manage in the future. The fact it's not usually done do not mean it's not correct, go with it. 

Graça

2019-06-15 21-39-22
Afonso Carvalho
 
MVP

Hello Nicholas,

I think there's no one-size-fits-all solution to these sorts of issues. I'm instinctively drawn to solution 1 because 2 sounds like overengineering. Adding multiple levels of business logic can bog you down because for example, if you're using consuming Server Actions, you now have to follow specific steps in order to refresh them - changes in your specific business modules will cause them to be published, which forces you to refresh the orchestrator business module, and only then can you refresh your end user module.

There's nothing inherently wrong with an end user module consuming several business modules - it can still be done poorly if you're consuming dozens, but if you perform a change in one of these modules and then decide to promote your end user module to other environments, you don't have to bring along the unchanged business modules. The impact is restricted to their consumers.

After observing the alert from AI Mentor Studio, what do you think? Looking at the module in question, do you agree that it's become a monolith? Does it mix different business concepts, or does it really only refer to one concept while aggregating too much logic inside? I'd still separate it in both cases, but the end solution may differ depending on what exactly is being represented in the module.

2022-11-02 07-18-33
Nicholas Campbell

Thanks Afonso, this is an insightful answer. I like the abstraction you've explained and independant deployment lifecycles.

For scenario 1, would you create server actions in the front end module that would then call the different actions from the different BL modules in one server action - in the scenario where one user action (say a press of a button) would require actions to be run in two different BL modules?

Technique 3: Following from my comment above, I've heard some people suggest that server actions be created in the front end to handle the button logic (i.e ione front end server action to do action x from the BL module and then action y from the same BL module) and then the BL does not contain applicatio/screen specific logic/flows but just manages the logic of interacting between the different core modules. This approach would shrink the BL size as the more app specific logic would be in the front end. I worry however, that this creates less abstraction since the front end now becomes more bulky and you can't deploy it separate to that business logic like if it were to be rather in the BL.

To answer your last question I'd like to hear your thoughts on the new option 3 above. Also, I am curious about your comment about having multiple concepts in the BL - I know that core modules should not have different concepts together, but I thought that the purpose of a Business Layer was to tie multiple core modules together (i.e multiple concepts together) with specific business logic for the front end applications - so then the BL would have to have the logic for multiple concepts inside of it?

2019-06-15 21-39-22
Afonso Carvalho
 
MVP

For scenario 1, if the logic is trivial, I'd wrap them in the front end, yes. As an example, if all your frontend requires is a chain of calls, it's okay to implement this in the frontend. If you need more complex logic and decision-making in your frontend Action wrapping these BL Actions, then it becomes much less clear-cut: this is a great intro to Technique 3.

Technique 3 is dangerous precisely because of what you mention: your frontends become much more complex and if you ever find yourself needing to reuse this logic built on the frontend, you now have to create a BL and move it there. That's not to say that it's absolutely wrong and you should never, ever do it. You shouldn't have reusable logic in your frontends, with reusable as the keyword. Does it make sense to create an entirely new BL module for 2 Server Actions that don't logically fit anywhere else and that you won't consume in any other frontend? Probably not, you might as well leave them in the frontend - abstraction can be supremely helpful, if you're going to make use of it. Creating and maintaining abstraction for the sake of abstraction leads to complex solutions to what should be simple problems.

Regarding what concepts should be in a BL module, I have an example. Imagine a Car Insurance app. You've modeled the concept of a Vehicle into its own CS, and you did the same for the concept of Insurance. How many BLs do you create? You probably shouldn't, but you could make a single BL module: your BL module is related to your own single application, so you create a CarInsurance_BL module. You're aggregating two different concepts into one BL but if the amount of logic that you require is small and you're only going to ever require one frontend, how much do you really gain by splitting it into different modules and applications?

But now let's assume that you want other consumers and other applications using the data you create and manage. It makes sense to completely isolate the concepts of Vehicle and Insurance into their own applications. You also separate your initial BL into two different modules, Vehicle_BL and Insurance_BL. You can now more easily maintain logic associated with these two concepts. But associating an Insurance policy with a Vehicle is a complex process. It doesn't make sense to keep it in the Vehicle because it can exist without the Insurance concept, and the reverse isn't true. Do you leave it in the Insurance_BL module, or do you create a third BL module to isolate this more complex logic (this would closely parallel Technique 2 in your initial post)? It's not an ironclad rule that a business concept must have its own dedicated BL module, or that a BL module must be used to mix different business concepts - the main purpose of a BL module is to encapsulate reusable/complex logic that you plan on consuming in different modules. They can refer only to a single concept (maintaining the Validation/Save actions for the Vehicle in a Vehicle_BL, for instance) and they can also mix concepts (a theoretical third module to create Insurances related to Vehicles). They can become monolithic if you attempt to aggregate too many concepts, like the CarInsurance_BL.

If you're thinking I wrote 3 different answers to your last question, you'd be about right. I think the complexity of your architecture should accompany the complexity of the problems you're trying to solve: ideally, it should be less complex than your issue, but the opposite should never be true.

2022-11-02 07-18-33
Nicholas Campbell

Once again, a very insightful reply. Thanks Afonso.

Haha yes there are a few different answers in there but I can see why - it depends... Very good food for thought and I am going to probably read over it a few more times.

Looking back now, Technique 1 and 3 are actually basically the same.

I like your final comment about the architecture not being more complicated than the app is, it's very true.

I'm going to think more on this topic and respond further next week. Thank again

2019-06-15 21-39-22
Afonso Carvalho
 
MVP

No problem. I enjoy discussing architecture because asking someone what "good" architecture looks like can have such a variety of possible answers.

Feel free to return to this thread, or to share any other questions you have.

Community GuidelinesBe kind and respectful, give credit to the original source of content, and search for duplicates before posting.