Refactor for ease of publishing

I'm curious who else has encountered something like this:

I have a team of 6 developers all working on one application.  We have done much to implement the 4-layer architecture, but have found the main application module has become very slow to publish, not to mention the issue of constantly having to merge with the other developers.

It seems all the training videos and documentation are tailored to breaking out business logic and implementing the 4-layer architecture.  What we are most interested in is breaking apart the main modules into several logical modules within the application itself.  We have some application-specific logic and many UI screens, all of which are appropriate to be in the end-user module.  We just want to break apart that module for ease of publishing.  

It seems as though even in this case, side-references for the modules are frowned upon, even though it's within an application.  There is also the issue of session and site variables, which are espace specific.  I can only think to create getters and setters to manage the use of those.  It seems as though there has to be a "preferred" way to accomplish this.

Has anybody else encountered a situation like this?  Is there documentation out there that addresses best practices? 

Hi Mike Neyman ,

(...) we are most interested in is breaking apart the main modules into several logical modules (...) issue of session and site variables (...) Is there documentation out there that addresses best practices? 

In case you split your application, consider the fit towards the different business domains. Regarding the side references, session and site properties maybe is a good practice not to use them extensively.

There is a landing page for OutSystems best practices: https://success.outsystems.com/Documentation/Best_Practices

Hope it helps, cheers!

Thank you for your response Marco.  Unfortunately, Outsystems doesn't have anything specific listed in their best practices when it comes to refactoring the way we're trying to do it.  I understand what you're saying about session and site properties, and it certainly makes sense.  Side references are necessary simply because of my wanting to split apart the modules, and yet all modules are related to one another in some fashion.  This does give me a few ideas, however.

Hi Mike,

Depending on how your separate End-User modules relate to each other, you may want to create an Orchestration module to take care of the references to different End-User modules.

Otherwise, if dependencies are tighter, you may consider:

  • using hand-built URLs (using External URLs) instead of referencing screens from other End-User modules (this eliminates a lot of the side references);
  • refactor actions referenced from other End-User modules into Core Business modules, so there aren't side references.

The thought of using an orchestration module is indeed intriguing, but would require a lot more code refactoring and proper planning.  Not saying that we won't go that route, that would be interesting.  I appreciate both of your insight, it sounds like there's not really a cut and dry way to go about this.  Leaving this open to see if others are willing to share their experiences.

In my project, here the division:

# there are 4 applications: UI/theme, web services for consumed by outside, external db, and the core (consume web service to external web services, common logic for other applications, and BPT).



# working with other developers, i cheat by publish as frequent as possible so others will lost :). 

# I am thinking to using something like 'token' to fairly publish among developers - who gets the token, it has a turn to publish.

# we minimize using session to only for searching and site properties to only address of a web service, the rest will be stored in database for many adavantages (not caching, can provide a screen to change the value, etc).

# module functional dependencies will be: screen(webservice/bpt(common logic(external db)))

# and unfortunately the screen module become fat 

# the project has been in production and business running

# the application growths and the need to redesign the applications becomes material

# unfortunately we are afraid that big changes will make the logic errors (as it is in a production already - the contracts to customer/client has been running)

# more over, we are not sure if splitting to more module will not influence the performance.


Solution

@Mike,

From your question I had the impression that your team were working with a single end user module? 

If so, this is indeed not recommended. 

You have here an example of a typical 4 layers application: https://www.outsystems.com/forge/component-overview/2190/practical-example-of-4-layer

You will noticed that the number of end user modules increase with the number of user stories. 

In general we split or keep together end user screens depending on how they are related or not. 

The services are than split in different modules the same way, but also to improve efficiency on publishing. So even related concepts may be split if this helps preventing unnecessary dependency. 

There are specific training material and documentation on architecture, and some nice lectures from ODC that are available. I recommend going for them. 

Specifically regarding refactoring, I recommend this course: https://www.outsystems.com/learn/lesson/1229/refactoring-an-application/?LearningPathId=17

Just remember that if you need to move entities from one space to another, if the application is already used in production, you may require the use of the Refractor app (from Forge) to help migrating data (there are other possibilities also). 

Regarding session variables and site properties, best practice is to use them as little as possible. Here the numbers have a negative impact in performance. And if you need to share them, getters and setters are the way to go. 

Regarding screens references, in O11 they are considered weak references and do not create hard dependency per se. If you are on O10 or O9, the anternative is to use external URL. This will help to avoid side references if you have the need to split end user screens that must be accessible from other end user modules. 

An alternative that consumes AOs but may help is to keep generic business interfaces in Web blocks and keep them at core services level, reusing on different end user screens, but in general I would avoid this if you are constantly using all the same blocks on many different screens (that become the same screen). 

By the way, refactoring is common even when the application has a good architecture, depending on how it grows. 

Hope this could be of help. 

Cheers 

Solution

Hi brrrr,

Thanks for your contribution, would be easier to read if your posts are aggregated in one single post :)

Cheers!

@Eduardo,

We actually have implemented a general 4-layer architecture, so I apologize for the confusion.  Most (if not all) of the logic and UI in the end user module is indeed appropriate for an end user module.  It's really just the challenge of breaking up the end user module into more logical, workable parts.  I do love some of the suggestions that you have made, it gives me information and more confidence in moving forward with a refactor.  I am marking your comment as the solution.  Thank you all for your insight.