IMCAT.DEV
로그인 가입
Ruby 고급 디자인패턴

Ruby 디자인 패턴 (Design Patterns)

Ruby 디자인 패턴 (Design Patterns) — 고급

디자인 패턴 (Design Patterns)

1. 도입 (왜 배워야 하는가)

디자인 패턴은 소프트웨어 개발에 있어서 문제 해결의 템플릿입니다. 실무에서는 요구사항이 변화하고, 코드의 유지보수성이 중요해지기 때문에 디자인 패턴을 이해하고 활용하는 것이 필수적입니다. 디자인 패턴을 모르면 코드가 복잡해지고 유지보수하기 어려운 상황이 발생할 수 있습니다. 예를 들어, 동일한 기능을 구현하려고 할 때 매번 새로운 코드를 작성하게 되면, 코드의 중복이 발생하고 버그가 생길 확률이 높아집니다. 이는 결국 프로젝트의 완성도를 떨어뜨리고, 팀원 간의 협업을 어렵게 만듭니다.

2. 핵심 개념 설명

디자인 패턴은 크게 생성(Creational), 구조(Structural), 행동(Behavioral) 패턴으로 나눌 수 있습니다. 각 패턴은 특정 문제를 해결하기 위한 일반적인 접근 방식을 제공합니다.

패턴 유형설명
생성(Creational)객체 생성과 관련된 패턴
구조(Structural)클래스나 객체의 구성과 관련된 패턴
행동(Behavioral)객체 간의 상호작용과 책임 분배와 관련된 패턴

예를 들어, 생성 패턴은 요리에서 재료를 조합하여 요리를 만드는 것과 같습니다. 각각의 재료(객체)를 어떻게 조합할지에 대한 방법이 디자인 패턴인 겁니다.

3. 기본 코드 예제

아래는 싱글턴 패턴(Singleton Pattern)의 기본적인 코드입니다. 이 패턴은 클래스의 인스턴스가 오직 하나만 존재하도록 보장합니다.

class Singleton
  @instance = nil

  def self.instance
    @instance ||= new
  end

  private_class_method :new
end

# 사용 예
singleton1 = Singleton.instance
singleton2 = Singleton.instance

puts singleton1.object_id == singleton2.object_id # true

실행 결과

true

코드 한 줄씩 동작 설명

  1. @instance 변수를 클래스 변수로 선언하여 인스턴스를 저장할 준비를 합니다.
  2. self.instance 메서드를 통해 인스턴스를 반환합니다. 만약 인스턴스가 존재하지 않으면 new를 호출하여 새로 생성합니다.
  3. private_class_method :new는 외부에서 인스턴스를 생성하지 못하도록 막습니다.
  4. 두 개의 인스턴스를 생성하고, 이들이 동일한 객체인지 확인합니다.
  5. 4. 실전 활용 예제

    4.1. 팩토리 패턴 (Factory Pattern)

    쇼핑몰에서 다양한 상품을 생성할 때, 각 상품의 구체적인 클래스 이름을 알 필요 없이 공장(Factory)을 통해 상품을 생성할 수 있습니다.

    class Product
      def initialize(name)
        @name = name
      end
    
      def details
        "Product: #{@name}"
      end
    end
    
    class ProductFactory
      def self.create_product(name)
        Product.new(name)
      end
    end
    
    product = ProductFactory.create_product("Laptop")
    puts product.details # Product: Laptop

    4.2. 옵저버 패턴 (Observer Pattern)

    주식 시장에서 주식 가격이 변할 때마다 여러 투자자에게 알림을 보내는 상황에 적합합니다.

    class Stock
      attr_reader :price
      def initialize(price)
        @price = price
        @observers = []
      end
    
      def attach(observer)
        @observers << observer
      end
    
      def notify
        @observers.each { |observer| observer.update(price) }
      end
    
      def price=(new_price)
        @price = new_price
        notify
      end
    end
    
    class Investor
      def update(price)
        puts "New stock price: #{price}"
      end
    end
    
    stock = Stock.new(100)
    investor = Investor.new
    stock.attach(investor)
    stock.price = 120 # New stock price: 120

    5. 흔한 실수와 주의사항

    실수 1: 잘못된 인스턴스 생성

    # 잘못된 코드
    instance1 = Singleton.new # 오류 발생

    올바른 코드

    instance1 = Singleton.instance # 정상 작동

    실수 2: 옵저버를 등록하지 않음

    옵저버 패턴에서 옵저버를 등록하지 않으면 알림이 발송되지 않습니다. 이를 주의해야 합니다.

    6. 정리

    • 디자인 패턴은 효율적인 소프트웨어 설계를 위한 템플릿입니다.
    • 패턴을 통해 코드의 중복을 줄이고 유지보수성을 높일 수 있습니다.
    • 생성, 구조, 행동 패턴을 이해하고 적절히 활용하는 것이 중요합니다.
    • 다음에는 SOLID 원칙을 학습하면 좋습니다. SOLID 원칙은 객체 지향 프로그래밍의 기본 원칙으로, 디자인 패턴과 함께 사용하면 더욱 강력한 설계를 할 수 있습니다.