The most important OOP design principles by Hernan Wilkinson

In this post, I will write about my personal notes and some personal comments from the amazing talk of Hernan Wilkinson about seven design principles with OOP. If you want to see the original video in Spanish you can take a look here.

Introduction

The design of our application, it’s one of the most important parts of our application. How can we measure or know if our application is good or bad? Well, from the point of view of the design, we could say if our solution is reflecting all use cases of the business domain problems that we are trying to resolve. Let’s take a look at the following bad design:

As you can see, on the right side is the real problem that our client exposes to us (eg: Billing system). And the left side is our domain. Each Group contains green circles and red circles, the green circles represent the use cases of the Real domain problem that are on both sides, and the red circles represent the missing use cases that our design missed. The point of view of design, our Software representation is not covered all uses cases, so for that, we could say that it’s not a good design. A concrete example of that could be if we create a Billing system in which we generate invoices that are possibles to change after their creation. It is something that does not reflect user needs. Another is the Date object like Calendar of Java.

Next will see a good design in which all use cases of the user domain problem they are covered by our software representation.

A concrete example of that could be the same Billing system that allows us to create an invoice, but now it doesn’t allow us to change them.

Also, Hernan mention in his talk, two really interesting tips to help us to don’t miss some use cases (or green circles) of the business domain that we are trying to represent:

  • Imagine that we don’t have computers (like 90 years ago), it’s easier to imagine the domain of the problem in that way because we start to represent the roles persons, not just things.
  • The use of metaphor it’s soo important to start imagining the invisible part of the business domain as a visible. In that way, we favor interacting with live objects not just a set of instructions. An example of an invisible mode could be Sales. How does a sale smell? What is the color of a sale?. It’s complicated to imagine that, so for that, using a metaphor helps us to imagine that.

Also, It was really fun how Hernan, describe the difference between self and this . which basically talks about the perception to interact with non-living things or objects, you don’t say yourself when you feel hungry this feel hungry :D).

Well, let start with Hernan’s seven principles:

Encourage represent our domain with immutable objects

But the most important part of working with an Immutable object it’s you don’t longer care about Time constraints. The time axis of our domain problem, it doesn’t longer be a problem for us. In that way, avoid problems like concurrency, shared states, avoiding side-effects and restrict them in an immutable object, it gives us as a benefit to building easy to deal with objects, easy to implement time-traveling, referential transparency, able to easily implement pure functions and a lot of properties which come from mostly from functional programming.

Always create complete objects

Each object should be valid from their initialization

Avoid using setters

Only allow atomic changes

Never use null, undefined, nil, etc

So, this heuristic is to never use Null. You should not have any parameters, properties, or return reference to Null, nil, undefined, etc

The null is not a polymorphic object, so each time that you ask for some value that may become null, I will need to introduce if conditional. At this point, the problems starting to arise. Our code starts to become fragile or error-prone. At this moment you enter into the billion-dollar mistake problem.

To help us to avoid null, we could do the following:

  • Implement Null-Object Pattern in our code, in that way for instance if we are working with user addresses, and the user doesn't add any address, we could represent that state of our domain with an object calledEmptyAddress (each field with default values, like numbers with 0 or emptystrings). Of course, if only if, our domain problem allows us to represent in that way, otherwise, we should throw an exception.
  • Other way is to pass a closure that will be executed only if the condition was related to null. In that way, the ifexistence is encapsulated, it’s the same conclusion that the video that I give you before. The point is, we sometimes be really difficult to eliminate the if. But the point is, null should be treated as a disease. Should be controlled. Another benefit to be encapsulated it’s when you are refactoring will be easier than it was spread the conditions along with our system. An example in JS of the encapsulate the if, our user object will return the address , in case that doesn’t exist, it will execute given closure to that message:
const user = {
name: undefined,
getAddress: callback => {
return name === undefined ? callback() : this.name;
}
}
user.getAddress(() => {
// Execute this closure in case that address doesn't exist.
})

Use Metaphors to design our domain problem

Please give me your thought about this short article, I love to share ideas, learn from others and I hope this article may be helpful for someone out there!

Also, you can be following me on Twitter, or contact me by Linkedin.

Full-Stack Software Developer