Factory method pattern은 객체를 생성하기 위한 인터페이스를 정의하지만, 어떤 클래스의 인스턴스를 생성할지에 대한 결정은 subclass가 내리도록 한다. 이 패턴을 이용하면 클래스의 인스턴스를 만드는 일을 subclass에게 맡길 수 있다.


구조

UML 클래스 다이어그램


  • Product: Factory method가 생성하는 객체의 인터페이스를 정의한다.
  • ConcreteProduct: Product 클래스에 정의된 인터페이스를 실제로 구현한다.
  • Creator: Product 타입의 객체를 반환하는 Factory method를 선언한다. Creator 클래스는 Factory method를 기본적으로 구현하는데, 이 구현에서는 ConcreteProduct 객체를 반환한다. 또한 Product 객체의 생성을 위해 Factory method를 호출한다.
  • ConcreteCreator: Product를 실제로 생산하는 클래스. Factory method를 재정의하여 ConcreteProduct의 인스턴스를 반환한다.

장단점

  1. Facotry method로 클래스 내부에서 객체를 생성하는 것이 객체를 직접 생성하는 것보다 훨씬 응용성이 높아진다.
  2. OCP(Open-Closed Principle). 기존의 client 코드를 수정하지 않고 새로운 유형의 제품을 프로그램에 넣을 수 있다.

예시

아래와 같이 MazeGame 클래스 내에 Factory method를 정의한다. 여기서 MakeMaze(), MakeRoom(), MakeWall(), MakeDoor() method가 Factory method다.

class MazeGame
{
public:
	Maze* CreateMaze(MazeBuilder&);

	virtual Maze* MakeMaze() const
	{ return new Maze; }

	virtual Room* MakeRoom(int n) const
	{ return new Room(n); }

	virtual Wall* MakeWall() const
	{ return new Wall; }

	virtual Door* MakeDoor(Room * r1, Room * r2) const
	{ return new Door(r1, r2); }
};

Factory method를 통해 CreateMaze를 다시 써보면 아래와 같다.

Maze* MazeGame::CreateMaze(MazeBuilder& builder) {
	Maze* aMaze = MakeMaze();

	Room* r1 = MakeRoom(1);
	Room* r2 = MakeRoom(2);
	Door* theDoor = MakeDoor(r1, r2);

	aMaze->AddRoom(r1);
	aMaze->AddRoom(r2);

	r1->SetSide(North, MakeWall());
	r1->SetSide(East, theDoor);
	r1->SetSide(South, MakeWall());
	r1->SetSide(West, MakeWall());

	r2->SetSide(North, MakeWall());
	r2->SetSide(East, MakeWall());
	r2->SetSide(South, MakeWall());
	r2->SetSide(West, theDoor);

	return aMaze;
}

다른 미로 게임을 만든다면, MazeGame 클래스를 상속해서 미로의 부분을 재정의하면 된다. 예를 들어, BombedMazeGame 클래스는 Room과 Wall 객체를 다시 정의하여 폭탄을 맞은 것들을 반환하도록 만든다.

class BombedMazeGame : public MazeGame {
public:
	BombedMazeGame();

	virtual Wall* MakeWall() const
	{
		return new BombedWall;
	}

	virtual Room* MakeRoom(int n) const
	{
		return new RoomWithBomb(n);
	}
};


'프로그래밍 관련 > 객체 지향 설계' 카테고리의 다른 글

메모. Proxy pattern  (0) 2019.11.18
메모. Facade pattern  (0) 2019.11.17
메모. Builder pattern  (0) 2019.05.18
메모. Concrete class  (1) 2019.05.13
메모. Abstract factory pattern  (0) 2019.05.13