As more and more things are being automated, our daily life becomes easier. In many cases however we have a mix of automation and manual actions, or we want to be able to intervene or correct when automation goes wrong. Whatever reason, a fully automated system is often still not feasible, and thus manual interactions needs to be allowed and taken into account during design and implementation. But what exactly are the implications of this?
When creating a fully automated system, you can keep everything contained, and control can be restricted. This results in nice and clean code which can maximise the concepts of Object Oriented Programming to the fullest. As soon as you need manual interaction however, you need to cut straight across your nice design and let the user manipulate data that could otherwise be shielded. This means you need to extend your API such that these internal data can be altered, which opens the risk of other developers using this API as well and completely mess up your application.
While you can try to keep your API clean and allow only limited and controlled changes, this is only possible if the requirements allow it. But if for example you need to be able to set the value for a variable directly (because a sensor could break for instance), there is no way you can do any sanity checks on this data anymore.
The risk of manipulating internal data directly is clear, you can no longer guarantee system consistency, which could lead to crashes or mistakes being made, based on bad data. Because of this it is essential that you log any changes that are made directly and out of your control, if something goes wrong in that case you can always prove that it was manual manipulation that caused the problem.
Another aspect of how it can destroy clean code is that the user need a way to interact with the application to change the data. But the user interface and the data that needs to be manipulated can be far apart, as the data can be hidden deep inside the application. This would mean that the request to change the variable needs to be passed on, by each layer as it makes it way to where it belongs. This results in many small and stupid methods on the intermediate levels, either to get the next level, or to just pass on the call to the next level.
As far as I know, there is no real solution for this, but knowing what type of manipulation needs to be done upfront, allows you to make some room for it in your design and minimise the crap that you would have to write otherwise. The real question however is why the customer wants to be able to manipulate the variables, usually this indicates a bigger problem that perhaps should be fixed in a different way. The example mentioned earlier (that of a broken sensor) relates to my previous blog post. Being able to eliminate or detect a broken sensor before it reports bad data to the software is always preferable over fixing it in the software.