반복자 패턴은 내부 구조를 노출하지 않고, 컬렉션의 요소들을 하나씩 순회(traverse)할 수 있도록 하는 행동(Behavioral) 디자인 패턴이다.
STL의 컨테니어들에 항상 들어가있다.
자료구조마다 순회 방식이 다를 수 있다. (예:) 트리는 깊이 우선 탐색(DFS)과 넓이 우선 탐색(BFS) 등 여러 순회 방식이 있다.)
특정 컬렉션을 순회할 때 내부 구조에 직접 접근할 수 있게 된다면, 컬렉션이 변경될 때 마다 클라이언트 코드도 함께 수정해야 하므로 결합도가 높아진다는 문제가 있다.
반복자들은 보통 다음 요소를 가져오는 메서드, 순회가 끝났는지 확인하는 메서드 등을 포함한 인터페이스를 구현한다.
예를 들어 아래처럼 함수를 구현할 수 있다.
bool HasNext() : 다음 요소가 존재하는가?
T Next() : 다음 요소를 가져오고, 내부적으로 포인터(현재 위치)를 한 칸 전진
template <typename T>
class IIterator
{
bool HasNext();
T* Next();
};
위에서 말한대로 Interface를 구현한다.
HaseNext가 true라면 Next로 다음 요소에 접근하는 방식
template <typename T>
class IAggregate
{
IIterator<T> CreateIterator();
};
CreateIterator() : 이 메서드를 통해 컬렉션에 맞는 반복자를 생성(또는 반환)한다.
주의할 점은, 반복자 반환 타입이 IIterator<T> 라는 점이다.
이로써, 컬렉션 구현체가 무엇이든, 클라이언트는 반복자 인터페이스만 보고 순회할 수 있다.
빌더(Builder) 패턴은 복잡한 객체의 생성 로직을 객체 내부나 거대한 생성자 대신, 별도의 빌더 객체로 캡슐화하여, 다음을 가능하게한다.
단계별(점진적) 생성
동일한 생성 과정을 통해 여러 표현을 지원
CarBuilder가 스포츠카를 만들 수도, SUV를 만들 수도 있음 (옵션/단계 호출 방식만 다름)class Character
{
public:
float hp;
float damage;
string job;
string weapon;
};
이 캐릭터 클래스를 빌더로 만든다고 해보자
현재는 너무 간단해서 빌더까지 필요 없겠지만 Builder를 만든다고 생각해보자
class CharacterBuilder
{
private:
Character* character;
public:
void Reset()
{
character = new Character();
}
void SetHp(float hp)
{
character->hp = hp;
}
void SetDamage(float damage)
{
character->damage = damage;
}
void SetJob(string job)
{
character->job = job;
}
void SetWeapon(string weapon)
{
character->weapon = weapon;
}
Character* GetResult()
{
return character;
}
};
다음과 같이 빌더를 만들었다면
아래와 같이 사용 가능하다.
int main()
{
CharacterBuilder builder;
builder.Reset();
builder.SetJob("전사");
builder.SetHp(100);
builder.SetDamage(10);
builder.SetWeapon("장검");
Character* warrior = builder.GetResult();
}
이런 식으로 순차적으로 구성을 쌓아 제작할 수 있다.