Less is more

Low code framework

Call To Words — Jun 2022 by Paulo Ferro

Since the birth of computer science much has changed, languages have evolved, and complexity has been abstracted by programming languages and frameworks. Yet metrics say that projects cost the same as 40 years ago, take the same time and practically the same number of projects fail before ever reaching production stage. Why?

One reason is because functionalities exploded in richness and complexity, nowadays our systems allow for a much richer user experience than 40 years ago. This is the expected evolution of systems.

Yet other reasons contribute to increase cost and time. To understand them we need to first look at today’s computer science actors.

Current technical decision makers suffered severe beatings from past technology when they were programmers, in those days the code needed to develop even the easiest function was huge (when compared to modern code). Code reuse and code organization in data/business/presentation layers was crucial to the success of delivery and maintenance. Today’s systems are defined and evaluated according to these principals, code reuse and layers.

After the 2000 bug and the bubble burst many mergers had to be made, forcing different systems to talk to each other, previous linear functionalities like “finding my clients” became a nightmare because several systems had to be visited. This led to another evaluation factor: All systems need to be service oriented.

With code reuse to the top and “everything” service oriented, the dependency mesh in a system became out of control and problems like “I deployed a change in A and broke B” became daily. This was perceived as a deployment issue so the “micro-service architecture pattern” was born to rescue. One system transformed itself in 20 “independent” deployable units thus system’s installation became a challenge: DevOps came to rescue and evolved like never.

Even more recently “Single Page Applications” were added to the basket which broke each system in two different applications: one that runs on the browser (usually developed in html + typescript) and one on the server side (usually a web api developed in C# or java for ex.). Each of these applications is developed according to the principles above.

All this history led us to design applications very often composed of 7 layers and very often developing, for ex: one application screen that searches a database means to fill a 30-task list from creating the presentation layer to the services, create the repository (or data layer) classes, data objects for each layer both on the client side as on the server side, and so on and so on…

Each new lesson learned from the history above led to a new layer in our applications, yet no revision was made to remove any obsolete layers. Ex: not many realized that modern frameworks implement data-layers that obsolete those we had to build, as examples we can see that EntityFramework is the repository pattern implemented by .NET Framework and hibernate is the equivalent for java. Presentation layers are abstracted by the same frameworks, an exposed web service is just a regular class where business logic can be defined decorated with an attribute there is no more “Presentation Layer code” to be created. Defining these layers has no added value.

As a baseline, only 4 components are needed, to develop an application screen in an angular app for ex: An html view, a typescript component class a Web Api Controller and the Data Objects to be shared between client and server side, this is the current baseline effort to develop such functionality, yet our projects show very different baseline of code churn.

It’s time to review our architecture designs, it’s time to remember that framework vendors relieve us from the dangers we faced in the early years, things changed and evolved, so should our design methodologies.

In a quest to bring development closer to the baseline effort I produced the following drivers and principles:

  1. Reuse functionality, not code. Ex: A query on Clients table is not a functionality, calculating a Credit Cash Flow is a functionality, only the later should be reused when needed.
  2. A system should be composed only of components that add real functional value, everything else should be removed, this includes layers.
  3. All system folders and components should be functionally organized, ex: Folders should reflect the system menu or interface hierarchy. All components that participate on a functionality should be together on the same folder, ex: the 4 components that implement a screen should be on the same folder. Each folder on the system ultimately reflects a functionality.
  4. Hide or move code doesn’t make it disappear, only makes it harder to find. If 100 lines of code are needed to solve a functional problem, splitting these lines in different areas of the application offers no value added. It’s easier to create, maintain and read sequential code than code split all over the solution. We all learned the “No GoTos in code” rule yet forgot that a function call is a disguised GoTo.
  5. All functional code should be visible as closer as possible to the origin of the functional problem itself. Ex: A click on a button represents a need to perform a search on the database, so the code that performs this search should be all visible on the first layer possible (in a single page application this would be the Web Api Controller)
  6. The only code to be abstracted from the component above is one that has no functional relevance, ex: Technical details of reading a file is non-functional code, so a ReadFile function can be defined and called. Only these exceptions should be applied to the rule above.
  7. Avoid functional code abstraction like “Validate” methods. Any rules, validations or “ifs” needed to comply with the functional requirement should be visible soon and follow the rules above,
  8. Only promote a layer to a tier (physical separation) when no other option exists, the complexity added by physical tiers is too expensive to be added freely

These principles by themselves will create a Low Code System, Low Code is above all a mindset and a methodology rather than any product or technology.

Imagine a world where functional teams define application visual and data model in an intuitive and direct fashion.

Imagine this application model is used to generate the skeleton of the application and that code is the absolute minimum code to solve functionality, easy to read, just standard angular/C# code representing the baseline components of a single page application with the basic deterministic tasks like html, database queries and data objects all done.

Imagine that developing a production ready system was just developing the customizations to generated code.

Imagine that user experience teams can customise user experience just by applying customisations to the application design system (customise standard angular components and css).

This brings people’s skills to use in what really matters, in the real functional challenges of a system, in the complex algorithms and interactions rather than brainless time-consuming tasks like copy-paste 100 fields on an html page or data object.

This is the world of Low Code Framework, and it’s a reality.