Value Object in Ruby

Perhaps you already stumbled upon a piece of code like this:

class ReportCard
attr_accessor :grades
 def initialize(attributes = {})
@scores = attributes[:scores]
@grades ||= grade_scores
end
 private
 def grade_scores
@scores.map do |score|
grade_score(score)
end
end
 def grade_score(score)
if score < 60
‘F’
elsif score < 70
‘D’
elsif score < 80
‘C’
elsif score < 90
‘B’
else
‘A’
end
end
end

Grade Score is something that stores some values, maybe those values are not persisted in any database, maybe we're just using these values in our business logic. Normally they are simple objects which are used widely. Value Objects may be Dates, MoneyCurrency, strings, etc.

Let's try to define what a value object is:

A small simple object, like money or a date range, whose equality isn’t based on identity. — Martin Fowler

Now we know how to discover a value object in our code and some possible definitions.

Why value objects are important?

Maybe the question should be: when should I use value objects? Or even, when should I extract value objects from my code?

In the code above we have the Grade Score code as value object and I certainly should extract that and put it in a new ruby class file or module named GradeScore or something like that.

There are some important facts we should take attention related to value objects, they are:

  • Value objects normally have multiple attributes
  • Attributes should be immutable through its life cycle
  • Equality is determined by its attributes and not related to the memory address.

Probably using Value Objects might inspire you to write a more neat code?

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.