Factory Method Pattern

JInwoo·2024년 2월 13일
0

그냥 스터디

목록 보기
2/2

Definition

"Define an interface for creating an object, but let subclasses decide which class to instantiate. The Factory method lets a class defer instantiation it uses to subclasses." (Gang Of Four)

Object의 생성은 code duplication, 접근할 수 없는 composing object에 대한 information 요구, 불충분한 abstraction level 등의 문제를 불러올 수 있다. factory method design pattern은 object creating method를 별도로 분리하여 위에서 언급한 문제를 해결환다. 분리된 factory method는 subclass에서 원하는 타입의 생성될 product를 명시하도록 override 될 수 있다. factory method의 return을 product라고 부르기도 한다.

즉 factory method design pattern은 다음의 문제를 해결한다.

  • object를 어떻게 생성할 것인지, 그리고 subclass에서 어느 class를 instatiate 할 것인지
  • subclass에서 instantiation을 어떻게 다르게 할 것인지

그리고 위의 문제를 다음과 같이 해결한다.

  • object 생성을 위한 별도의 operation을 정의(factory method)
  • factory method를 호출하여 object를 생성

Example

Structure

Room은 final product의 base class이다(MagicRomm or OrdinaryRoom). MazeGame은 abstract factory method를 선언한다. MagicRoom과 OrdinaryRoom은 base product의 subclass이다. MagicMazeGame과 OrdinaryMazeGame은 factory method를 implement한 MazeGame의 subclass이다. factory method는 caller(MazeGame)을 concrete class의 implementation과 분리해준다. 이것은 "new" operator를 redundant하게 해주고 Open/close principle을 따르도록 하고, envent change에 대해 final product 생성을 더 유연하게 해준다.

Python Implementation

from abc import ABC, abstractmethod


class MazeGame(ABC):
    def __init__(self) -> None:
        self.rooms = []
        self._prepare_rooms()

    def _prepare_rooms(self) -> None:
        room1 = self.make_room()
        room2 = self.make_room()

        room1.connect(room2)
        self.rooms.append(room1)
        self.rooms.append(room2)

    def play(self) -> None:
        print(f"Playing using {self.rooms[0]}")

    @abstractmethod
    def make_room(self):
        raise NotImplementedError("You should implement this!")


class MagicMazeGame(MazeGame):
    def make_room(self) -> "MagicRoom":
        return MagicRoom()


class OrdinaryMazeGame(MazeGame):
    def make_room(self) -> "OrdinaryRoom":
        return OrdinaryRoom()


class Room(ABC):
    def __init__(self) -> None:
        self.connected_rooms = []

    def connect(self, room: "Room") -> None:
        self.connected_rooms.append(room)


class MagicRoom(Room):
    def __str__(self) -> str:
        return "Magic room"


class OrdinaryRoom(Room):
    def __str__(self) -> str:
        return "Ordinary room"


ordinaryGame = OrdinaryMazeGame()
ordinaryGame.play()

magicGame = MagicMazeGame()
magicGame.play()

Reference

profile
Jr. AI Engineer / Researcher

0개의 댓글