giant robots smashing into other giant robots

We are thoughtbot. We make web & mobile apps.

Tagged:

Comments (View)

Role Suggesting Name

There’s an excellent discussion on Josh’s “self” post last week. In it, I argued:

in my opinion, naming classes, methods, and variables expressively should be the #1 goal of a programmer when writing or refactoring code.

How to write great names

The path to great naming involves a few simple rules.

You can often deduce the scope and type of a variable.

The one thing you can’t deduce from a variable is its role, or purpose, it plays in the application.

Example

The following is something I wrote today.

Let’s consider a CreditCard class:

class CreditCard < ActiveRecord::Base
  belongs_to :brand_manager, :class_name => "User"
end

class User < ActiveRecord::Base
  has_many :credit_cards, :foreign_key => "brand_manager_id"
end

Why

Context.

What reads better to you when you use these objects?

This…

user.credit_cards
credit_card.user

… or this?

brand_manager.credit_cards
credit_card.brand_manager

“User” is too generic. In the real world, credit cards don’t have users.

In the domain-specific language of this application, the people are referred to as “brand managers”.

Why not just name the model BrandManager?

In this case, User is overloaded to handle three different roles using simple flags on the model. This allows us to use Clearance normally and keeps authentication and standard user vocabulary available where it makes sense.

Another example

class Impression < ActiveRecord::Base
  belongs_to :campaign, :class_name => "Offer"
end

From the same application, we again see a case where the object in question plays two different roles depending on to whom it is being displayed. The object is a campaign to advertisers and offer to recipients.

From the perspective of impressions, the Role Suggesting Name is campaign.

Reveal refactoring opportunities

In this second example, we now intend to rename the Offer model Campaign.

We were undecided which name would be dominant in the app when we first wrote the model but as we’ve written new features, using Role Suggesting Name has dictated that the model should be renamed as there is only one place where offer makes sense.

By caring about naming as we’ve gone, that eventual refactoring will be painless as we have less code to change. We did not let ourselves feel restricted by original name, and let context and purpose drive naming.

100% stolen from studying the masters

I first heard of this idiom in Smalltalk Best Practice Patterns by Kent Beck.

I heard it applied to a similar use case in Philippe Hanrigou’s talk, What the Ruby craftsman can learn from the Smalltalk master.

There’s a lot more to great naming but I can’t say it any better than those guys, so watch Philippe’s talk and read the book.