Search

'IT/Design Pattern'에 해당되는 글 2건

  1. 2009/06/18 Abstract Factory Pattern
  2. 2009/06/12 Factory Method Pattern

Abstract Factory Pattern

IT/Design Pattern 2009/06/18 23:47 Posted by Gony Taegony

문제
어떻게 하면 같은 제품군에 속한 제품들의 객체만을 생성해서 사용하도록 명확히 보장받을 수 있는가?
예를들어 타입A 제품의 종류는 A1, A2가 있으며 타입B 제품의 종류는 B1, B2 가 있다.
제품 생산시 1번 제품군은 A1, B1이며 2번 제품군은 A2, B2이다.
조건에 따라 제품군으로 분류된 제품만을 생성해야 한다.

방법1
- 제품군을 생성할 때마다 조건 비교를 한다.
- 이 방법은 조건문이 곳곳에 들어가게 된다.
  추후 제품이 추가되는 경우 조건문이 들어간 부분을 모두 찾아서 수정해야한다.
  아래 코드와 같이 생성함수에서 추가된 제품의 종류를 비교해야 한다.
- 샘플
[code cpp]
class productA {};
class productB {};
class productA1 : public productA {};
class productA2 : public productA {};
class productB1 : public productB {};
class productB2 : public productB {};

void CreateProductA ()
{
  ...
  if (iType == 1) {
    productA1 pa1;
  }
  else {
    productA2 pa2;
  }
  ...
}

void CreateProductB ()
{
  ...
  if (iType == 1) {
    productB1 pb1;
  }
  else {
    productB2 pb2;
  }
  ...
}

int main ()
{
  ...
  CreateProductA ();
  CreateProductB ();
  ...
}
[/code]

방법2
- Factory Method 패턴에서 사용했던 팩토리 메소드를 가진 클래스를 제품군별로 생성한다.
- 이점
  1. 개별 제품 클래스의 객체를 생성할 때마다 일일이 조건을 검색할 필요가 없어진다.
  2. 새로운 제품군의 생성시 기존 소스코드는 건드릴 필요가 없다.
  3. 팩토리 클래스가 별도로 존재하기 때문에 클라이언트는 추상클래스의 인터페이스만 바라보면 된다.
  4. 반드시 선택된 제품군에 포함된 제품들만 생성해야하는 경우 유용하다.
- 단점
  1. 제품군이 늘어나면 어쩔 수 없이 팩토리 클래스의 수도 늘어나게 된다.
  2. 기존 제품군에 새로운 제품이 추가되면 모든 팩토리 클래스에 새로운 제품을 추가해야한다.
- 샘플
[code cpp]
class AbstractProductA {};
class AbstractProductB {};
class ProductA1 : public AbstractProductA {};
class ProductA2 : public AbstractProductA {};
class ProductB1 : public AbstractProductB {};
class ProductB2 : public AbstractProductB {};

class AbstractFactory
{
  public:
    virtual productA* CreateProductA () = 0;
    virtual productB* CreateProductB () = 0;
};

class Type1_Factory : public AbstractFactory
{
  public:
    AbstractProductA * CreateProductA () {return new ProductA1;}
    AbstractProductB * CreateProductB () {return new ProductB1;}
};

class Type2_Factory : public AbstractFactory
{
  public:
    AbstractProductA * CreateProductA () {return new ProductA2;}
    AbstractProductB * CreateProductB () {return new ProductB2;}
};

int main ()
{
  ...
  AbstractFactory *pFactory = null;

  if (iType == 1) {
    pFactory = new Type1_Factory ();
  }
  else {
    pFactory = new Type2_Factory ();
  }
 
  AbstractProductA *pProductA = pFactory->CreateProductA ();
  AbstractProductB *pProductB = pFactory->CreateProductB ();
  ...
}
[/code]

사용자 삽입 이미지

사용자 삽입 이미지


Factory Method Pattern

IT/Design Pattern 2009/06/12 00:20 Posted by Gony Taegony

객체를 생성하기 위해 인터페이스를 정의하지만, 어떤 클래스의 인스턴스를 생성할지에 대한 결정은 서브클래스에서 책임지도록 한다.

사용자 삽입 이미지
사용자 삽입 이미지

유용한 경우
- 구체적으로 어떤 클래스의 객체를 생성해야 할지 미리 알지못하는 경우
- 객체의 종류별로 객체 생성과 관련된 부분을 국지화 시키는 경우

장점
- 어떤 객체를 생성할 것인지와는 무관하게 동일한 형태로 프로그래밍이 가능하다.
  ; 당연하다. 클래스 상속을 통한 다형성을 구현하므로 ...
- 클라이언트가 직접 객체를 생성하는 것보다 유연한 확장성 구조를 가지게 된다.
  ; 새로운 객체를 생성하거나 이전 객체를 확장해서 생성하고자 할 때
    새로운 하위 클래스를 정의하고 Factory Method에 해당하는 멤버 함수만
    Override 시키면 된다.
 
; 다시 말하자면 객체 생성과 관련된 변경을 국지화 시킬 수 있다.
- 서로 연관된 클래스들의 상속관계가 병렬로 존재하는 경우 한 쪽 상속 관계의
  클래스들이 다른 쪽 상속 관계의 클래스 객체를 생성할 때 유용하다.
- 상속관계에 있는 클래스들의 멤버 함수가 동일한 프로그램 로직을 가지고 있으면서
  내부적으로 생성할 객체만 서로 다를 때 편리하다.
  ; 로직은 상위클래스에서 구현하고 생성과 관련된 부분만 하위 클래스에서 구현한다.

단점
- 객체의 종류가 달라질 때마다 새로운 하위 클래스를 정의해야한다.
  ; 따라서 불필요하게 많은 클래스들을 내포할 가능성이 있다.

[뱀발바닥]
패턴의 유용성을 알리기 위해 좀 어거지라고 생각되는 예를 (지극히 내생각이다.) 들었다는 느낌이 많이 들었다. GoF 패턴에 대한 해설서이므로 저자가 의도적으로 설명하기 위해서 그렇게 한 것 같긴 하지만 나에겐 좀 아쉬운 부분이다. 하지만 아직 이쪽부분에 대해 용어나 표현에 대해 미숙하기 때문에 그렇게 생각하는지도 모르겠다. 어쨌든 패턴이라고 하는 영역이 소프트웨어를 설계할 때 많은 도움이 되리라고 확신하지만 너무 이쪽 이론에 빠지게 되면 자칫 말장난에 빠질 수도 있겠다는 생각이 든다. 패턴은 객체지향언어를 제대로 쓰기 위해 필요한 기본적인 테크닉일 뿐이라고 생각한다. 나머지는 자신의 영역에 맞게 적용하는게 문제라고 본다. 뭐 그게 어렵겠지만 ㅋㅋㅋ