How To Dramatically Improve Your Ruby Code With Fundamental OOP Principles

Two of the most important object-oriented principles are cohesion & coupling.

Cohesion is about the relationship between all the methods inside a class. Are they using the same set of instance variables & parameters, all working together towards the same goal? Or does every method feel separate from each other?

Coupling is how dependent is a class to other classes, how “tied together” is it to the rest of the system, and the ability of this class to be used in isolation.

Knot image used to demonstrate coupling

Both of these concepts help you see every class in your code base through a specific set of lenses. These lenses help you find out how solid your class design is & where you could be making some changes.

For best results you want to aim for high cohesion & low coupling.

An Example Of Cohesion

Low cohesion is like having an unusual topping on your pizza, while high cohesion feels like everything is where it should be.

You can get a feeling for it, but it’s hard to measure, you can’t just get a number that tells you how cohesive your class is. So to make it easy to understand I want to show you a code example where it’s really obvious.

Here you go:

class Library
  def lend_book
  end

  def return_book
  end

  def make_coffee
  end
end

In this example make_coffee stands out quite a bit, even if this library has a cafeteria it makes no sense for the Library class to be making coffee 🙂

The cafeteria doesn’t need any information about the books it has, how to lend a book, etc.

And the library doesn’t need to know how much coffee is left or how to make it.

That’s what we mean by LOW cohesion.

Of course:

It’s not always this obvious, sometimes you need to pay attention & look beyond the method names.

  • What are these methods actually doing?
  • What data are they working with?
  • What objects are they collaborating with?

These questions should give you an idea of the level of cohesion of your class.

How do you fix low cohesion?

You’ll need to extract the methods that don’t belong to this class to another class, often a new one.

An Example Of Coupling

Now let’s have a look at coupling.

Here’s the example:

class ShoppingCart
  attr_accessor :items

  def initialize
    @items = []
  end
end

class Order
  def process_order(cart)
    cart.items.map(&:price).inject(:+)
  end
end

In this example Order is highly coupled to ShoppingCart because it knows too much about it, it knows there is an items variable & it’s doing some calculation with that.

Now if you change ShoppingCart‘s implementation of items, you’ll also have to change Order.

Not good!

We can fix it like this:

class ShoppingCart
  attr_accessor :items

  def initialize
    @items = []
  end

  def calculate_total
    items.map(&:price).inject(:+)
  end
end

class Order
  def process_order(cart)
    cart.calculate_total
  end
end

We have reduced coupling by moving the details of the calculation where they belong.

If you need a metaphor for this think about these cell phones that come with a fixed battery, that’s high coupling.

If you can replace the battery then that’s low coupling.

Notice that you still need some level of coupling, the phone wouldn’t work without a battery & the Order class wouldn’t work without knowing how much to charge the customer.

Summary

You have learned about two very important OOP principles, cohesion & coupling. These two concepts help you find out how well the methods in a class work together & how independent is your class from the rest of the system.

You can apply this right now to one of your projects, open it up & look at some of your classes. How you can you improve them using what you just learned?

Thanks for reading! Don’t forget to share & subscribe to the newsletter if you haven’t yet 🙂

16 thoughts on “How To Dramatically Improve Your Ruby Code With Fundamental OOP Principles”

  1. Great article, I had a nice reading! This principles are very important and sometimes easy to forget. I wish I knew those principles when I was learning how to use Ruby on Rails!

  2. Nice contribution! I hope that you continue do it! They are important concepts that we sometimes forget. Excelent metaphors and examples!

  3. i really appreciate and look forward to your articles , keep them coming and great work!

Comments are closed.