설명
클래스의 원형을 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 패턴과 시너지
댓글 없음:
댓글 쓰기