In this article, I will cover some things that make for creating an elegant code base, both to maintain & to utilise. I’ll try to keep this post reasonably short, since some of the content may be considered opinionated.
Let’s start with the Fluent Interface, in my honest opinion, it’s a beautiful solution for creating libraries. As an example, let’s use a Guard Clause as an example. For the sake of argument, let’s say that you have some interface called ‘Validator’, in this interface, you just have one method called ‘validate’, it’s return type is void & it throws an illegal argument exception.
In this case, you may wish to establish some common set of methods, to reduce the amount of repeatable code. In such a case, you can implement this solution via a fluent interface, I won’t provide a specific implementation of this base solution since your requirements will vary. So here’s a concrete implementation of the ‘Validator’ interface, using a fluent interface style approach:
In the solution above, you can clearly make several assumptions of what this code does. In the event that you’re unsure, I’ll provide you with a little input on how this code works.
In the code above, you can see that the method named message is being called quite a number of times. The idea behind this method is to set the message that will be passed to the illegal argument exception, when one of the cases holds true.
It’s simple, it’s super easy to read & it’s super easy to test since there are no branches in this concrete implementation, you could get away with having one test that passes the guard clause & another that fails.
By now, if you keep up to date with the Java programming language, you’re aware of the power of Java 8’s Optional implementation. Personally, I must say, I’m a huge fan, since it allows me to express code in a more elegant manner. To illustrate my point, here’s an example:
In the above example, one thing that’s awesome about a solution like this is that it’s short & straight to the point. It also doesn’t have any branches so to speak, at least it has no if statement as such. But of course, it does still have a logical statement, this is clean, it’s modern & it’s simple. Who doesn’t love simplicity?!
Another beautiful thing about Java is that by default, it’s built for OOP, meaning that we can leverage polymorphism over branches. This appears to be a common practice when refactoring older code bases, there’s also an insane number of ways in which you can achieve this.
So, let’s say for arguments sake that you want to implement a financial service, where a customer may have several states:
- Requires Validation
So let’s say that you have a base class called ‘CustomerState’, let’s also say that you’re using the null object pattern, where the null object will use the default state. In such a case, I’d suggest that you implement this solution using the state pattern.
When a user provides invalid credentials, lets assume that in the customer reaches the state of a unregistered user, for the sake of security purposes also. As an unregistered user, you have no privileges, you can’t do much apart from signup.
Rather than implementing business logic in some large singular class, where each method may have large if statements or guard clauses, etc. You could utilise a pattern like this, which makes sense, since it enforces the single responsibility discipline & it keeps things simple.
In the case that you’ve implemented this pattern, you can specify the implementation of each action that a customer can make. An example being how an unregistered customer is able to make a ‘register’ action, but a registered customer is unable to make a ‘register’ action, since this makes no sense at all. You could say throw an illegal state exception, or you could just log that unusual, the options may be more specific to your use case, but I’m sure you get the idea.
To draw this short article to an end, I’d like to think that you get the idea that through the use of patterns, it makes your code base cleaner, clearer & generally easier to use & maintain. However, while I encourage encapsulation, I suggest that you try to find the right balance. I’ve actually come across where cases in my career where there’s so much encapsulation that it’s hard to figure out whats going on, it’s a debugging & maintenance nightmare.
I also suggest that you really focus on the maintainability side of things, trust me, I’ve worked on some code bases where there are far too many god objects, aka large classes dominate the code base. An example being how I’ve actually encountered a controller which essentially handles ~90% of the business logic for the entire application. In this precise case, it would make perfect sense to use the state pattern since there are so many different states that the customer can reach. I also suggest that your team utilises best practices, honestly, I can’t emphasise this enough, especially if you’re working with a large number of junior developers.
I emphasise that it’s important to think about junior developers since you don’t want the junior members of your team to pick up bad habits or practices. If these juniors were to pick up such practices, then it’s possible that they’ll never change, of course this does depend on the developer specifically. But for arguments sake, let’s say that you’re working with a stubborn developer that refuses to change, at least if they’re working with the best of practices, it’s unlikely that they’ll be a nightmare to work with in future.
I specifically stated stubborn developers that refuse to change their ways of working is all due to the fact that this is something else that I’ve encountered far too many times. It makes sense to an extent since to change how you think requires a lot of time to conduct research, in addition to the research, developers need to experiment, this all takes time & will eat into the developers spare time.
Provided you heed my advice, I hope that you too produce beautiful code, that when assembled, it performs like a beautiful orchestra, it behaves like a sweet symphony. I hope that you don’t implement unnecessary complexity & I hope that you implement a code base that your colleagues will be grateful for.
Another exceptional advantage to implementing beautiful code is that it’s partially self documented, which by default means that it’ll make your life a lot easier when creating the necessary documentation. I promise not to ramble on any further, I hope you’ve enjoyed this post & I wish you all the best in your coding adventures! 🙂