2020년 7월 6일 월요일

GOF Design Pattern - Abstract Factory





설명


 생성용 인터페이스 Factory 와, 객체용 인터페이스 Factory. 

 인터페이스를 공유하는 객체들이 모두 Factory 인터페이스로 생성되므로

 객체를 생성하거나 수정하는데 일관성을 유지할 수 있음.

 
 문제는 일부만 바꿔도 서브클래스들을 통채로 다 바꿔야하는 경우가 생김.



예제 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class MazeFactory {
public:
    MazeFactory() = default;
 
    virtual Maze* MakeMaze() const { return new Maze; }
    virtual Wall* MakeWall() const { return new Wall; }
    virtual Room* MakeRoom(int n) const { return new Room(n); }
    virtual Door* MakeDoor(Room* r1, Room* r2) const { return new Door(r1, r2); }
};
 
class EnchantedMazeFactory : public MazeFactory
{
public:
    EnchantedMazeFactory() = default;
 
    virtual Room* MakeRoom(int n) const { return new EnchantedRoom(n, CastSpell()); }
    virtual Door* MakeDoor(Room* r1, Room* r2) const { return new DoorNeedingSpell(r1, r2); }
 
protected:
    Spell* CastSpell() const { return new Spell("spell"); };
};
cs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Maze* MazeGame::CreateMaze()
{
    Maze* maze = m_factory->MakeMaze();
    Room* r1 = m_factory->MakeRoom(1);
    Room* r2 = m_factory->MakeRoom(2);
    Door* theDoor = m_factory->MakeDoor(r1, r2);
 
    maze->AddRoom(r2);
    maze->AddRoom(r1);
 
    r1->SetSide(North, m_factory->MakeWall());
    r1->SetSide(East, theDoor);
    r1->SetSide(South, m_factory->MakeWall());
    r1->SetSide(West, m_factory->MakeWall());
 
    r2->SetSide(North, m_factory->MakeWall());
    r2->SetSide(East, m_factory->MakeWall());
    r2->SetSide(South, m_factory->MakeWall());
    r2->SetSide(West, theDoor);
 
    m_mazes.push_back(maze);
 
    return maze;
}
cs

Maze 가 Wall, Room, Door 로 구성되어 있다고 하면,
Maze 를 만들고 안에 Wall, Room, Door 를 추가하기 위해
MazeFactory 를 통해서만 가능하게 구현하는 것.

약간 다른 버전인 Maze 를 상속받은 EnchantedMaze 를 만들기 위해
MazeFactory 를 상속받은 EnchantedMazeFactory 를 호출해야함.

인터페이스는 Maze 와 상속 시리즈들이 서로 같듯이
MazeFactory 도 ConcreteFactory 에 해당되는 시리즈들이 같은 인터페이스를 가짐.

그래서 객체 사이의 일관성을 높혀줌.



추가 설명

Factory 자체는 대개 Factory Method 로 구현되고

Prototype 과는 경쟁적이지만 같이 사용되기도 함.

또한 Factory 는 하나만 있으면 되서 Singleton 으로도 구현되기도 함. 


댓글 없음:

댓글 쓰기

List