Using coding conventions in a no code environment
A major benefit of the no code app development movement is that it accesses a new audience of problems solvers that are closer to and have a better understanding of the problems needing solving. This leads to solutions that are more targeted and relevant than what might come out of a separate IT organization. However, it can also lead to decentralized, disorganized programming that doesn’t follow standard practices. This article introduces a common program architecture that can be applied to FileMaker development that will produce more efficient results that are easier to test and debug down the road.
We can think of building an application like building a house. There are many ways to build a house, and architecture provides us with common ways of developing different types of buildings. It’s not practical to build a house from top to bottom, or left to right. Even though the door is the first part of the house someone will use, it wouldn’t make sense to start construction there. This brute force method works well, until it doesn’t. And when it doesn’t, we often just keep hammering on it until it does. This is the result-driven approach common to new developers. It’s hard to argue with a system that works, but what is often lost in the pounding is how and why it works. That’s important information to have available when you inevitably come back to the program to update or improve it.
One way to clarify the approach to the solution is to utilize a common design. A software architecture provides a structured approach to how to go about designing and building a problem. An important aspect of any architecture is that it tells us not only what we should do, but also things that we shouldn’t do. One design that works well for FileMaker Development is MVC. MVC stands for Model – View – Controller, and this is how FileMaker already separates its available areas of development.
The Model is the Relationship Diagram. It’s where you design your data tables, fields, and relationships.
The View is the Layout View, where you design the look and feel of your user interface.
The Controller is the Script Workspace. This is where the logic and programming of what the application does is created.
These three areas work together to deliver the User Experience. The view takes user interactions and tells the controller what to do. The controller tells the model what records to update.
MVC tells us that we should keep these three aspects as separate as possible. This imposes some limitations on what we should do. We should not keep variables that manage how the interface looks (View) mixed in with the data we track for our records (Model). We should separate the script steps (Controller) that make changes to our data (Model) from the scripts steps that update our interface (View). This makes our programming much easier to understand and debug when we know where to look for causes of errors.
One method for reducing these dependencies is called Abstraction. Abstraction is when you refer to layout objects, instead of the fields directly in your scripts. How is this beneficial? Let’s look at a simple example where we create a new record in an Issue table, and set the status to “New.”
New Record
Set Field; Issue::status; "New"
These steps will work, but they are directly dependent on the Model, a table named Issue and a field named status, and since scripts are run from the View, also dependent on the which layout it is run. Imagine if we also want to create a new Assignment record and also set its status to “New.” We would need to create an entirely new script for Assignments. With Abstraction, we can pick up the context from the layout the script is running on to set the correct field. We do this by adding the status field of each table to the Issue layout and the Assignment layout, and naming them both “status.”
New Record
Set Field By Name; GetLayoutObjectAttribute ( “status”; “source” ); “New”
Now this script will run correctly because, with Abstraction, the script is independent of the Model, and it gets the correct field and table from an object on the View. We can call this script from either layout and get the expected outcome. By reducing the dependencies across our Model, View, and Controller, we create dynamically adaptable programming that can be used in more situations than the straight forward, brute force method.
Here’s how we can build a script house using Model-View-Controller architecture. The beginning of our script is the user interaction which is the foundation. This is where we gather all the information needed from the View, what button the user clicked, what record the user is viewing, or what layout the user is on. Then the information is passed to the Model to be processed into creating records, updating records, and other steps. Finally, the Controller determines if the process was successful or not and updates the layout view to present that information to the user.
Once you start to ask yourself, is this script updating the View or updating the Model, you can begin to modularize the Controller script steps based on their function. This makes the Controller scripts much more robust, since they don’t have dependencies on the Context. This will leads to more modular code with fewer dependencies that can be used from any Layout in the application. Only the View Controller steps need to be evaluated when updating the interface, or porting the function to a new file or layout.