최상단 광고

2012년 4월 17일 화요일

[Chapter2] 생성 패턴 -시작하기

1. 생성 패턴(Creational pattern)이란?
 인스턴스를 만드는 절차를 추상화하는 패턴입니다. 이 범주에 해당하는 패턴은 객체를 생성&합성하는 방법이나 객체의 표현 방법과 시스템을 분리해 줍니다. 클래스 생성 패턴이 인스턴스로 만들 클래스를 다양하게 만들기 위한 용도로 상속을 사용하는 반면, 객체 생성 패턴은 인스턴스화 작업을 다른 객체에게 떠넘길 수 도 있습니다.
 생성 패턴은 시스템이 어떤 구체 클래스를 사용하지에 대한 정보를 캡슐화합니다. 그리고 생성 패턴은 이들 클래스의 인스턴스들이 어떻게 만들고 어떻게 서로 맞붙는지에 대한 부분을 완전히 가려줍니나. 결론적으로, 생성 패턴을 이용하면 무엇이 생성되고, 누가 이것을 생성하며, 이것이 어떻게 생성되는지, 언제 생성할 것인지 결정하는데 유연성을 확보할 수 있게 됩니다.

2. 예제로 보는 패턴들....
[[ 미로게임 ]]
§ 전제
- 단순히 미로에서 빠져나오는 게임일 때는 전체 미로 중 플레이어에게 보이는 만큼의 미로가 표시 됨.
- 풀어야 할 문제가 있을 수도 있고, 극복해야 할 위험이 숨겨진 미로게임일 때는 미로의 일부분에 해당하는 평면 지도가 제공되기도 함.
- 복잡한 미로게임을 다루지는 않음.
- 플레이어가 ( 1..* )임.
- 미로는 방들의 집합이고 각 방은 옆에 무엇이 있는지도 알 수 있음.
- 방 옆에 방
- 방 옆에 문
- 방 옆에 벽

§ 클래스도

( C++  구현시 )
- 각 방은 네 개의 뱡향을 갖는데,,,
MapSite 클래스는 미로의 구성요소들에 필요한 모든 연산을 정의한 공통 추상 클래스
 
Room 클래스는 MapSite를 상속받은 구체적인 클래스로 미로에 있는 다른 요소와 관련성을 갖도록 정의합니다. 
Door과 Wall 클래스
- 또한 방들의 집합을 표현하기 위해서 클래스 Maze를 정의

-  MazeGame이란 클래스가 필요합니다.
   실제로 미로를 생성하는 클래스로 일련의 연산을 통해 빈 미로에 미로의 구성요소를 추가하고 이들을 연결하는 것입니다.

위 CreateMaze()가 갖고 있는 문제는 유연성이 떨어진다는 것이다. 즉, Room 클래스의 생성자에 변경되는 아래 부분만 코드화하면 된다!
r1->SetSide(East, theDoor);
r2->SetSide(West, theDoor);
(흠... 위 소스코드는 타이핑 하는데.. 자연스럽게.. Ctrl+C / Ctrl+V 를 이용하고 있는 제 자신을 발견하고...놀랐다는;;)
생성패턴은 이런 상황에서 어떻게 유연한 설계를 할 수 있는지에 대한 해법을 제공합니다.


지금 시점에서 가장 큰 장애 요인은 클래스들의 인스턴스를 직접 생성하도록 하드코딩한다는 점입니다.
- CreateMaze가 방, 벽, 문을 생성하기 위해서 생성자를 이용하지 않고 가상 함수를 호출하도록 구현되어 있다면, 이 가상 함수의 실제구현을 다양한 방법으로 변경할 수 있을 것입니다. <<팩토리 메소드 패턴>>
- CreateMaze가 방, 벽, 문을 생성하기 위해 생성 방법을 알고 있는 객체를 매개변수로 넘겨받을 수 있다면, 생성 방법이 바뀔 때 마다 새로운 매개변수를 넘겨받음으로써 생성할 객체의 유형을 달리할 수 있습니다. <<추상 팩토리 메소드 패턴>>
- CreateMaze가 생성하고자 하는 미로에 방, 문, 벽을 추가하는 연산을 사용해서 새로운 미로를 만들 수 있는 객체를 넘겨받는다면 미로를 만드는 방법이나 변경을 이 객체의 상속을 통해서 해결할 수 있습니다. <<빌더 패턴>>
- CreateMaze를 이미 만든 다양한 방, 문, 벽 객체로 매개변수화하는 방법도 가능한데, 이미 만든 객체를 복사해서 미로에 추가하면, 이들 인스턴스를 교체하여 미로의 복합 방법을 변경할 수 있습니다. <원형 패턴>

cf) 단일체 패턴은 한 게임에 오로지 하나의 미로 객체만 존재할 수 있고 그 게임에서 돌아가는 모든 게임 객체들이 이 미로에 접근이 가능하도록 보장합니다. 전역 변수나 전역 함수에 의존할 필요 없이 이런 일이 가능합니다. 또한 단일체 패턴은 기존 코드를 건드리지 않고도 미로를 쉽게 대체하거나 확장할 수 있도록 해 줍니다.

댓글 없음: