Categories
Software Architect

Welcome to the Real World

Engineers like precision, especially software engineers who live in the realm of ones and zeros. They are used to working with binary decisions, one or zero, true or false, yes or no. Everything is clear and consistent, guaranteed by foreign key constraints, atomic transactions, and check sums.

Unfortunately, the real world is not quite that binary. Customers place orders, just to cancel them a moment later. Checks bounce, letters are lost, payments delayed, and promises broken. Data entry errors are bound to happen every so often. Users prefer “shallow” user interfaces, which give them access to many functions at once without being boxed into a lengthy, one-dimensional “process”, which is easier to program and seems more “logical” to many developers. Instead of the call stack controlling the program flow, the user is in charge.

Worse yet, widely distributed systems introduce a whole new set of inconsistencies into the game. Services may not be reachable, change without prior notice, or do not provide transactional guarantees. When you run applications on thousands of machine, failure is no longer a question of “if”, but of “when”. These systems are loosely coupled, asynchronous, concurrent, and do not adhere to traditional transaction semantics. You should have taken the blue pill!

As computer scientists’ brave new world is crumbling, what are we to do? As so often, awareness is a first important step towards a solution. Say good bye to the good old predictive call-stack architecture, where you get to define what happens when and in what order. Instead, be ready to respond to events at any time in any order, regaining your context as needed. Make asynchronous requests concurrently instead of calling methods one by one. Avoid complete chaos by modeling your application using event-driven process chains or state models. Reconcile errors through compensation, retry, or tentative operations.

Sounds scary and more than you bargained for? Luckily, the real world had to deal with the same issues for a long time: delayed letters, broken promises, messages crossing in transit, payments posted to the wrong account — the examples are countless. Accordingly, people had to resend letters, write off bad orders, or tell you to ignore the payment reminder in case you already sent a payment. So don’t just blame the real world for your headaches, but also use it as a place to look for solutions. After all, Starbucks does not two-phase commit either [1]. Welcome to the real world.

'Coz sharing is caring
Categories
Software Architect

Fight repetition

Are your developers performing recurring tasks that needs little thinking? Can you find recurring patterns in the code? Can you spot code that’s been written copy-paste-modify style? If that’s the case, your team is moving slower than they should and oddly enough – you may be the cause.

Before explaining why, let’s agree on a couple of truths about software development:
1) Duplication is evil.
2) Repetitive work slows down development.

As an architect, you set the tone. You’ve got the best overall grasp of the system and you probably wrote a trend-setting, end-to-end, vertical slice of the system that serves as an example for the team – an example that has been copied many times by now. Whenever a developer copies anything – be it a few lines of code, an XML-file, or a class – that’s a clear indication that something could be made simpler or even completely abstracted away. Most often, it’s not the domain logic that is copied; it’s the infrastructure code that just has to be there to make it work. For that reason, it’s crucial that you can envision the effects your examples have. Any code and configuration in your examples will be the base for tens, hundreds, or maybe thousands other slices of the system, which means you have to make sure that your code is clean, intention revealing, and contains nothing except what can’t be abstracted away – the domain problem itself. As an architect, you need to be highly sensitive to any kind of repetitive patterns, since anything you write will (ironically) be repeated.

But that doesn’t happen in your system, right? Take a look at that configuration file. What needs to be different if applied on another slice of the system and what will stay the same? Look at a typical business layer method. Is there a pattern that shows up in other methods as well, containing things like transaction handling, logging, authentication or auditing? How about the data access layer? Any code in there that will be the same except for names of entities and fields? Look broader. Can you find two or three lines of code that frequently seems to go together and even though they operate on different objects, it feels like the same thing? These are all examples of repetition. Repetition in code is something that developers eventually learn to filter out and ignore when reading the code, once they figured out where the interesting variabilities are found, but even if the developers get used to it – it slows them down. Code like that is clearly written for computers execute, not for developers to read.

Your responsibility is to remove it. To do that, you may need to harvest frameworks, create better abstractions, perhaps ask the toolsmith to setup an aspect framework or write a few small code generators, but the repetition won’t go away unless someone does something about it.

That someone is you.

'Coz sharing is caring