봄맞이 세일
팩토리 메서드

루비로 작성된 팩토리 메서드

팩토리 메서드는 제품 객체들의 구상 클래스들을 지정하지 않고 해당 제품 객체들을 생성할 수 있도록 하는 생성 디자인 패턴입니다.

팩토리 메서드는 메서드를 정의하며, 이 메서드는 직접 생성자 호출​(new 연산자)​을 사용하여 객체를 생성하는 대신 객체 생성에 사용되여야 합니다. 자식 클래스들은 이 메서드를 오버라이드하여 생성될 객체들의 클래스를 변경할 수 있습니다.

다양한 팩토리 패턴들과 개념들의 차이점을 이해하지 못하셨다면 팩토리 비교를 읽어보세요.

복잡도:

인기도:

사용 사례들: 팩토리 메서드 패턴은 루비 코드에서 널리 사용되며 코드에 높은 수준의 유연성을 제공해야 할 때 매우 유용합니다.

식별: 팩토리 메서드는 구상 클래스들로부터 객체들을 생성하는 생성 메서드들로 인식될 수 있습니다. 구상 클래스들은 객체 생성 중에 사용되지만 팩토리 메서드들의 반환 유형은 일반적으로 추상 클래스 또는 인터페이스로 선언됩니다.

개념적인 예시

이 예시는 팩토리 메서드의 구조를 보여주고 다음 질문에 중점을 둡니다:

  • 패턴은 어떤 클래스들로 구성되어 있나요?
  • 이 클래스들은 어떤 역할을 하나요?
  • 패턴의 요소들은 어떻게 서로 연관되어 있나요?

main.rb: 개념적인 예시

# The Creator class declares the factory method that is supposed to return an
# object of a Product class. The Creator's subclasses usually provide the
# implementation of this method.
class Creator
  # Note that the Creator may also provide some default implementation of the
  # factory method.
  def factory_method
    raise NotImplementedError, "#{self.class} has not implemented method '#{__method__}'"
  end

  # Also note that, despite its name, the Creator's primary responsibility is
  # not creating products. Usually, it contains some core business logic that
  # relies on Product objects, returned by the factory method. Subclasses can
  # indirectly change that business logic by overriding the factory method and
  # returning a different type of product from it.
  def some_operation
    # Call the factory method to create a Product object.
    product = factory_method

    # Now, use the product.
    "Creator: The same creator's code has just worked with #{product.operation}"
  end
end

# Concrete Creators override the factory method in order to change the resulting
# product's type.
class ConcreteCreator1 < Creator
  # Note that the signature of the method still uses the abstract product type,
  # even though the concrete product is actually returned from the method. This
  # way the Creator can stay independent of concrete product classes.
  def factory_method
    ConcreteProduct1.new
  end
end

class ConcreteCreator2 < Creator
  # @return [ConcreteProduct2]
  def factory_method
    ConcreteProduct2.new
  end
end

# The Product interface declares the operations that all concrete products must
# implement.
class Product
  # return [String]
  def operation
    raise NotImplementedError, "#{self.class} has not implemented method '#{__method__}'"
  end
end

# Concrete Products provide various implementations of the Product interface.
class ConcreteProduct1 < Product
  # @return [String]
  def operation
    '{Result of the ConcreteProduct1}'
  end
end

class ConcreteProduct2 < Product
  # @return [String]
  def operation
    '{Result of the ConcreteProduct2}'
  end
end

# The client code works with an instance of a concrete creator, albeit through
# its base interface. As long as the client keeps working with the creator via
# the base interface, you can pass it any creator's subclass.
def client_code(creator)
  print "Client: I'm not aware of the creator's class, but it still works.\n"\
        "#{creator.some_operation}"
end

puts 'App: Launched with the ConcreteCreator1.'
client_code(ConcreteCreator1.new)
puts "\n\n"

puts 'App: Launched with the ConcreteCreator2.'
client_code(ConcreteCreator2.new)

output.txt: 실행 결과

App: Launched with the ConcreteCreator1.
Client: I'm not aware of the creator's class, but it still works.
Creator: The same creator's code has just worked with {Result of the ConcreteProduct1}

App: Launched with the ConcreteCreator2.
Client: I'm not aware of the creator's class, but it still works.
Creator: The same creator's code has just worked with {Result of the ConcreteProduct2}

다른 언어로 작성된 팩토리 메서드

C#으로 작성된 팩토리 메서드 C++로 작성된 팩토리 메서드 Go로 작성된 팩토리 메서드 자바로 작성된 팩토리 메서드 PHP로 작성된 팩토리 메서드 파이썬으로 작성된 팩토리 메서드 러스트로 작성된 팩토리 메서드 스위프트로 작성된 팩토리 메서드 타입스크립트로 작성된 팩토리 메서드