반응형
빌더 패턴은 여러 복잡한 요소들의 조합이 필요한 객체를 생성해야 하거나 여러 개의 다양한 객체 집합을 생성해야 할 때 객체 생성만을 전담하는 컴포넌트를 정의하여 객체 생성을 간편하게 하는 것입니다.
이해가 되지 않으면 예제 코드를 보면 쉽게 이해가 되겠죠.
House house = HouseBuilder::.buildWalls().
.buildDoors().
.buildWindows().
.buildRoof()
.buildGarage()
.getReulst();
Email mail = Email::make().from("me@mail.com")
.to("you@mail.com")
.subject("C++ builders")
.body("I like this API, don't you?");
- 컴포지트 빌더
객체 하나를 생성하는데 복수의 빌더가 사용되는 경우입니다.
"주소"와 "직업"정보를 가진 Person을 빌드하는 예제입니다.
Person p = Person::create()
.lives().at("123 London Road").with_postcode("SW1 1GB").in("London")
.works().at("PragmaSoft").as_a("Consultant").earning(1000);
create()함수를 이용해 빌더를 얻고
PersonBuilder Person::create()
{
return PersonBuilder{};
}
lives(), woarks() 함수를 이용해 각각 PersonAddressBuilder와 PersonJobBuilder를 얻습니다.
PersonAddressBuilder PersonBuilderBase::lives() const
{
return PersonAddressBuilder{ person };
}
PersonJobBuilder PersonBuilderBase::works() const
{
return PersonJobBuilder{ person };
}
생성절차가 모두 완료되고 나면 최종적으로 완성된 Person 객체를 얻습니다.
GoF의 디자인 패턴에서는 Builder, ConcreteBuilder, Director, Product로 빌더 패턴을 예시하였습니다.
여기서 설명한 빌더와 목적은 같지만 전혀 다른 구현의 빌더 패턴이므로 이러한 빌더 패턴도 숙지해두면 좋겠습니다.
- Gof의 빌더(Builder) 패턴
복잡한 객체를 생성하는 방법을 클래스별로 분리하여, 서로 다른 표현이라도 이를 생성할 수 있는 동일한 절차를 제공합니다. Concreate Builder(아처, 워리어)들이 클래스 별로 분리이며 생성할 수 있는 절차가 Director입니다.
struct Weapon
{
int mPower;
};
struct Armor
{
int mDefence;
};
// Product
class Character
{
public:
Weapon* mWeapon;
Armor* mArmor;
void DisplayParts()
{
std::cout << "Weapon power:" << mWeapon->mPower << std::endl;
std::cout << "Armor defence:" << mArmor->mDefence << std::endl;
}
};
// Builder 인터페이스
class CharacterBuilder
{
public:
virtual Weapon* CreateWeapon() = 0;
virtual Armor* CreateArmor() = 0;
};
// Director, Product 생성 공정을 책임 집니다.
class CharacterDirector
{
CharacterBuilder* mBuilder;
public:
void SetBuilder(CharacterBuilder* newBuilder)
{
mBuilder = newBuilder;
}
Character* CreateCharacter()
{
Character* character = new Character();
character->mWeapon = mBuilder->CreateWeapon();
character->mArmor = mBuilder->CreateArmor();
return character;
}
};
// Concrete Builder for archer
class ArcherBuilder : public CharacterBuilder
{
public:
Weapon* CreateWeapon()
{
Weapon* weapon = new Weapon();
weapon->mPower = 200;
return weapon;
}
Armor* CreateArmor()
{
Armor* armor = new Armor();
armor->mDefence = 50;
return armor;
}
};
// Concrete builder for warrior
class WarriorBuilder : public CharacterBuilder
{
public:
Weapon* CreateWeapon()
{
Weapon* weapon = new Weapon();
weapon->mPower = 50;
return weapon;
}
Armor* CreateArmor()
{
Armor* armor = new Armor();
armor->mDefence = 200;
return armor;
}
};
int main()
{
Character* character;
CharacterDirector director;
ArcherBuilder archer;
director.SetBuilder(&archer);
character = director.CreateCharacter();
character->DisplayParts();
WarriorBuilder warrior;
director.SetBuilder(&warrior);
character = director.CreateCharacter();
character->DisplayParts();
return 0;
}
코드 참고 : https://cpp-design-patterns.readthedocs.io/en/latest/
'프로그래밍 일반 > 디자인 패턴' 카테고리의 다른 글
브릿지 패턴(Bridge Pattern) (0) | 2019.12.08 |
---|---|
어댑터 패턴(Adapter Pattern) (0) | 2019.12.08 |
싱글턴 패턴(Singleton Pattern) (0) | 2019.12.08 |
프로토타입 패턴(Prototype Pattern) (0) | 2019.12.08 |
팩토리 패턴(Factory pattern) (2) | 2019.11.17 |