RubyGuides
Share this post!

All posts by Jesus Castello

Ruby singleton pattern

How To Use The Singleton Pattern In Ruby (And Why You Should Avoid It)

Have you ever wanted to create a class that can only have one instance?

No?

Me neither.

But that’s exactly what the singleton pattern is.

Some people even call this an anti-pattern!

Let’s have a look at a code example, so you know what it looks like.

Singleton Pattern Code Example

The idea of the singleton pattern is that you want a class with only one instance.

To do this:

  • You make the new method private
  • You define a class method named instance that returns the unique instance for the class

Because this is a popular design pattern, the Ruby standard library comes with a Singleton module you can include in any class.

It looks like this:

Now if you try to create a Shop object with Shop.new you’ll see this:

And if you want to get the one & only Shop object you can use the instance method:

You can tell it’s always the same object because the object_id never changes.

What you need to remember:

This is a simple pattern, it limits object creation to 1 object & you can request that object whenever you want.

Why You Shouldn’t Use This Pattern

The singleton pattern is often an excuse to have some form of global variable & we know global variables are bad because you have no control over them. This makes things harder to test & it can increase coupling.

“The real problem with Singletons is that they give you such a good excuse not to think carefully about the appropriate visibility of an object.” – Kent Beck

Imagine having an object that most of your classes depend on, that’s what the singleton pattern can become. Good luck refactoring that!

Now:

Are there any good uses for this pattern?

Searching on Github turned up some repos using the Singleton pattern in conjunction with the Null object pattern. I guess that makes sense, Rails uses this as part of ActionPack.

Here’s the code:

This ensures there will only be one AllType object.

Video

Summary

You learned about the singleton design pattern, how to implement it in Ruby & why you should avoid it most of the time.

What do you think about this pattern? Have you seen it before? Let me know in the comments 🙂

Thanks for reading!

ruby cohesion and coupling

How To Dramatically Improve Your Ruby Code With Fundamental OOP Principles

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.

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:

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 🙂

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.

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:

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:

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.

Summary

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 🙂

strategy design pattern

How to Use The Strategy Design Pattern in Ruby

Let’s talk about the strategy design pattern!

This design pattern helps you change the main algorithm inside a method.

You do this by passing in a class that implements this algorithm, instead of hardcoding it into the class.

And when I say algorithm I don’t mean a fancy computer science algorithm, but any code that follows a sequence of steps to get a result.

When To Use The Strategy Pattern

What problem is this pattern solving exactly?

The open/closed principle problem.

This principle says that:

“Software entities (classes, modules, methods) should be open for extension & closed for modification.”

This means that to make a class do new things you shouldn’t need to change the class itself. This makes your code more flexible & robust at the same time.

But how do you accomplish that?

Using design patterns like the strategy pattern 🙂

Let’s say you have a ReportGenerator class, and you want to generate many kinds of report formats using the same data.

You could write a method for each report type, but that would mean you have to change the class (by adding a new method) every time you want to add a new type, breaking the open/close principle.

Or even worse!

You could have a single HUGE method with all sorts of if statements… These often don’t end up well.

But what if the class didn’t have to know how to format the reports?

What if the algorithm came from outside the class?

Then we can change the formatting algorithm whenever we want without changing the class itself.

This solves the problem.

And that’s exactly what the strategy pattern is all about.

Strategy Pattern Example

A strategy is implemented in the form of a class with a single method.

Here are some formatting strategies for the ReportGenerator class:

Notice how all of the strategies implement the format method. This method will be called by the report generator class.

Here is the code:

Now:

If you want to change the output format (from HTML to PlainText) you just have to pass in a different strategy & it will work as long as the strategy implements the format method.

Another way to think about this pattern is that you are hiring a consultant specialized in a specific business strategy, the consultant will come in & implement the strategy for you, then this strategy will produce a specific result.

In contrast, a pattern like the decorator pattern is like adding new ornaments to a Christmas tree to make it more flashy.

You can only work with 1 strategy at a time, but you can have as many ornaments as you want.

Video

Summary

You have learned about the strategy design pattern, use it when you need to change part of what your class does without having to change the class itself.

Thanks for reading!

Don’t forget to share this post on Twitter if you found it interesting, it will help more people enjoy it too 🙂

decorator design pattern

How To Use The Decorator Pattern in Ruby

The decorator design pattern…

What is it, and how can you use this pattern in your Ruby projects?

The decorator design pattern helps you enhance an object by adding new capabilities to it without having to change the class.

Let’s have a look at an example.

Logging & Performance

In this example we are making HTTP requests using a gem like rest-client.

Here’s what that looks like:

Now:

Let’s say that we want to add logging to some of our requests, and we don’t want to change the RestClient module.

We can do this using the decorator pattern.

Here’s our logging module:

This will print the information we want on the screen then call the original get method from RestClient.

To add logging capabilities to a request you can use the extend method.

Like this:

You have to create this HTTPClient wrapper class because RestClient is a module & you can’t create objects from modules.

When To Use The Decorator Pattern

The beauty of this pattern is that you are only enhancing one object, so you could have a non-logging client & a logging client.

Another benefit is that you can layer these decorators & have one that does performance testing, another for logging, etc.

Combining decorators would not be possible if you used inheritance to create a HTTPClientWithLogging, and a HTTPClientWithPerformanceTesting class.

Inherithance Diagram

You can’t have WithLogging and WithPerformanceTesting at the same time unless you create this class…

The decorator pattern solves this problem while avoiding code duplication & crazy class names.

Video

Summary

You have learned about the decorator design pattern, this pattern helps you add new capabilities to objects without having to change the class.

Don’t be passive! Now it’s your turn to practice & apply this concept yourself. It will help you remember this when you need it.

Share this article so more people can read it 🙂

ruby memory leak

How To Create A Memory Leak in Ruby

There are a few articles out there about how to find memory leaks.

But how about creating one?

I think it will be an interesting exercise so you know what a memory leak looks like in Ruby.

Let’s see some examples.

A Simple Leak

We can create a memory leak by simply adding new objects to an array.

Like this:

This creates 10k strings every second & it prints an object count:

The count keeps going up because the GC can’t collect these strings, they are being referenced by the containing array (a).

If a goes out of scope that will allow the GC to collect all these "abc" strings. You can test this with the example above by setting a to nil, then running GC.start.

You can find a live example here, just click run to see the results.

C Extension Leak

When you create an object from Ruby the GC keeps track of how much memory it is using, but when using a C extension Ruby has no control over what happens.

If you create a C extension like this:

The allocate_memory() function will leak memory because it’s using malloc & it doesn’t call free to release that memory.

As you can see here:

This kind of leak won’t show up on any heap dump or on GC.stat, but you will see memory usage grow.

Summary

Now you know what a memory leak looks like, hopefully that will help you find one faster if you ever have this issue. Btw Ruby 2.4.1 has a known memory leak, so you may want to upgrade if you are using this specific version.

Do you have any questions, feedback or an interesting memory leak debugging story? Leave a comment below 🙂

Thanks for reading!

1 2 3 25