JS Value Objects – 4. Equality

Until now we learned how to create a Value Object. But we’ve seen that 2 instances of the same value object created with the same value do not equal each other. How can we make sure that their equality is based on value instead of identity? Let’s take a more practical example!

Note: This is the fourth post in a series about the use of Value Objects in JavaScript.

Registration form

We are going to build a very simple registration form with an email field and two password fields. When the user submits the form we want to validate the input before posting it to the server. When validation fails we prevent the post and show the validation error to the user.

The HTML might look something like this:

And the JavaScript like this:

In the validation part we need to verify that all fields are filled, that the email address is valid, that the password is strong enough and that the second password matches the first one. We will do this by first creating a Value Object for both email address and password.

EmailAddress and Password

We define EmailAddress in the same way as Integer in the previous post.

There is not much to it really. The only thing that makes the difference is the validation part. In this case we use a simple regular expression that tests the passed value for an @ and a dot with some other characters around it, but of course, you can make the regex as strict as you want. If the test fails we throw an exception stating that the value is not a valid email address.

Extra methods could be added to the object to access specific parts of the email address like the local part (before the @) and the domain part (after the @).

Passwords have to be strong, so they cant be easily guessed. In this example we define strong as ‘containing at least 8 characters and including at least 1 lowercase character, 1 uppercase character and 1 digit’.

Form validation

Validation is pretty simple now. We only have to create nwe instances of the defined Value Objects with the provided form input and all will be done automatically. The only thing we have to do ‘manually’ is checking if the two passwords are the same.

Sadly, we can’t compare the password objects directly because objects are always unique. Instead we have to compare the values of the those objects. Although it isn’t the worst thing you could think off, it still looks and feels a bit weird. If we compare strings or numbers with each other we do not need to access its inner value (we actually need to if we create them from their objects instead of from literals).

But is there no way to fix this? Yes, there is!

Equality with the flyweight pattern

The Flyweight pattern is primarily used to reduce the number of objects created and to decrease memory footprint and increase performance. It will try to reuse already existing similar objects by storing them and creates new object when no matching object is found.

To simplify: Instead of creating 3 exactly the same objects only one instance is created and that one is referenced 3 times. Its works like a caching system. Of course this pattern has clear limitations. The main downside is that, if one of the references is changed, the original cached object is changed and therefor all references. So it is important that the object is immutable. Doesn’t sound that familiar?

Let’s build one for our Password VO. We start with the factory, the distributor of the flyweight objects.

Simple as that! Instead of instantiating the password our self we let it be created by the factory. It will first check if it has created a password with the same value before, if so he returns it, if not he creates it, stores it and returns it.

We reached our goal: Value Objects being equal on value.

Refactor

Creating passwords like this doesn’t make beautiful code, but praise JavaScript for being awesome! We can rebuild the Password constructor to make it implement this pattern.

Defining the Password is now done inside a private scope to prevent variable name collisions, might you want to apply this pattern for more Value Objects (which you do, but more about that in the next post). The password constructor is now actually the flyweight factory that makes use of a private constructor defining the password. This gives us the ability to compare passwords that are created through pure instantiation.

I am really exited about this! As you see in the example, we actually beat the native data type objects, because they are not equal on value.

Back to our form validation we can now compare the two passwords without the need to access the value property of both objects.

Summary

We saw how Value Objects can be implemented in real life development with a practical example. Value Objects make validation easier and more readable, because they have high cohesion; everything about an email address is inside the object EmailAddress. There is no need to put any logic concerning the email address in the validation function.

A big improvement is the implementation of the Flyweight pattern that allows us to compare objects based on their value instead of their identity. This also makes our objects comply with the second key-property of values: ‘no life cycle’ (see post 2 in this series). Value Objects are no longer created (technically they are created the first time), but instead are references to an instance in the ‘universe of values’.

It is time to put all our discoveries together and create a library that helps us to generate our own Value Objects. To be continued…