I. Introduction

Design patterns are essential tools in a software developer’s toolkit, offering reusable solutions to common problems encountered in software design. By following established design patterns, developers can create elegant, maintainable code that adheres to best practices and design principles. In this article, we delve into the world of design patterns in Ruby, exploring some of the most popular patterns and their applications in real-world scenarios.

List of design patterns:

  • Singleton Pattern
  • Factory Pattern
  • Observer Pattern
  • Strategy Pattern
  • Decorator Pattern
  • Template Method Pattern
  • Command Pattern
  • Adapter Pattern
  • Proxy Pattern
  • Composite Pattern
  • State Pattern
  • Chain of Responsibility Pattern
  • Iterator Pattern
  • Visitor Pattern
  • Memento Pattern
  • Mediator Pattern
  • Flyweight Pattern
  • Builder Pattern
  • Prototype Pattern
  • Abstract Factory Pattern
  • Bridge Pattern
  • Facade Pattern

II. Singleton Pattern

The Singleton pattern ensures that a class has only one instance and provides a global point of access to that instance. In Ruby, the Singleton module can be used to implement the Singleton pattern. Here’s an example of a Singleton class in Ruby:

require 'singleton'

class Logger
  include Singleton

  def initialize
    @log = File.open('log.txt', 'a')
  end

  def log(message)
    @log.puts(message)
  end
end

In this example, the Logger class is a Singleton that ensures only one instance of the Logger class is created. The log method can be used to log messages to a file.

III. Factory Pattern

The Factory pattern is a creational pattern that provides an interface for creating objects without specifying their concrete classes. In Ruby, the Factory pattern can be implemented using class methods or a dedicated Factory class. Here’s an example of a Factory class in Ruby:

class ShapeFactory
  def self.create_shape(type)
    case type
    when :circle
      Circle.new
    when :square
      Square.new
    when :triangle
      Triangle.new
    else
      raise ArgumentError, "Invalid shape type: #{type}"
    end
  end
end

In this example, the ShapeFactory class provides a create_shape method that creates instances of different shapes based on the specified type.

IV. Observer Pattern

The Observer pattern is a behavioral pattern that defines a one-to-many dependency between objects, so that when one object changes state, all its dependents are notified and updated automatically. In Ruby, the Observer pattern can be implemented using the Observable module. Here’s an example of the Observer pattern in Ruby:

require 'observer'

class Subject
  include Observable

  def change_state(new_state)
    changed
    notify_observers(new_state)
  end
end

class Observer
  def update(new_state)
    puts "Received update: #{new_state}"
  end
end

subject = Subject.new
observer1 = Observer.new
observer2 = Observer.new

subject.add_observer(observer1)
subject.add_observer(observer2)

subject.change_state('new_state')

In this example, the Subject class is observable, and the Observer class receives updates when the subject’s state changes.

V. Conclusion

Design patterns play a crucial role in software development by providing reusable solutions to common design problems. By leveraging design patterns such as the Singleton, Factory, and Observer patterns, developers can create robust, maintainable code that adheres to best practices and design principles. Understanding and applying design patterns in Ruby can help developers build scalable, flexible software solutions that meet the demands of modern software development.

References: