A very important topic in object-oriented design is 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.
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.
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 with cohesion.
It’s not always this obvious, sometimes you need to pay attention & look beyond the method names.
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.
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
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 being able to know how much to charge the customer.
You have learned about two very important OOP topics, 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 🙂