Organizing (a lot of) code with a controller pattern

General Add comments

ServiceNow does a lot of things right. It allows for a great deal of extending and customizing, and compared to most other SaaS solutions I see in practice it does so very well. You write your custom logic, save it as a Script Include and use Business Rules, UI Actions and Scheduled Jobs to invoke your code. For most use cases the Script Include itself is enough to organize your code. But when the amount of functions needed becomes larger, there comes a point when one Script Include is just not enough too properly organize your code. Scrolling through 1500 lines of code is a pain even when it is properly formatted and well written.

One way to solve this issue would be to divide your code over different Script Includes and just call the Script Include that holds the function that you need. A problem with this approach is that you need to remember what Script Include contains what function when you want to call one of the functions. And what if (like the good developer that you are!) made helper functions for common operations. Do you need to put the helper functions in all Script Includes? Do you divide the functions on the basis of what helper functions they need? Obviously these solutions have some drawbacks when it comes to flexibility and maintainability. Since we want to organize our code the notion of using multiple Script Includes seems like a good starting point. Why not have some code that keeps track for us where different functions live? And while we are at it, why not have one place for our generic functions as well?

The solution I found consists of three ingredients: a controller, the functions groups and the generic functions. All of these are actually Script Includes and they are organized as follows:

In this example, there are three function groups, but depending on the amount of functions and the way they are divided this can vary from one to as many as you need. It works as follows:
All functions are registered in the controller, that instantiates the correct Script Include and calls the needed function for you. Every Script Include instantiates the Script Include that contains the generic functions and makes it available for its functions as a variable. All calls are made to the controller Script Include, and all function groups can be made as small or large as is convenient for you. But the functions can also be divided on a logical basis instead of just size, keeping related functionality together where possible or needed. So what does that look like?
In the controller we need a way to register our functions with Script Includes and have it called automatically. That would look something like this:

In the Script Include that acts as a function group 1 there must be a function called processX and the generic functions must be available. That would look something like this:

Finally an example of a generic function Script Include:

So per the above example, if I want to call a function that is in a function group it would look something like the following:

Keep in mind that these are simplified examples, and should not be used in production as-is. There are different ways to achieve this kind of setup and some are more elegant than the other. Think about how you can apply this idea to your own needs for organizing your code on ServiceNow and if the amount of code you are writing is actually needed for the requirements you are fulfilling. Happy coding!

Leave a Reply