Those of you coming from a Google search are about to be disappointed: this is a post about types of coupling in programming.
Coupling refers to the degree to which components in your program rely on each other. You should generally seek to minimize this property, though you’ll see it’s impossible to eliminate entirely.
Here are a few types of coupling, ordered by severity (first is worst):
Your class reaches inside another class and reads (or, perish the thought, changes) its instance variables.
You are literally pathological and deserve the pain this will cause you.
class NuclearLaunchController
def initialize(launch_codes)
@launch_codes = launch_codes
end
end
class ExtremelyBadIdea
def initialize(nuclear_launch_controller)
@launch_controller = nuclear_launch_controller
end
def do_bad_things
# This is poison
@launch_controller.instance_variable_set(:@launch_codes, 'password')
end
end
You have two classes that both rely on some shared global data, maybe a Singleton or a class variable.
When many test files all depend on global factory definitions, a change to any one can ripple through the system.
# spec/factories.rb
FactoryGirl.define do
factory :user do
# Changes here are global and can affect many test files.
end
end
# spec/model/user_spec.rb
before do
# This refers to global data.
@user = build_stubbed(:user)
end
# spec/model/order_spec.rb
before do
# So does this.
@user = build_stubbed(:user)
end
Note that this is probably an example where the cure (duplicating the logic for creating test objects in every spec) is worse than the disease.
You pass in a flag that tells a method what to do.
Remember save(false) in ActiveRecord? That boolean argument caused control coupling. Remember how we all had to change our code when it became save(validate: false)? If we’d been calling save and save_without_validation instead, Rails Core could have refactored that method more times than the router and we’d never have known. Also, notice that passing validate: false into save does not reduce the coupling, it’s just disguised better.
Control couples are smelly because the calling method has intimate knowledge of how the receiver implements the method being called. You’re determining what an object should do based from outside it. Good OOP lets objects decide what to do based on their own state.
def save(should_run_validations=true)
# When you see a parameter in a conditional, that's control coupling.
# The fact that this method has an if in it has leaked out into client code.
# Changes can now require changes in these clients.
if should_run_validations
run_validations
persist
else
persist
end
end
# One possible fix: define two methods and let the clients
# choose which to call. Now we can refactor either without
# affecting clients.
def save
run_validations
persist
end
def save_without_validations
persist
end
You call a method and pass it a parameter that doesn’t affect its control flow.
This is still coupling, but we’re starting to reach the kind that isn’t so bad. Sometimes you need parameters! If you wanted to remove all coupling you wouldn’t be able to pass data between objects at all.
class ScreenPrinter
# This method is coupled to its parameter, because a change to that argument
# can cause breakage (if we undefined to_s, for example).
def print(text)
output_to_screen(text.to_s)
end
end
You call a method on an object and send no parameters.
You’re coupled to the name of the message, but not any hint of its implementation. This is the loosest type of coupling and should be your goal. Notice that this makes methods that take no arguments better than methods that take one (and so on).
# No reliance on anything outside this object. Feels good, man.
class ScreenPrinter
def print_to_screen
output_to_screen(@text)
end
end
Keep an eye out for the nasty types of coupling in your code, and see if you can can’t refactor it into something further down the ladder.
(I cribbed this list of coupling types from Wikipedia’s article, paraphrased and added examples. The original article is worth reading.)
Here’s a refactoring example for a simple Ruby math problem using the inject method.
The goal is to generate an n by n multiplication matrix. Pretty straightforward. Let’s make a first pass:
def multiplication_table(n)
results = []
(1..n).each do |row_index|
row = []
(1..n).each { |column_index| row << row_index * column_index }
results << row
end
results.each do |row|
header = '%-3s ' * row.length
puts header % row
end
end
multiplication_table(7)
1 2 3 4 5 6 7
2 4 6 8 10 12 14
3 6 9 12 15 18 21
4 8 12 16 20 24 28
5 10 15 20 25 30 35
6 12 18 24 30 36 42
7 14 21 28 35 42 49
It does the job, but it’s nothing to look at. We can condense using in-line blocks and fancy curly braces, but first let’s try using inject.
Quick background: Inject iterates over a set using a block with a collector, which is a variable whose value is passed back each round, making it good for iterative uses. The block’s return value is passed into the collector (make sure you return something or you’ll get a nil). Also, the return value of the whole inject block is the final collector value.
Simple example from the docs:
(5..10).inject {|sum, n| sum + n } #=> 45
The inject method takes a parameter, which initializes the collector value (default is to set to the first value). You can pass in an empty array and add values:
def multiplication_table(n)
results = (1..n).map do |row_index|
(1..n).inject([]) { |row, n| row + [row_index * n] }
end
results.each { |row| puts '%-3s ' * row.length % row }
end
So that’s inject with the iterative collect (Whoo-aaaa - got you all in check)
Note: For a more in-depth discussion of inject, read Mike Burns’ recent post.
I recently sat down with Mike Burns to discuss his operating system and computer setup. Mike uses an entirely Open Source stack.
We discussed how he got started with this, the current state of running Linux, as well as some of the unique benefits and cool features of doing so.
We decided to make this special video available for free, and you can watch it here.
I needed an open? method. First try:
def open?
opens_at < Time.now < closes_at
end
However, Ruby doesn’t support that kind of expression. Second try:
def open?
(opens_at < Time.now) && (Time.now < closes_at)
end
It’s noisy and lacks expression. Third time’s a charm:
def open?
Time.now.between? opens_at, closes_at
end
Ship it.
We’ve been paying closer attention lately to how we use design patterns in our Ruby on Rails work.
Decorators have emerged as one pattern that’s helped us keep code ready for change. We’ve chosen our spots carefully, but it’s proven useful quite often.
For me, it’s been a new technique that’s required asking a lot of questions to evaluate alternative decorator implementations in Ruby and understand terms.
Some questions I’ve had:

A decorator’s intent, as described in Design Patterns by the Gang of Four, is:
Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality.
Invoking a classic decorator in Ruby looks like this:
coffee = Coffee.new
Sugar.new(Milk.new(coffee)).cost
A popular alternative style is:
coffee = Coffee.new
coffee.extend Milk
coffee.extend Sugar
coffee.cost
There’s a family of patterns that are similar to decorators.
When would we use them instead of a decorator?
The Gang of Four differentiates these succinctly:
Said another way, a decorator is likely to add functionality (decorate) an object and a strategy is likely to swap functionality.
Example of a strategy in Ruby using the same Coffee analogy:
class Coffee
def initialize(brewing_strategy = DripBrewingStrategy.new)
@brewing_strategy = brewing_strategy
end
def brew
@brewing_strategy.brew
end
end
Coffee.new SteepBrewingStrategy.new
The form is similar to a PORO decorator, which is why the patterns feel related.
The difference is that the object passed to the constructor is not being “wrapped” like a decorator. We’re “swapping” functionality.
The decorator is additive and the strategy is a replacement.
With words like “guts”, “swapping”, and “replacement”, it’s no surprise that strategies are often used with Dependency “Injection”. In the example above, constructor injection lets us easily swap the brewing strategy.
Gang of Four:
Example of a composite in Ruby from the ActivePresenter library:
class SignupPresenter < ActivePresenter::Base
presents :user, :account
end
A decorator decorates a single component and a composite composes multiple components (user and account in the example above).
Both patterns are named well.
Now, the most confusing one:
This is my own definition. I don’t have an authority to refer you to since you won’t find “Presenter” in Gang of Four. As best I can tell, the Rails community began using the term “Presenter” with this 2007 article by Jay Fields.
The easiest mnemonic is just to defer to their names. What makes a presenter a presenter is its presentation-ness.
One example:
class HumanizedStat
def initialize(component)
@component = component
end
def to_s
# giant case statement that used to be in a model
end
# a bunch of private helper methods supporting #to_s
# which used to be in app/helpers
end
In this case, the presenter looks a lot like a decorator (but doesn’t meet the Gang of Four definition): it’s adding functionality to a single component.
However, because the functionality is completely presentation-related, I’d expect this to be considered a presenter and maybe saved in a app/presenters directory.