There are strong parallels to this narrative in the world of software engineering. Object orientated languages introduced the notion of inheritance, a clever idea to promote code reuse. However, inheritance – when misused – can easily lead to complex hierarchies and can make it difficult to change objects. The misuse of inheritance can reek havoc and since all it takes to use inheritance (in Java) is to be able to spell the word “extends”, it’s very easy to reek such havoc if you don’t know what you are doing. A similar story can be told with polymorphism and with design patterns. We all know the case of someone hell bent on using a pattern and thinking more about the pattern than the problem they are trying to solve. Even if they understand the difference between a Bridge and an Adapter it is still quite possible that some part of the architecture may be over engineered. Perhaps it’s worth bearing in mind that every single one of the GOF design pattern is already in JDK, so if you really want it in your architecture you don’t have to look very far – otherwise only use when it makes sense to use it.
This ‘Powerful use, damaging misuse’ anti-pattern is ubiquitous in Java systems. Servlet Filters are a very handy feature for manipulating requests and reponses, but that’s all they are meant to do. There is nothing in the language to stop a developer treating the Filter as a classical object, adding public APIs and business logic to the Filter. Of course the filter is never meant to be used this way and when they are trouble inevitably happens. But the key point is that it’s easy for a developer to take such a powerful feature, misuse it and damage architectures. ‘Powerful use, damaging misuse’ happens very easy with Aspects, even Exceptions (we have all seen cases where exceptions were thrown and it would have made more sense to just return a boolean) and with many other features.
When it is so easy to make mistakes, inevitably they will happen. The Java compiler isn’t going to say – ‘wait a sec do you really understand this concept?’ and codestyle tools aren’t sophisticated enough to spot misuse of advanced concepts. In addition, no company has the time to get the most senior person to review every line of code. And even the most Senior Engineer will make mistakes.
There’s a lesson to be learnt here. As soon as you design anything which something else uses, whether it be a core component in your architecture, a utility library class or a REST API you are going to tell the world about, ask youself:
- How easy is it for people to misuse this? Is it at the risky levels of inheritance or the safer levels of encapsulation?
- What are the consequences of misuse?
- And what can you do to minimise misuse and its consequences?
Aim to increase ‘powerful use’ and minimise ‘damaging misuse’!
Reference: Musing on mis-usings: ‘Powerful use, Damaging misuse’ from our JCG partner Alex Staveley at the Dublin’s Tech Blog blog.
Related Articles :
Bulletproof Java Code: A Practical Strategy for Developing Functional, Reliable, and Secure Java Code
Use Java? If you do, you know that Java software can be used to drive application logic of Web services or Web applications. Perhaps you use it for desktop applications? Or, embedded devices? Whatever your use of Java code, functional errors are the enemy!
To combat this enemy, your team might already perform functional testing. Even so, you're taking significant risks if you have not yet implemented a comprehensive team-wide quality management strategy. Such a strategy alleviates reliability, security, and performance problems to ensure that your code is free of functionality errors.Read this article to learn about this simple four-step strategy that is proven to make Java code more reliable, more secure, and easier to maintain.