상세 컨텐츠

본문 제목

팩토리 패턴

프로그래밍 관련/패턴

by AlrepondTech 2010. 4. 28. 10:08

본문

반응형

 

 

 

=================================

=================================

=================================

 

 

 

 

 

 

1. 간단한 팩토리(Simple Factory)- 객체 생성을 처리하는 클래스를 팩토리라고 부른다. 객체를 생성하는 작업을 한 클래스에 캡슐화시켜 놓으면 구현을 변경해야 하는 경우에 여기저기 다 들어가서 고칠 필요 없이 이 팩토리 클래스 하나만 고치면 된다. 2.정적 팩토리(static Factory)- 정적 팩토리란 간단한 팩토리를 정적 메소드로 정의 하는 기법이다. 정적 메소드를  쓰면 객체를 생성하기 위한 메소드를 실행 시키기 위해서 객체의 인스턴스를 만들지 않아도 된다. 하지만 서브클래스를 만들어서 객체 생성 메소돌의 행동을 변경 시킬 수 없다는 단점이 있다.3.Factory Method Pattern의 정의

- 객체를 생성하기 위한 인터페이스를 만든다. 어떤 클래스의 인스턴스를 만들지는 서브클래스에서 결정하게 만든다. 팩토리 메소드 패턴을 이용하면 클래스의 인스턴스를 만드는 일을 서브 클래스에게 맡기는 것이다. 즉, 사용되는 서브클래스에 따라 생산되는 객체 인스턴스가 결정된다.

4.Factory Method Pattern 의 특징

- 팩토리 메소드는 객체 생성을 처리하며, 객체를 생성하는 코드를 캡슐화 한다. 서브 클래스에서 어떤 클래스를 만들지 결정하게 함으로써 객체 생성을 캡슐화 한다. 이렇게 하면 슈퍼 클래스에 있는 클라이언트 코드와 서브클래스에 객체 생성 코드를 분리 시킬 수 있다. 어떤 구상 클래스를 필요하게 될지 미리 알 수 없는 경우에도 매우 유용하다. 서브클래스를 만들고 팩토리 메소드를 구현하면 된다.

5. Factory Method Pattern의 구성

A.  Creator에는 제품을 가지고 원하는 일을 하기 위한 모든 메소드들이 구현되어 있다. 하지만 제품을 만들어 주는 팩토리 메소드는 추상 메소드로 정의도어 있을뿐 구현되어 있진 않다.

B. 제품 클래스에서는 모두 똑 같은 인터페이스를 구현해야 한다. 그래야 그 제품을 사용할 클래스에서 구상 클래스가 아닌 인터페이스에 대한 레퍼런스르 써서 객체를 참조할 수 있다.

C. Concretecreator에서는 실제로 제품을 생산하는 faroryMethod 를 구현한다

D. 구상클래스 인스턴스를 만들어 내는 일은 ConcreateCreator가 책임진다 여기에서 실제 제품을 만들어내는 방법을 알고 있는 클래스는 이 클래스뿐이다.

6.Factotry Pattern의 장단점

객체 생성 코드를 전부 한 객체 또는 메소드에 집어 넣으면 코드에 중복되는 내용을 제거할 수 있고, 나중에 관리할 때도 한군데에만 신경을 쓰면 된다. 그리고 클라이언트 입장에서는 객체 인스턴스를 만들 때 필요한 구상 클래스가 아닌 인터페이스만 필요로 하게 된다. 이 패턴을 도입하면 구현이 아닌 인터페이스를 바탕으로 프로그래밍을 할 수 있게 되고, 그 결과 유연성과 확장성이 뛰어난 코드를 만들 수 있게 된다.

[출처] 팩토리 패턴(Factoty Pattern)|작성자 랄로



 

 

=================================

=================================

=================================

 

 

 

팩토리 패턴에 대해 알아보자. 팩토리 패턴의 기본 개념은 객체 생성은 객체 생성 전문가에게 맡기자는 것이다.

풀어 설명하면 팩토리 패턴은 서로 관련성이 있거나 책임이 같은 클래스들을 생성해주는 클래스를

객체 생성 과정에 중간을 두어 복잡도를 줄이는 방법이라고 할수있다.  한마디로 객체 생성 전담자라고 생각하면 된다.

 

간단한 팩토리는 엄밀히 말해서 디자인 패턴이라고 할수 없지만, 클라이언트와 구상 클래스를 분리 시키기위한 간단한 기법으로

사용될수 있다. (여기서 패턴의 기본원칙중 하나인 조금만 알기 원칙이 포함되어 있음을 알수있다)

 

 

                                          입력 ====> 팩토리(Factory) ====> 출력

 

위 그림과 같이 팩토리가 모든 객체 생성을 대신하게 된다.

어떤 객체 타입을 선택하였는지 파라미터로 팩토리 클래스에 넘겨주면 팩토리 클래스는 파라미터에 맞게 적당한 클래스를 new로

생성하며 넘겨준다. 이 경우 모든 리턴되는 객체 타입은 팩토리가 알고 있는 모든 클래스의 부모 클래스로 사용한다.

 

 

예제 코드를 보자.

 

                                      class CStampFactory

                                     {

                                      public:

입력(ESTAMPTYPE)==>              static CGeneralStamp* Create(CESTAMPTYPE_Type);  ===> 출력(CGeneralStamp*)

                                     }

                                     CGeneralStamp* CStampFactory::Create(CESTAMPTYPE_Type)

                                     {

                                            switch(ESTAMPTYPE_Type)

                                            {

                                            case ESTAMPTYPE_TRIANGEL: return new CTriangleStamp; 

                                            case ESTAMPTYPE_SQUARE: return new CSquareStamp;

                                            case ESTAMPTYPE_CIRCLE: return new CCircleStamp;

                                            }

                                            return NULL;

                                      }

 

 

실제로 클라이언트 코드 부분에서는

 

       CESTAMPTYPE  eType = ESTAMPTYPE_TRIANGEL;

       CGeneralStamp *pStamp = CStampFactory::Create(eType);

 

      ...............................

 

      if(NULL != pStamp)

     {

           delete pStamp;

           pStamp = NULL;

     }

로 사용 하면 된다.

주의 할점은 new/delete 원칙이 위배 되는것처럼 보이지만(실제로 new는 팩토리 안에서 이루어지고, delete는 팩토리를 호출한

부분에서 이루어진다) 팩토리 클래스 자체가 논리 적인 관점에 new 키워드를 대신하는 개념으로 이해하면 된다.

 

팩토리 패턴을 쓰게되는 이유에 대해 알아보자.

 

1) 팩토리를 쓰면 객체 생성을 캡슐화 할수 있다.

2) 간단한 팩토리는 엄밀하게 말해서 디자인 패턴은 아니지만 클라이언트와 구상클래스를 분리 시키기 위한 간단한 기법으로 활용 될수

    있다.

3) 어떤 클래스에서 인스턴스를 만드는 일을 팩토리 클래스에 넘김으로써 느슨한 결합이 가능하다.

출처 : http://blog.naver.com/kkan22?Redirect=Log&logNo=80056238198



 

 

=================================

=================================

=================================

 

 

 

Factory란 공장입니다.

그런데 어떤 제품을 만다는 공장입니다.

그 제품이란 바론 객체입니다.

 

스타크래프트로 비유해보자면,

팩토리는 배럭입니다. 배럭을 통해서,

마린도 파이어뱃도, 매딕도 만들어집니다.

 

마린, 파벳, 매딕은 인스턴스입니다.

그들은 팩토리를 통해서, 생성되어서 공격활동도 하고 방어도 하나가 적에게 죽어서 객체의 생명을 다해서 소멸되는거죠.

 

왜 이런 패턴을 고민했을까요?

저도 배우는 입장이기에, 잘 모르겠습니다.^^;

단지 추정을 해볼 뿐입니다.

 

여기서 기억할 것은

제품으로써의 객체와, 그 제품을 만다는 팩토리라는 객체입니다.

 

그럼 추상팩토리란 무엇일까요?

그것은 바로 인터페이스로의 팩토리입니다.

스타크래프트에선 종족이 있습니다. 그 종족을 선택하면서 그 종족에 따른 유닛이 나오죠.

 

그럼 이렇게 생각해 볼 수 있죠.

종족 팩토리  유닛
테란 배럭 마린
프로토스 게이트웨 이 질럿
저그 해처리 저글링

 

이렇게 본다면, 종족에 따라서 어떤 객체군(집합)이 형성된다는것을 알 수 있죠.

예를 들어 배럭 -마린 이라는 객체군이 형성된는 것을 알 수 있죠.

 

그런던, 종족에 따라서 팩토리를 3개씩 만들었다면, 코딩이 얼마나 복잡해질까요? 코딩이 복잡성을 떠나서 종족에 따라서 코딩을 할때, 그 팩토리 종류에 따라서 if else를 남발할 가능성이 매우 높습니다.

그럴바에는!!!

 

팩토리에 대한 사용법을 통일해 놓고, 종족선택마다 종족에 맞는 팩토리를 생성시켜 사용하는게 옳지 않을까요?

 

// 테란 선택시

IF_Factory* if_factory =new Barrck;

IF_Unit* if_unit = if_facotry.MakeUnit();  // 마린 만들어짐

 

unit .attack();

unit .defend();

 

// 저그 선택시

IF_Factory* if_factory =new Hattery;

IF_Unit* if_unit = if_facotry.MakeUnit();  // 저글링 만들어짐

 

unit .attack();

unit .defend();

 

즉 추상팩토리란....

스타크래프트에서 버전과 종족에처럼 특정 객체군을 형성할 때,

그 객체군을 만드는 팩토리에 대한 사용법을

종족에 상관없이 통일시켜놓은 하나의 인터페이스라고 볼 수 있죠.



 

=================================

=================================

=================================

 

 

팩토리 패턴은 서로 관련성이 있거나 책임이 같은 클래스들을 생성해 주는 클래스를 객체 생성 과정 중간에 두어 복잡도를 줄이는 방법이다.

한마디로, 객체 생성 전담자라는 의미로 생각하면 된다.

#include "stdafx.h"
 
class CCharacter
{
        //각종멤버
};
 
class CUser : public CCharacter
{
        //각종멤버
};
 
 
 
class CNpc : public CCharacter
{
        //각종멤버
};
 
class CMonster : public CCharacter
{
        //각종멤버
};
 
 
class CCharacterFactory
{
public:
        static CCharacter * CreateUser()
        {
               return new CUser;
        }
 
        static CCharacter * CreateNpc()
        {
               return new CNpc;
        }
 
        static CCharacter * CreateMonster()
        {
               return new CMonster;
        }
};
 
int _tmain(int argc, _TCHAR* argv[])
{
        CCharacter * pcCharacter = CCharacterFactory::CreateUser();
        //다형성을 통한 pcCharacter 제어/ 관리 가능.
        return 0;

출처:

http://elky.tistory.com/106

팩터리 추가 관련 (팩토리 잘구현한 클래스)

http://iamgsi.com/348

 

 

 

=================================

=================================

=================================

 

 

 

 

반응형

'프로그래밍 관련 > 패턴' 카테고리의 다른 글

이터레이터 패턴 (Iterator Pattern)  (0) 2010.03.26
상태 패턴  (0) 2010.03.26


관련글 더보기

댓글 영역