Design Think your Code
Updated: Oct 12, 2022
Have you ever opened an existing solution, took one look at the scripting - and your eyes just glazed over - as if you were attempting to decipher the Matrix code ?
The Claris FileMaker Platform provides Developers a rich toolkit of Scripting (code) functions to build and craft mature app solutions with built-in logic and workflow control.
As a function of Design Thinking - 'consider' applying these Design Patterns to your next solution, with the audience not just being the End User, also include the Project Manager and the 'next' Developer.
"Design Thinking is a term used to represent a set of cognitive, strategic and practical processes by which design concepts are developed." ~ Wikipedia
"In software engineering, a software Design Pattern is a general, reusable solution to a commonly occurring problem within a given context in software design." ~ Wikipedia
As an exercise, run your next script through this Code Design Pattern Checklist - making considered decisions as to the structure and usability of your script code.
Code Design Patterns:
There's no one single 'right' way to write Scripts - just different outcomes related to these Patterns, with no real 'weight' as to one decision creates a higher weight, than another.
This is by no means a complete list, as there will obviously be many other Design Patterns to consider while crafting your scripts.
Economical Execution. No 'End User' wants to press a button and wait for 'x' minutes for the outcome to appear on their screen. No 'Developer' wants to wait for 'x' minutes to run the script while creating, troubleshooting or updating said script.
I can confidently say that the number one factor in creating 'fast' scripts is not within the scripting code at all - it's the calling of un-stored data - I've discussed this at length in the 'Find in Progress' blog - its a must read, if you are not familiar with this concept.
That said, loading data into variables which are declared at the start of each script is a good starting practice, to begin moving this data into memory, the fastest option for accessing data. This also allows the same data point to be loaded once, not every time is called.
This method can also be applied to configuring 'Let' statements inside complicated Calculations, to not only aid the speed of the calculation loading, also the Developer's ability to read, update or troubleshoot the Calculation.
Exercise: Create a timer function for your next script, and while in the Design phase of your code, experiment with different methods - you may be surprised in the throughput of one method over an other - or you may find one method is only milliseconds slower than an other, while providing various benefits to the next Developer.
The initial thought pattern is that the script in question will only need to be troubleshooted while the Developer is writing the initial code. This falls into the category that 'you are not the user' - which in real life is hardly the case.
When setting up the initial script, consider how as the Developer, you will perform Support and Troubleshooting of this code, either within the Live or Test environments. This troubleshooting consideration also extends to how the Users can troubleshoot the script themselves, in a non-disruptive method.
Exercise: While writing the next script, perform a mock troubleshooting session, with the environment being either Live or Test, and time your ability to complete the session.
Error Checking and Capturing.
This concept goes beyond when the User doesn't do what the Developer is expecting, to an environmental change that can render the outcome of the script un-expected or destructive.
Displaying a Custom Dialogue via the script step - with the error code, or even in the language of the User - doesn't really give the best experience of the code.
Example: I apply an email notification script to solutions when an 'Unknown' User authenticates against the 'Test' Version of any system. This script presents a Custom Dialogue to the 'Unknown' User that they have opened the Test Version, and they have the option of Exiting or Continuing - this result is emailed to the Support Staff.
Exercise: create an error log table, which logs the details surrounding the User's situation in creating this error, and include the option to notify Support staff of this error, either via email, Slack or SMS, depending on the workflow required for this error.
Successful Completion. At first glance, this one seems to be a no-brainer. Before we write the first line of our script, does this script need to reach the last line, to be defined as successfully executed ?
Does the 'next' developer understand this expectation - on updating or troubleshooting this script - even if that Developer is you, in six months time ?
One of the most under-utilised script steps is the Exit Script [ Text Result ] script step.
Let's be very clear on the difference between Exit Script and Halt Script. The Halt Script step is akin to taking the keys out of the ignition of your car to slow it down, rather than using the breaks. I do apply a Commit and then Halt 'utility' script for over-riding the tab order for fields on the layout, as part of the UI.
Example: There is nothing more frustrating that troubleshooting a script, where an 'if' statement returns a condition as part of the error checking, only to find that the script continues on to the bulk of the code, where the context 'fails' further 'if' statements - and as the Developer, you are left clicking through seemingly never ending script steps in the Script Debugger.
Exercise: Investigate the use of the Exit Script, returning a text result in a more 'complicated' script, and make a considered decision to exit at that point, each time a new script is written.
User Logging and Notification.
This concept is the lesser known cousin of the Error log table. Just as we'd like to know what something goes wrong, it's helpful to when, and how often, it goes right.
This is particularly helpful when introducing new functions to solutions, to gauge and report on which users are using these new functions and when, to provide feedback to Project Managers if further User Training is required, the feature does not fit the User's needs, or if the feature was in fact added without full support from the Users.
Exercise: create a user log table for the next major new feature you add to your solution. Allow a number of days or week of use to create a set of log data of the users. Create a chart or basic report for the Project Manager, outlining the ROI of the current feature.
Comments as Section Headers.
As per the image at the beginning of this post, the 'cognitive load' of your logic applied to your scripts have greatly reduce the next Developer's ability to understand your code.
This concept can be applied to multiple techniques, with Comments being one discussed at length over the years. It's not if you comment, it's more about 'how' your Comment.
Personally, I don't find it useful to open an exiting script, to find the first 100 lines dedicated to the changes made to the code, and/or a long explanation of the function the script provides. I've called this the 'Comments Header'.
And from a UX design patten perspective - this is not that different to creating a long winded error dialogue - which we know the User doesn't generally read, anyhow.
Example: Put simply, if you need a number of paragraphs to explain the complexity of the script, then you may wish to looking at simplifying the script itself.
Exercise: Rather than create the Comment Header, apply your Comments more as a Function breaker. Create a 'section' for the Variable collection, a section for the Error Capturing, and preface each main section with a Comment Marker.
In practice, this allows the reader of the script to scan through each section, without the need to understand the script logic, expected result or to find the change in logic.
Human Friendly Variable Names.
This concept can be applied to not just Variable Names, basically every element in your solution. I can't be the first developer to open up an existing solution and wonder if I needed a degree in applied algebra or trigonometry to understand the code.
Attempt to stay away from using terms that may change over time, such as the Company Name, or descriptors that can change over time. As the Developer, there's not much you can do if the name of an entity changes from Location to Depot to Office to Workshop over a period of time.
That said, keeping the logic consistent and human friendly can go along way to reducing the cognitive load of your code for the next Developer - and again, this can be you, in six months time.
That's not to say you can not apply some best practices when it comes to naming conventions. And no, I am not talking about prefixing field names with a Z that I think I may not be using in code.
As an example of this exception, my preference is to use $i and $j as the counters for looping. This technique is clean and simple, and allows loops to exit when $i > $j.
Exercise: Open one of your more complicated scripts, and with your 'next' Developer hat on, scroll half way down the script, and see if you can 'decider' the data behind the Variable, based on only the name of the Variable, followed by the context of the use of the Variable.
Research New Functions.
With each new version of FileMaker, we receive newer and more powerful functions. This is now even more evident with the 'Agile' method of releases from Claris.
The mindset is to challenge assumptions and pre-existing notions of how we have always completed a task, to ensure our craft is continually improving.
As a practice, spend some quality time researching and applying these new functions, and decide to include these in your Coding Toolkit.
Example: The 'While' function was introduced with FileMaker 18. The Claris documentation is not exactly a tutorial on how to create your first While function, this blog by Skeleton Key to clearly break down the structure of your first While function.
Exercise: Find an existing Recursive Custom Function, or even a looping script and then update your code to apply the new 'While' function. Compare the old and the new, and decide on which allows for the best Design Pattern.
Hit by a Kangaroo Scenario.
I prefer to not utter 'hit by a bus' or invite any other inanimate object into my universe.
That said, I have been in the situation - as a toddler - where I was the only obstruction between food and a hungry six foot kangaroo that was prepared to throw down.
Back on topic, there's no employment guarantee provided by writing code that only you can read, let alone update or troubleshoot. And I ask you, do you wish to be developing the same code for the same solution in ten years time ?
Exercise: This follows the other exercises, simply write code that lends itself to various levels of developer skill and experience, particularly for the next Developer.
Trust me - I guarantee you a deeper and more fulfilling Developer Career.
Developer Friendly Code.
This could be considered the collective of these types of Developer Design Patterns.
The Headline of this blog could have been simply 'Developer Friendly Code.' or even 'Hit by a Kangaroo'.
The final takeaway is simply - 'design' your code to be Developer Friendly.