프로그래밍 관련/디자인 패턴

[생성 패턴] 추상 팩토리 패턴 - Abstract Factory

QA Engineer - P군 2016. 7. 28. 22:45
반응형

[생성 패턴] 추상 팩토리 패턴 - Abstract Factory

 

 

 

[ 이미지 출처 : http://www.c-jump.com ]

 

 

목적

 

상세화된 서브 클래스를 정의하지 않고도 서로 관련성이 있거나 독립적인 여러 객체의 군을 생성하기 위한 인터페이스를 제공하기 합니다.

 

활용

 

- 객체가 생성되거나 구성.표현되는 방식과 무관하게 시스템을 독립적으로 만들고자 할때

- 여러 제품군 중 하나를 선택해서 시스템을 설정해야 하고 한번 구성한 제품을 다른 것으로 대체할 수 있을 때

- 관련된 제품 객체들이 함께 사용되도록 설계되었고, 이 부분에 대한 제약이 외부에서도 지켜지도록 하고 싶을 때

- 제품에 대한 클래스 라이브러리를 제공하고 , 구현이 아닌 인터페이스를 노출하고 싶을때.

 

장점

 

1. 구체적인 클래스 분리

2. 재사용성 증가

3. 객체간의 일관성 증가

 

단점
1. 새로운 종류를 추가하기 어렵다.
: 새로운 종류가 추가 된다면, 팩토리 구현을 변경해야합니다. 

 

구현

1. 팩토리를 단일체로 정의

2. 제품 생성

3. 확장 가능한 팩토리들을 정의


class HouseFactory
{
 
public :
 
    virtual House* MakeHouse() const
    {
        return new House;
    }
 
    virtual Room* MakeRoom() const
    {
        return new Room;
    }
 
    virtual Door* MakeDoor() const
    {
        return new Door;
    }
 
    HouseFactory();
    ~HouseFactory();
    
};
 
House* CreateHouse(HouseFactory& factory)
{
    House* house = factory.MakeHouse();
    Room* room = factory.MakeRoom();
    Door* door = factory.MakeDoor();
 
    house->AddRoom(room);
    room->AddDoor(door);
 
    return house;
}

만약 조금 더 큰 집을 만든다고 한다면..

HouseFactory ,  House , Room 클래스를 상속하는 다른 서브 클래스의 인스턴트를 반환하도록 만듭니다.

class Big_HouseFactory : public HouseFactory
{
 
public :
 
    virtual House* MakeHouse() const
    {
        return new BigHouse;
    }
 
    virtual Room* MakeRoom() const
    {
        return new BigRoom;
    }
 
    Big_HouseFactory();
    ~Big_HouseFactory();
 
};

 

작은집이나 큰집이나 모두 CreateHouse 함수로 호출하면 됩니다. 

 

void main()
{
 
    HouseFactory factory1;
    Big_HouseFactory factory2;
 
    CreateHouse(factory1);
    CreateHouse(factory2);
 
    return;
}

 

단순히 팩토리 메서드들이 모인 집합체로 구현하는것이 추상 팩토리 패턴을 구현하는 가장 일반적인 방법입니다.

 

하지만 구현된 펙토리 클래스가 추상 클래스가 아니므로  ConcreteFactory 나 concreteFactory로 사용 할 수 있는데, 이것을 응용하는 또하나의 일반적인 구현 방법으로 보면 되겠습니다.

 

- 참고 : GOF의 디자인 패턴 , 게임 프로그래밍 패턴 , 시용주의 디자인 패턴 , WIKI , MSDN

 

[개인적인 생각]

그런데 생각해본다면, 말 그대로 추상 클래스가 포함된 팩토리 패턴이어야 하지 않을까 하는 생각이 듭니다.

 

[MSDN] - 추상 클래스(설명)

 

추상 클래스는 보다 구체적인 클래스가 파생될 수 있는 일반 개념의 식 역할을 합니다. 추상 클래스 형식의 개체를 만들 수는 

없지만, 추상 클래스 형식에 대한 포인터와 참조를 사용할 수 있습니다.

순수 가상 함수가 하나 이상 포함된 클래스는 추상 클래스로 간주됩니다. 추상 클래스에서 파생 클래스는 순수 가상 함수를 구현해야 합니다. 이렇게 하지 않으면 파생 클래스도 추상 클래스가 됩니다.

 

아래처럼 말이죠..

class Item
{
 
public:
 
    int price;
    virtual void PrintMessage() const = 0;
};
 
class House : public Item{
 
public:
 
    int price = 10;
 
    virtual void PrintMessage() const
    {
        std::cout << price << endl;
    }
};
 
class Room : public Item{
 
public:
 
    int price = 5;
 
    virtual void PrintMessage() const
    {
        std::cout << price << endl;
    }
};
 
class Door : public Item{
 
public:
 
    int price = 3;
 
    virtual void PrintMessage() const
    {
        std::cout << price << endl;
    }
};
 
 
 
class HouseFactory
{
 
public:
 
    virtual House* MakeHouse() const
    {
        return new House();
    }
 
    virtual Room* MakeRoom() const
    {
        return new Room;
    }
 
    virtual Door* MakeDoor() const
    {
        return new Door;
    }
    
};
 
House* CreateHouse(HouseFactory& factory)
{
    House* house = factory.MakeHouse();
    Room* room = factory.MakeRoom();
    Door* door = factory.MakeDoor();
 
    house->PrintMessage();
    room->PrintMessage();
    door->PrintMessage();
 
    return house;
}
 
 
void main()
{
    HouseFactory factory1;
 
    CreateHouse(factory1);
 
    return;
}

 

반응형