Very Valuable Value Objects!

Value objects are awesome! I love them! If I ever get a chance to use a value object, which is often, I will — every time! And no, I’m not talking about the old school J2EE “Value Object.” I am talking about good-old, run-of-the-mill, immutable value objects. Why do I love them? Because they are extraordinarily powerful, insanely easy to use, encourage unit testing, and are simple to maintain.

This post isn’t going to cover the specifics of value objects or how we model them in any detail. There are plenty of articles on those topics. So, if that is what you are seeking, this is not it. Though, I have taken the liberty of starting you on your search. :{)}

What we will cover today are a few concrete examples of common value objects found in the ku4js-kernel library, specifically, properName, phoneNumber, dayPoint, and money.

So, let’s, quickly, take a peek, run a few examples, and then continue on your way to building awesome, quality, maintainable systems. If you don’t already have it, grab the latest ku4js-kernel from GitHub, open your favorite browser console, and, without further ado, let’s get started.

properName

Often times, systems that we develop contain people, and those people have names, a.k.a., in this case, properNames. The problem with names is that they are deceptively complex. Many developers tend think of them, simply, as a string, but proper names are more than that. Names, generally, consist of first names, middle names, and last names. Often times we are interested in the initials of a name, other times we must format the name in a specific way. Whatever the case, a name is certainly more than a string, but this common oversight tends to lead many developers down the road of creating “Utilities” or “Formatters,” which are hideous boilerplate that should be avoided and done away with.

A much more appropriate approach is to leverage a name class that contains the features that we expect a name to have. This allows our names to actually be names, and not strings posing as such. Furthermore, this approach makes a name responsible for what it is and how it behaves, and allows us to scrap the boilerplate “Utilities” and “Formatters.”Enter the first of the value objects that we will look at today: $.properName. This class, as with the others that follow, is found in the ku4js-kernel library. Let’s play!

Say, you have a secure system where employees are to confirm that they are the agent responsible for completing some work item, or task. This system displays the logged-in user’s name in various ways:

  • it display’s the user’s full name in the upper right-hand corner of the view to inform them that they are the party currently logged in
  • it shows their name in the “last name first, first name last” on a “Work Complete” form, and
  • it contains an “Initial” button that, when pressed, adds the user’s initials to said form near the task in question to indicate confirmation of work completed and responsibility accepted.

Three different name representations, all the same name. A ‘textbook’ place in a codebase for “Utilities,” “Formatters,” and other boilerplate to manifest, bloat the code, go untested, and give rise to future side-effects. But not with $.properName. $.properName encapsulates all of these name features in one name class, as it should be!

So, let’s say that one of the people in our system is named, Erin Kelly VanBuren. The server serves the name in a common, unthoughtful, string format: “Erin Kelly VanBuren.” Let’s create a $.properName. Then, use it to satisfy our system requirements.

var name = "Erin Kelly VanBuren",
    split = name.split(/\s/),
    properName = $.properName(split[0], split[1], split[2]);

Now you can get the full name:

properName.full();

The “first name last, last name first” format:

properName.toStringWithFormat("{L} {F}, {m}.");

And her initials

properName.initials();

BOOM! :{)}

phoneNumber

Phone numbers have issues similar to names. They are, again, a deceptively complex concept that is, all too often, misrepresented as a simple string, leading to bloated untested boilerplate. Generally, this occurs, on the front-end, because phone numbers can begin at the user input level and phone numbers are extraordinarily diverse in their formatting. For example, the phone number, (222) 678-8933, is the same as 222-678-8933, is the same as 222.678.8933. This causes numerous problems in validation and in representation, and far many more developer hours than are needed to be spent on something so seemingly trivial. Enter $.phoneNumber.

var phoneNumber1 = $.phoneNumber(2226788933),
    phoneNumber2 = $.phoneNumber.parse("222.678.8933"),
    phoneNumber3 = $.phoneNumber.parse("222 678 8933");

phoneNumber1.toStringWithFormat("(###) ###-####") == "(222) 678-8933";
phoneNumber2.toStringWithFormat("(###) ###-####") == "(222) 678-8933";
phoneNumber3.toStringWithFormat("(###) ###-####") == "(222) 678-8933";

phoneNumber1.toStringWithFormat("1-###-###-####") == "1-222-678-8933";
phoneNumber2.toStringWithFormat("1-###-###-####") == "1-222-678-8933";
phoneNumber3.toStringWithFormat("1-###-###-####") == "1-222-678-8933";

phoneNumber1.equals(phoneNumber2);
phoneNumber1.equals(phoneNumber3);
phoneNumber2.equals(phoneNumber3);

Simple! :{)}

dayPoint

Days are yet another seemingly simple construct that definitely is not! Days get crazy because, again they can be formatted different ways, i.e. mm/dd/yy vs. dd/mm/yy, and also because they follow odd rules: 30 days one month 31 another, 28 days in February one year, 29 another. This makes traversing any given sequence of days quite difficult! Then it gets worse when building, say, retail sites, when there are, say, specials, or sales: “Every weekend in July, stop in for our Independence Day Blow Out!” Well, which days is that?! Is today an Independence Day Blow Out day? Is tomorrow? How about three weeks from now? All tough questions to answer, and all common reasons for more bloat and boilerplate. Enter $.dayPoint. With an actual day concept, we can ask a day all about itself, and expect that it should know the answers.

var day1 = $.dayPoint(2015, 2, 28),
    valentinesDay = $.dayPoint(2015, 2, 14),
    independenceDay = $.dayPoint(2015, 7, 4);

day1.nextDay().toString() == "03/01/2015";
day1.nextMonth().lastDayOfMonth().toString() == "03/31/2015";

day1.add(5, 0, 0).toString() == "02/28/2020";
day1.add(5, 2, 0).toString() == "04/28/2020";
day1.add(5, 2, 4).toString() == "05/02/2020";

day1.nextYear().nextDay().toString() == "02/29/2016";

day1.isLeapYear() == false;
day1.add(1, 0, 0).isLeapYear() == true;

day1.isBefore(valentinesDay) == false;
day1.isAfter(valentinesDay) == true;

day1.isBefore(independenceDay) == true;
day1.isAfter(independenceDay) == false;

Here, again, we can see that all of the complexity and nuance is encapsulated in one sophisticated, yet simple, value object. Excellent!

money

The last value object that we will look at today, has always been one of my favorites — money! Money is, certainly, less complex than days though it is nuanced. At times we want it to work like a number and at other times we want it to be a string. You can perform math operations on money, but money also contains important metadata, i.e. currency;  two different currencies cannot be operated on mathematically except over some exchange rate. The level of specificity of money that is important often differs from app to app, and decimal mark and thousands separator can differ between countries. Again all issues commonly giving rise to more boilerplate that is needless once we have $.money.

Let’s say that we want to purchase something awesome that costs  2.51 Bitcoin. We have 1322.78 USD, and the current exchange on Bitcoin to USD is 510.43. We also have rent that is due at the end of the month: 600.00 USD. Can we afford to buy something awesome?

var cashOnHand = $.money(1322.78, "$"),
    rent = $.money(600, "$"),
    somethingAwesome = $.money(2.51, "B"), 
    Bto$ = 510.43,
    $toB = 1/Bto$;

cashOnHand
   .subtract(somethingAwesome)
   .isGreaterThan(rent); //Throws non-conforming currencies exception

cashOnHand 
    .subtract(somethingAwesome.exchange(Bto$, "$"))
    .isGreaterThan(rent) == false;

cashOnHand 
    .subtract(somethingAwesome.exchange(Bto$, "$"))
    .toString() == "$41.80";

cashOnHand.toString() == "$1,322.78";
cashOnHand.toString(".", ",") == "$1.322,78";

Looks like we’ll be sending the landlord an I.O.U. :{)}

So, there you go, a couple of really cool, clean value objects that come packaged and ready to go in ku4js-kernel. I hope that you find them useful, and use them to clean up any unruly boilerplate, “utilities”, or “formatters” that you might have in your codebase.

Please, comment on and share this post with others if you enjoy it; follow @kodmunki on Twitter for regular updates on new developments, deployments, articles, and tools; check out kodmunki™ on Github for cool, managed, and tested kodmunki™ projects, and find heavy tunes to flip bits to on komdunki™ SoundCloud page.
Thank you for reading, and as always, happy coding :{)}
Advertisements

Software development leaders at the forefront of the latest in technology. Whether implementing updates or integrating with existing technology; developing products that push the bleeding edge of the latest in tech; or developing open-source products, paving the way of future tech, kodmunki™ inspires innovation, elevates quality, and drives value to production. kodmunki™ are experts in web, mobile, and hybrid solutions development; local and distributed team management and collaboration; and fast, quality, successful product delivery, offering R&D, training, consulting, and development services. Contact us at info@kodmunki.com. Let's discuss your vision.

Posted in JavaScript
One comment on “Very Valuable Value Objects!
  1. […] I hope that you enjoyed this short read, found it insightful, and find the ku4js-* libraries useful! Too, if you are actually looking to round money, I suggest taking a look at the ku4js-kernel money class. It not only rounds, but also takes care of numerous other nuances with money. More on this in Very Valuable Value Objects! […]

Enjoy the read? -- Let us know.

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

kodmunki™ Tweets

Enter your email address and receive notifications of new kodmunki™ posts by email.

%d bloggers like this: