2. Who am I
Product Developer - Systems Architect - Freelancer - Development Manager
Past experience
Senior Developer for Cleverbug
Lecturer at the Digital Skills Academy
Director of Tercet, software development consultancy
Current position
Software Development Manager for OliveMedia
Barry O Sullivan
3. Design Patterns
When developing systems, there are common patterns of problems that
emerge.
Design patterns are common, named solutions to these problems.
The ValueObject pattern is one of these patterns.
It’s simple, easy to integrate and can bring a lot of clarity to your code with
minimal investment or technical overhead.
So lets get to it . . .
4. The Problem
public function change_name($firstname, $lastname)
{
if (!is_string($firstname) || $firstname == “”) {
throw new InvalidNameException(“Firstname is invalid”);
}
if (!is_string($lastname) || $lastname == “”) {
throw new InvalidNameException(“Lastname is invalid”);
}
$this->firstname = $firstname;
$this->lastname = $lastname;
}
Have you ever written code like this?
5. Guarding
This is called Guarding.
You are guarding against bad input
The idea is that you can’t trust the data sent by other
objects/developers, it might be invalid and break your
system, or worse, it might seem to work until it breaks
later. Guarding protects you against inconsistent state.
Guarding is as old as software development, it’s even
recommended in the Mythical Man Month, which is
nearly 40yrs old.
6. Too much guarding
The problem arises when you start adding this logic everywhere.
You end up with
• Duplicated code
• Messy Logic
• Poor legibility
Which leads to a system that’s very
difficult to modify and understand.
This leads to more bugs, not less.
7. The Solution
How do we solve this problem?
With encapsulation!
You create a class that represents the value.
On creation, it gets passed the basic types and it checks if they’re valid.
• If they are not, an exception is thrown.
• If they are, then the object is successfully created.
That’s the basic gist of it. Everywhere you need to ensure
data integrity, use one of these and you can guarantee
That the data is valid.
8. Example, Name as a ValueObject
class Name implements ValueObject
{
private $firstname;
private $lastname;
public function __construct($firstname, $lastname)
{
if (!is_string($firstname) || $firstname == “”) {
throw new InvalidNameException(“Firstname ‘$firstname’ is invalid”);
}
if (!is_string($lastname) || $lastname == “”) {
throw new InvalidNameException(“Lastname ‘$lastname is invalid”);
}
$this->firstname = $firstname;
$this->lastname = $lastname;
}
………
9. Using the Name ValueObject
//Controller method to change name
public function change_name()
{
$user = $this->user_repository->fetch($this->user_id);
$name = new Name(Input::get(‘firstname’), Input::get(‘lastname’));
$user->change_name($name);
$this->user_repository->store($user);
}
. . . . . .
//Then in our User class
public function change_name(Name $name)
{
$this->name = $name;
}
10. ValueObjects represent the value
Key Concept:
A value object represents the value,
not the data contained within it.
You shouldn’t care about the internal data when using VOs for business logic.
When you want to reference a value, use a value object.
The only place the internals matter is when you’re encoding/decoding them for
transmission (JSON/HTML) or storage (MySQL/REDIS), nowhere else.
11. ValueObjects in the wild
1. They are immutable
Once set, you cannot change their values.
In other words, you cannot change their state.
If you need to change one, simply create a new one and replace the
reference to the old one.
2. They are comparable
Two value objects of the same type can be
compared to check their values. This makes
business rules easier to build and check.
(Works a treat with the specification pattern)
12. Some examples of ValueObjects
• Email address
• Price (Amount + Currency)
• ID
• Country Code
• TestScore
• Discount
• Perspiration
NB: Usually you would not use a ValueObject to represent a user, since a user
can change state. User should be an entity that uses VOs internally.
13. Quick Recap:
ValueObjects . . .
• Encapsulate a self contained value
• Allow you to guard against bad input
• Represent the value, not the data within
• Are immutable
• Make code and system design much easier, leading to
more structured system that’s easier to maintain.
14. More reading
If you’re interested in learning more about this
pattern and others like it, I’d recommend
looking into “Domain Driven Design”,
specifically Eric Evans book.
It’s a how-to book on using this pattern and
others like it to build large scale, distributed
micro-services.
15. Thanks for listening
Any questions?
Barry O Sullivan – barry@tercet.io - http://barryosullivan.me