Value Objects to avoid Primitive Obsession
refactoring
NodeFlair Salaries is one of the many products by NodeFlair, a Tech Career SuperApp. It allows tech talents to look up the latest updated salaries and compensation in the market.
Most users we spoke to have is not knowing the salary details for a particular job opening. The current non-ideal workaround is to browse existing job listings that are similar, to get a gauge (if that is even possible).
As such, one of the features of NodeFlair Salaries is to solve this issue is to crawl job listings, tag them according to important attributes like specialisations and seniorities. Here’s a screenshot of it.
Tagging seniorities of a job listing
There are many attributes that we use, but I will simplify it for this post to use just the job listing’s title.
- If it contains the word ‘junior’, it’s a junior position
Issue with Primitive Obsession…
There’s quite a couple of content out there that explains this, so let me just quote this blogpost on Object Calisthenics.
TL;DR every variable with type that was not written by yourself is primitive, and you should encapsulate them to a class by their behaviours.
Let’s take a look at the initial implementation
Okay, not THAT bad. You kinda get what it is doing. But it does take you some time to digest it. And as this code smell appears in other parts of the code, the total time wasted will accumulate over time.
Value Object to the rescue!
Why do I think this is better?
Improved Readability
Almost always, this will lead to improvement in readability as you can give better names to variables, methods etc. This gives better context about what they are, and what is happening.
It would be tempting to wrap the logic in a method like the one below.
There’s nothing wrong with it, but I find that
- It is still dealing with primitive types like String
- Often, it results in methods with an unnecessarily long name and arguments at first glance, making the code less readable. E.g.
abstract_tech_stacks_from_job_listing_description(...)
😵
Business logics are abstracted and hidden away
Let’s say we want to update the logic in determining the seniority. As the logic to determine the seniority has been abstracted and encapsulated within the Title
class, any changes can be made easily without the object seniority
object do not have to care about it.
Class can be extended easily
Let’s say now we also want to determine the specialisation (e.g. data scientist, software engineer) from the title. We can add a new method easily!
A little about what I do at NodeFlair…
The world today runs on code written by developers that solve the world’s problems and impact lives.
Now, imagine a world where developers get to code at a place where they find purpose in their work. This meaning could translate into drive that pushes boundaries to solve more of the world’s problems.
That’s why at NodeFlair, we make it our mission to improve the world by empowering developers to code() at where they love.