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.
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 🙂
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!
Thanks for reading & leaving a comment Fernando 🙂
Nice contribution! I hope that you continue do it! They are important concepts that we sometimes forget. Excelent metaphors and examples!
Thanks for your comment Daniel, I’m glad you liked the article! 🙂
Nice article with good example.?
Thank you! 🙂
Another great article! For me, one of the best blogs on Ruby.
Thank you Rostyslav, I’m glad you’re enjoying my blog 🙂
i really appreciate and look forward to your articles , keep them coming and great work!
Thank you Eric! 🙂
Sweet! Thanks for sharing!
Thanks for reading Amit! 🙂
Nice article. Thanks for this
Thanks for reading Michael! 🙂
it’s really easy to understand 🙂
Thank you 🙂