728x90
1. 관찰자 패턴 ( Observer Pattern ) 정의
- 객체 사이에 일 대 다의 의존 관계를 정의해두어, 어떤 객체의 상태가 변할 때 그 객체에 의존성을 가진 다른 객체들이 그 변화를 통지받고 자동으로 업데이트될 수 있게 만드는 패턴
2. 관찰자 인터페이스 정의
// 옵저버 클래스
class Observer
{
public:
virtual ~Observer() {}
virtual void OnNotify( const Entity& InEntity, Event InEvent ) = 0;
};
3. 관찰자 인터페이스 구현
// 업적 시스템에 옵저버 인터페이스 구현 추가
class Achievements : public Observer
{
public:
virtual void OnNotify( const Entity& InEntity, Event InEvent ) override;
};
void Achievements::OnNotify( const Entity& InEntity, Event InEvent )
{
switch ( InEvent )
{
case EVENT_LEVELUP:
if ( InEntity.IsLevelUP() )
// 레벨업 업적 이벤트 처리
break;
case EVENT_KILL_MONSTER:
if ( InEntity.IsKillMonster())
// 몬스터킬 업적 이벤트 처리
break;
}
}
- 관찰자 인터페이스를 각각 시스템에 맞춰 정의하여 사용.
4. 관찰 대상 정의
// 관찰 대상자
class Subject
{
private:
std::list< Observer* > observers;
protected:
void Notify( const Entity& InEntity, Event InEvent );
public:
// 관찰 대상을 추가한다.
void AddObserver( Observer* InObserver );
// 관찰 대상을 제거한다.
void RemoveObserver( Observer* InObserver );
};
void Subject::Notify( const Entity& InEntity, Event InEvent )
{
for ( auto& iter : observers)
iter->OnNotify( InEntity, InEvent );
}
- 관찰 대상 리스트에 추가 / 삭제하여 관찰 당하는 객체 OnNotity()를 호출한다.
- 관찰 대상은 관찰자와 상호작용하지만, 서로 커플링되어 있지 않다.
5. 사라진 리스너 문제 ( Lapsed Listener Problem ) ★★★★★
- UI를 열 때 관찰자를 등록한 뒤, UI를 닫을 때 관찰자를 제거하지 않으면 발생하는 문제
- UI를 닫은 상태에서는 UI를 갱신할 필요가 없지만 관찰자를 제거하지 않아 알림이 올 때마다 UI가 갱신된다. ( CPU 연산 낭비 )
- UI를 매번 새로 생성한 뒤, 관찰자를 등론한 경우 관찰 대상자에 메모리가 참조되고 있어 GC가 돌지 않는 문제가 발생한다.
- ex ) 아이템 획득, 사용 등 빈번하게 발생하는 이벤트에서 가방을 갱신하도록 관찰자를 등록하고, 제거하지 않은 경우
반응형
'Design Pattern > 게임 프로그래밍 패턴' 카테고리의 다른 글
| [Design Pattern] 상태 패턴 (0) | 2022.07.31 |
|---|---|
| [Design Pattern] 싱글턴 패턴 (0) | 2022.07.30 |
| [Design Pattern] 프로토타입 패턴 (0) | 2022.07.30 |
| [Design Pattern] 경량 패턴 (0) | 2022.07.29 |
| [Design Pattern] 명령 패턴 (0) | 2022.07.29 |