---
title: never be satisified
teaser:
tags: web,analytics
author: Jared Carroll
published_on: 2007-04-13
---

Everyone loves metrics.  I think they're great guidelines and can help you push
yourself into writing a lot better code.  The first step is knowing the
guidelines, then you have to know when to apply them.  For example, "classes
should have roughly 12-15 methods"; now don't always follow that for the sake of
meeting the metric.  In some cases it applies, in others it doesn't, it's a
judgement call.  So say you've written the following code and you now take some
time to reflect on it by comparing it to your list of metrics, specifically the
above metric of "classes should have roughly 12-15 methods".

```ruby
class User < ActiveRecord::Base

  has_many :subscriptions

  def subscribe_to(magazine)
    self.subscriptions << Subscription.new(:user => self,
                                            :magazine => magazine)
  end

  # 13 other User related methods

  def full_name
    "#{first_name} #{last_name}"
  end

  def short_name
    "#{first_name.first}. #{last_name}"
  end

  def formal_name
    "#{last_name}, #{first_name}"
  end

end
```

Now looking at the above code there's 17 (ignoring Rails generated methods)
methods in the User class. Now those last three methods deal with formatting the
user's name in different ways.  More importantly, they put me over the metric;
I'm now at 17 methods.  So I ask myself, those 3 methods seem all related to a
user's name.  Maybe I'm missing an object in there somewhere?  Yes of course, a
Name object.  Let's move that name related behavior there.  So we now have:

```ruby
class User < ActiveRecord::Base

  has_many :subscriptions

  composed_of :name,
    :mapping => [%w(first_name first_name),
                  %w(last_name last_name)]

  def subscribe_to(magazine)
    self.subscriptions << Subscription.new(:user => self,
                                            :magazine => magazine)
  end

  # 13 other user related methods
  # name related behavior has moved to the Name class

end

class Name

  attr_reader :first_name, :last_name

  def initialize(first_name, last_name)
    @first_name, @last_name = first_name, last_name
  end

  def full_name
    "#{first_name} #{last_name}"
  end

  def short_name
    "#{first_name.first}. #{last_name}"
  end

  def formal_name
    "#{last_name}, #{first_name}"
  end

end
```

(I'd probably refactor those method names in the Name class to just `#full`,
`#short` and `#formal`; having the word "name" on the end of them is redundant)

We now meet our metric of "12-15 methods per class".  In the process we've
modularized (put in one place) all the name related behavior and simplified the
User model by delegating its name related behavior to another object.  Metrics
pushed us into thinking harder about our code and resulted in simpler, more
expressive code.
