2020년 7월 7일 화요일

GOF Design Pattern - Prototype








설명


 클래스의 원형을 Factory 에 넣어서, 이 원형들을 복사해서 객체를 생성하는 방법.

 런타임에 사용될 객체의 타입이 결정되고, 이러한 독립성은 유지보수에 도움이 됨.

 생성할 클래스와 병렬적으로 만들 필요가 없으며, 새로운 클래스를 프로토타입의 조합으로 생성하여 서브클래스의 수도 줄일 수 있음.

 또한 프로토타입의 복사를 사용하므로 전체적인 메모리가 적게 들어감.


 또한 Prototype Manager 를 만들어서 생성관리를 하는것도 좋음.



예제 코드


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class MazePrototypeFactory : public MazeFactoryMethod
{
public:
    MazePrototypeFactory()
        : _prototypeMaze(nullptr), _prototypeWall(nullptr), _prototypeRoom(nullptr), _prototypeDoor(nullptr)
    {}
 
    void Initialize(Maze* m, Wall* w, Room* r, Door* d)
    {
        _prototypeMaze = m; _prototypeWall = w; _prototypeRoom = r; _prototypeDoor = d;
    }
 
    virtual Maze* MakeMaze() const { return new Maze(*_prototypeMaze); }
    virtual Room* MakeRoom(int n) const { return new Room(*_prototypeRoom); }
    virtual Wall* MakeWall() const { return new Wall(*_prototypeWall); }
    virtual Door* MakeDoor(Room* r1, Room* r2) const 
    {
        auto d = new Door(*_prototypeDoor); 
        d->Initialize(r1, r2);
        return d;
    }
 
private:
    Maze* _prototypeMaze;
    Room* _prototypeRoom;
    Wall* _prototypeWall;
    Door* _prototypeDoor;
};
cs

1
2
3
4
5
6
7
8
9
10
Maze* MazeGame::CreateMaze()
{
    Room* r1 = new Room(1);
    Room* r2 = new Room(2);
 
    m_prototype_factory->Initialize(new Maze(), new BombedWall(), new RoomWithBomb(1), new DoorNeedingSpell(r1, r2));
    m_prototype_factory->CreateMaze();
 
    return m_builder->GetMaze();
}
cs

MazePrototypeFactory 는 원형을 위처럼 저장해놔야함.

그리고 이를 복사해서 사용하므로 복사생성자나 Clone 같은 복사해주는 함수를 구현해야함.

그리고 값을 수정할 Initialize 함수도 구현해서 유연한 관리도 하는게 좋음.


CreateMaze 는 MakeDoor, MakeWall 등을 사용해 복사된 값으로 객체를 만듬. 


여기선 Prototype Manager 가 없지만 있는게 좋음.



추가 설명

 Abstract Factory 가 생성할 클래스마다 병렬적으로 생성한다면,

 Prototype 은 생성할 클래스와 독립적으로 사용될 수 있음.

 하지만 둘 다 같이 쓸 수도 있음.


 Composite 패턴이나 Decorate 패턴과 시너지

댓글 없음:

댓글 쓰기

List