Digitalization is hard (especially in Germany)

Digitalization in this context means transforming traditional paper based processes to computer-based digital ones. For existing organisations and administrations – both private and public – such a transformation requires a lot of thought, work and time.

There are mostly functioning albeit sometimes inefficient processes in place providing services that do not allow interruptions or unavailabilities for extensive periods of time. That means the transition has to be as smooth as possible often requiring running multiple solutions in parallel or providing several ingestion methods and output formats.

Process evolution in general

Nevertheless I see a general pattern when business processes are transformed from traditional to fully digital:

I have observed and performed such transformations both privately as a client or customer and professionally implementing or supporting them.

Status quo

The current state in many organisations in Germany is “Digital Documents” and that is where it often stops. The processes themselves remain largely unchanged and opportunities and improvements remain lost.

Unfortunately this is the step where a lot of potential could be uncovered: Just by using proper collaboration tools one could assign assign tasks to specific people in a process associated to digital documents, track the progress and inform watchers. In many cases this results in much tighter processes, shorter resolution times and hugely improved documentation and traceability.

Going even further

The next step is where service providers like us are often brought to the table to extend, improve or replace the existing solution with custom- and purpose-build software to maximise efficiency, usability and power of the digital world.

Using general tools for certain processes and a certain time often shows the shortcomings and lets you destill a clearer picture of what is actually needed. Using that knowledge helps building better solutions.

Requirements for success

For this whole transformation to be successful one has to be very careful with the transition. It is seldom as easy as shutting down the old way ™ and firing up the new stuff.

Often we need to keep several ingestion points open – imaging snail mail, e-mail, texting, voice mail, web interface, app etc. as possible input media. At different points in the process several people may want to use their own way of interating with the process/documents/associated people. In the end the output may still be a paper document or a digital document as the end artifact. But maybe in addition other output like digital certificates, codes or tokens may benefit the whole experience and process.

So imho the key besides digitalisation and a good process analysis is keeping the process flexible and approachable using different means.

Some examples we all know:

  • Paying at a store often offers cash, bank card, credit card and sometimes even instant payment systems like Paypal or Wero
  • Document management with tools like Paperless-ngx office allows ingestion by scan, e-mail, direct upload etc. in different formats like PDF, JPG, PNG and hybrid storage digitally and optionally in a filing cabinet using file folders.
  • Sick notices may be sent in using phone, e-mail, web forms, in-app and be delivered by the means the recipient likes most.

The possibilities are endless and the potential improvement of efficiency, speed and comfort is huge. Just look around you and you will begin to see a lot of processes that could easily be improve and cause many win-win situations for both, service providers and their clients.

“Keep in mind” code

Reading source code, especially those from other people (and that includes your past self of some months, too), is hard and needs practice. Source code is one of the rare forms of literature that is easier to write than to read. Yet it seems that code is only written once, but read multiple times during its lifetime. Every time we need to make a change to it, we need to read the whole block of code thoroughly and sift through the rest in order to find the relevant block.

This means that source code should be written with readability and understandability in mind. And in fact, I’ve never met a programmer that set out to write obscure code. We all want our code to be easy to read. And while I don’t have a silver bullet answer how this feature can be achieved, I’ve seen some patterns that are detrimental to the goal. I call them “keep in mind” code lines, because that is what you need to do:

You need to make a mental or physical note of some additional requirement that the source code imposes onto the reader, often without a discernable reason.

Let me make an obvious example:

while (true) {
    // some more code
}

This simple line of code requires the reader to make a note: There needs to be some construct that exits the forever loop in the “some more code” section or else the program wouldn’t work right anyway. We have two possibilities: We can interrupt our flow of reading and understanding, scan ahead looking for the exit structure and discard the mental note once we’ve found it. Or we can persist the note, continue with our reading and cross the note off once we read past the exit structure. Both reactions require additional effort from the reader.

If we choose the first possibility, we need to pause our mental model of the code that we’ve read and understood so far. This is equivalent to peeking some pages ahead in a riveting book, just to make sure the character doesn’t die in the current situation. It’s good for peak suspense, but we really don’t want that in our source code. Source code should be a rather boring type of literature. The stories we tell should fascinate on a higher level than “will this thread survive the method call”?

Recalling a paused mental model is always accompanied by some loss. We don’t notice it right away, but some aspect that we already knew goes missing and needs to be learnt again if relevant. In my opinion, that is a bad trade: My high-level model gets compromised because I need to follow a low-level distraction from one line of code.

If we choose the second possibility and make a written note on a piece of paper (or something equivalent), we might hold the mental model in place during the short interruption of writing the note. But we need to implement a recurring note checking mechanism into our reading process, because we shouldn’t forget about the notes.

There is a third possibility: Ignoring the danger. That would mean reading the code like letting the TV run in the background. You don’t really pay attention and the story just flows by. I don’t think that’s a worthwile way to engage with source code.

Let me try to define what a line of “keep in mind” code is: It is source code that cannot be understood without a forward reference further “down” the lines, but raises concerns or questions. It represents an open item on my “sorrow list”.

Another, less obvious example would be:

private final InputStream input;

Because InputStream is a resource (a Closeable) in java, it needs to be used in accordance to its lifecycle. Storing it into a member variable means that the enclosing object “inherits” the lifecycle management. If the enclosing object exposes the resource to the outside, it gets messy. All these unfortunate scenarios appear on my checklist as soon as I read the line above.

What can we do to avoid “keep in mind” lines? We can try to structure our source code not for writing, but for reading. The dangling mental reference of “I need to exit that while-true loop” is present even as the code is written. Once we notice that we keep a mental short-term list of open code structure tasks while programming, we can optimize it. Every code structure that doesn’t lead to some mandatory complementary work further down is one less thing to keep in mind while reading.

How would the example above produce less mental load while reading? Two options come to mind:

do {
    // some more code
} while (true);

This is essentially the same code, but the reader has seen all lines that exit the loop before being made aware that otherwise, it loops forever. The solution to the problem is already present when the problem presents itself.

Another option makes the exit structure explicit from the start:

boolean exitWhileLoop = false;
while (!exitWhileLoop) {
    // some more code
}

The exit structures in the “some more code” section should now use the flag “exitWhileLoop” if possible instead of breaking out directly. If necessary, a hearty “continue” statement at the right place omits the rest of the loop code. This option will lead to more code that is more verbose about the control flow. For the reader, that’s a good thing because the intent isn’t hidden between the lines anymore. If you as the code author think that your code gets clunky because of it, contemplate if the control flow structure is a good fit for the story you want to tell. Maybe you can simplify it, or you need to employ an even more complex structure because your story requires it.

In any case, try to avoid “keep in mind” lines. They burden your readers and make working with the code less pleasant. I have several more examples of such lines or structures, but wanted to keep this blog post short. Are you interested in more specific examples? Can you provide some example from your experience? Write a comment!

P.S.: I love the gibberish on the AI-generated checklist in the blog entry picture and wanted you to savor it, too.