본문 바로가기

기타/Design pattern

Builder pattern


1. Background

● 실제적인 객체의 생성은 한번에 생성되지 않는다.

● 객체를 구성하는 데이터 멤버들을 일일이 생성

● 생성자의 호출로 인해서 객체를 생성

 

2. Issue

● 효과적인 객체 생성을 위해 부분 부분을 따로 생성하여 이를 조합해서 객체를 생성할 수 있는가?

 

3. Why

● 여러 부분에 걸쳐서 값이 입력되는 객체의 경우

● 입력된 정보만을 저장할 많은 공간 필요

● 최종 입력 후 객체 생성에도 시간이 많이 걸릴 수 있다.

● 내부구조의 변경 시 기존 소스 코드에 많은 영향을 준다.

 

4. Good point

● 객체의 생성 부분과 실제 표현하고 구성하는 부분을 분리시켜 서로간의 독립성 보장

● 독립성의 보장으로 독립적인 수정 및 재사용이 가능

● 서로 다른 표현방식을 가지는 객체를 동일한 방식으로 생성할 수 있다.

 

4. Example

● 프린터 스풀러 - 각각의 인스턴스 발생 시 시스템의 엄청난 리소스와 CPU의 낭비

● 데이터 베이스 엔진 - 하나의 데이터 베이스로 여러 사용자에게 같은 정보 공유, 효과적인 관리

● 사용자 인증 시스템 - 하나의 로컬 pc에서 하나의 user ID와 password를 얻어와 핸들링

● DirectX의 컴포넌트 - DirectDraw, Direct3D, DirectSound등은 하나만 존재

LPDIRECTDRAW7 g_pDDraw 로 전역변수화

 

※프린터 스풀러 - 인쇄 출력 속도와 컴퓨터 시스템의 처리 속도 차이를 위해 존재하는 임시저장공간 관리자

 

5. Solution

4-1. 전역변수에 의한 객체 생성, 관리

○ 전역변수에 의해서 main함수에서 여러 번 CreateCock()함수를 호출해도 하나의 객체만 유지

 

class Cock{

public :

Cock(){}

~Cock(){}

};

 

Cock *pCock = 0;// 전역변수로 선언

 

Cock *CreateCock()

{

if(pCock == 0){

pCock = new Cock;

return pCock;

}

return 0;

}

 

void main()

{

Cock *pCock1 = CreateCock();

Cock *pCock2 = CreateCock();

Cock *pCock3 = CreateCock();

}

 

 

○ 문제점

◆ 직접 생성자를 이용해서 생성하면 여러개의 객체 생성 가능

◆ 전역 변수 방식의 경우에는 해당 객체가 사용되든 안되든 무조건 객체 생성

◆ 전역 변수에 해당하는 객체들의 생성 순서를 지정해야 할 경우 문제 발생

◆ 처음부터 객체를 초기화 하고 객체에 대한 정보를 알아야한다.

 

void main()

{

Cock* pCock1 = CreateCock();

Cock* pCock2 = new Cock;

}

 

 

4-2. Singleton패턴

○ 생성자가 private로 되어 있으므로 main에서 Cock* pCock3 = new Cock로 생성할 수 없다.

○ CreateCock()에 의해서만 객체가 생성 되는데 static으로 선언되어 있으므로 하나의 객체만 생성

 

class Cock{

public :

static Cock* CreateCock(){

if(pCock == 0){

pCock = new Cock;

}

return pCock;

}

private:

Cock(){}

~Cock(){}

static Cock* pCock; // 정적 멤버 변수

};

 

void main()

{

Cock* pCock1 = Cock::CreateCock();

Cock* pCock2 = Cock::CreateCock();

}

 

 

5. A point to be considered (고려사항)

5-1. 복제 생성자를 명시적으로 정의 하지 않으면 C++컴파일러에서 public영역에 복제 생성자가 제공되어 객체가 생성. 반드시 복제 생성자도 protected, private영역에 정의

 

Cock* pCock1 = Cock::CreateCock();

Cock aCock(*pCock1); //복제 생성자 호출

 

5-2. 하위 클래스 존재 시에 Cock의 생성자에 의해서 객체 생성외에 상속 받은 하위클래스의 생성자는 자유롭게 이루어 지므로 정확하게 Cock자료형에 속하는 객체의 수를 전체적으로 제한하지 못한다.

 

5-3. CreateCock의 리턴형이 포인터가 되야만 하위 클래스에서 생성된 객체가 제대로 관리 되고 임의로 객체를 삭제하면 클래스에서 객체를 관리하는데 객체는 삭제되면 상위 클래스에서 그 포인터 값을 가지고 있는 객체는 여전히 남아 있으므로 Dangling Pointer문제가 발생한다.

 

6. Reference

http://cafe.naver.com/jzsdn.cafe?iframe_url=/ArticleRead.nhn%3Farticleid=4886

 

'기타 > Design pattern' 카테고리의 다른 글

Singleton pattern  (0) 2009.04.27
Decorator pattern  (0) 2009.04.27
Adapter pattern  (0) 2009.04.27
Abstract Factory pattern  (0) 2009.04.27
소프트웨어 개발 기본 요소  (0) 2009.04.27