설명
생성용 인터페이스 Builder 가 있고, 원하는 단계의 종류별로 Concrete Builder 를 만들어서
객체의 생성 과정과 표현방법이 분리되어 있음.
생성 단계별로 있다는게 중요함.
Abstract Factory 는 유사한 클래스 간의 생성, 수정 등의 인터페이스를 갖게하는 거고,
Builder 는 복잡한 객체의 단계별 생성에 중점을 두는 것이 차이.
예제 코드
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | class MazeBuilder { public: // 굳이 추상클래스일 필요는 없음 virtual void BuildMaze() = 0; virtual void BuildRoom(int n) = 0; virtual void BuildDoor(int from, int to) = 0; virtual class Maze* GetMaze() = 0; protected: MazeBuilder() = default; private: class Maze* _maze_cur; }; | 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 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | class StandardMazeBuilder : public MazeBuilder { public: StandardMazeBuilder() : _currentMaze(nullptr) {} virtual void BuildMaze() { if (_currentMaze) delete _currentMaze; _currentMaze = new Maze(); } virtual void BuildRoom(int n) { Room* r = new Room(n); r->SetSide(North, new Wall()); r->SetSide(South, new Wall()); r->SetSide(East, new Wall()); r->SetSide(West, new Wall()); _currentMaze->AddRoom(new Room(n)); } virtual void BuildDoor(int from, int to) { Room* r1 = _currentMaze->RoomNo(from); Room* r2 = _currentMaze->RoomNo(to); Door* d = new Door(r1, r2); r1->SetSide(CommonWall(r1, r2), d); r2->SetSide(CommonWall(r2, r1), d); } virtual Maze* GetMaze() { return _currentMaze; } private: Direction CommonWall(Room* r1, Room* r2) { return South; } // 바둑판식 방이라면 두개의 방이 인접한 경우 r1 에서의 r2 의 방향을 리턴한다. Maze* _currentMaze; }; | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | class CountingMazeBuilder : public MazeBuilder { public: CountingMazeBuilder() : _rooms(0), _doors(0) {} virtual void BuildMaze(); virtual void BuildRoom(int) { _rooms++; } virtual void BuildDoor(int, int) { _doors++; } virtual void AddWall(int, Direction); void GetCounts(int& r, int& d) const { r = _rooms; d = _doors; } private: int _doors; int _rooms; }; | cs |
1 2 3 4 5 6 7 8 9 10 11 | Maze* MazeGame::CreateMaze() { m_builder->BuildMaze(); m_builder->BuildRoom(1); m_builder->BuildRoom(2); m_builder->BuildDoor(1, 2); m_mazes.push_back(m_builder->GetMaze()); return m_builder->GetMaze(); } | cs |
Maze 가 Wall, Room, Door 로 구성되어 있다고 하면,
Maze 를 만들고 안에 Wall, Room, Door 를 추가하기 위해
Builder 를 통해서만 가능하게 구현하는 것.
단계별 생성 절차를 CreateMaze() 처럼 Director 가 지시하게 됨.
이게 CountingMazeBuilder 를 쓰더라도 생성 절차 인터페이스는 통일적임.
Builder 가 생성 관련 제약을 해결해주기 때문에
Maze, Wall, Room, Door 의 객체들이 더욱 간단해짐.
추가 설명
Abstract Factory 는 상속 등을 통한 유사한 클래스 간의 생성, 수정의 인터페이스 통일이 목적이고, Builder 는 다양한 종류의 단계별 생성 간의 인터페이스 통일이 목적인 것이라 초점이 다른 거임.
댓글 없음:
댓글 쓰기