퍼사드 패턴
서브시스템에 있는 일련의 인터페이스를 통합 인터페이스로 묶어준다.
고수준 인터페이스도 정의하므로 서브시스템을 더 편리하게 사용할 수 있다.
큰 인터페이스와 여러 인터페이스를 단순하게 바꾸거나 통합해야 할 때 쓰인다.
서브 시스템으로 퍼사드를 만들고 진짜 작업은 서브클래스에 맡긴다.
최소 지식 원칙 (Principle of Knowledge)
객체 사이의 상호작용은 될 수 있으면 아주 가까운 '친구' 사이에서만 허용하는 편이 좋다.
친구를 만들지 않고 다른 객체에 영향력 행사하기
- 객체 자체
- 메소드에 매개변수로 전달된 객체
- 메소르듣 생성하거나 인스턴스를 만든 객체
- 객체에 속하는 구성요소
class Car {
private:
Engine* engine;
public:
void start(Key *key) {
Doors* doors = new Doors{};
bool authorized = key->turns(); // 메소드에 매개변수로 전달된 객체
if (authorized) {
engine->start(); // 객체에 속하는 구성 요소
updateDashboardDisplay(); // 객체 자체 (객체 내에 있는 메소드)
doores->lock(); // 메소드를 생성하거나 인스턴스를 만든 객체 (직접 만든 경우)
}
}
void updateDashboardDisplay() {
}
};
메소드를 호출한 결과로 리턴받은 객체에 들어있는 메소드를 호출할 때의 단점
-> 다른 객체의 일부분에 요청하게 되고, 직접적으로 알고 지내는 객체의 수가 증가
최소 지식 원칙을 따르려면 객체가 대신 요청하도록 만들어야 한다.
이러면 객체의 한 구성 요소를 알고 지낼 필요가 없고, 친구의 수를 줄이는 데도 도움이 된다.
// 원칙을 따르지 않은 경우
float getTemp() {
Thermometer thermometer = station.getThermometer();
return thermometer.getTemperature();
}
// station 으로부터 thermometer 객체를 받은 다음,
// 그 객체의 getTemperature() 메서드를 직접 호출
// 원칙을 따르는 경우
float getTemp() {
return station.getTemperature();
}
// 최소 지식 원칙을 적용해어 thermometer 에게
// 요청을 전달하는 메소르듣 station 클래스에 추가
// 이러면 의존해야하는 클래스의 개수를 줄일 수 있다.
예제)
#include <iostream>
using namespace std;
class GameInstance {
public:
// Get a Subsystem of specified type
UGameInstanceSubsystem* GetSubsystemBase(TSubclassOf<UGameInstanceSubsystem> SubsystemClass) const
{
return SubsystemCollection.GetSubsystem<UGameInstanceSubsystem>(SubsystemClass);
}
// Get a Subsystem of specified type
template <typename TSubsystemClass>
TSubsystemClass* GetSubsystem() const
{
return SubsystemCollection.GetSubsystem<TSubsystemClass>(TSubsystemClass::StaticClass());
}
// 제공된 GameInstance에서 지정된 유형의 하위 시스템 가져오기
// 하위 시스템을 찾을 수 없거나 GameInstance가 null인 경우 nullptr을 반환합니다.
template <typename TSubsystemClass>
static FORCEINLINE TSubsystemClass* GetSubsystem(const UGameInstance* GameInstance)
{
if (GameInstance)
{
return GameInstance->GetSubsystem<TSubsystemClass>();
}
return nullptr;
}
// 수명이 UGameInstance의 수명보다 짧다는 확신이 없으면 이 배열 참조를 유지하지 마십시오.
template <typename TSubsystemClass>
const TArray<TSubsystemClass*>& GetSubsystemArray() const
{
return SubsystemCollection.GetSubsystemArray<TSubsystemClass>(TSubsystemClass::StaticClass());
}
private:
FObjectSubsystemCollection<UGameInstanceSubsystem> SubsystemCollection;
};
class UISubsystem : public UGameInstanceSubsystem {
public:
void ShowBaseUILayout();
void HideBaseUILayout();
};
class SequenceSubsystem : public UGameInstanceSubsystem {
public:
void SequencePlay(ALevelSequenceActor* sequenceActor) {
sequenceActor->Play();
}
void SequenceStop(ALevelSequenceActor* sequenceActor) {
sequenceActor->Stop();
}
};
int main () {
// 최소 지식 원칙 적용하여 사용
GetGameInstance()->GetSubsystem<UISubsystem>()->ShowBaseUILayout();
GetGameInstance()->GetSubsystem<UISubsystem>()->HideBaseUILayout();
// 실제 언리얼 에서는 GetSubsystem 비용이 비싸 변수에 저장한 다음 사용
TObjectPtr<UISubsystem> uiSubsystem = GetGameInstance()-><UISubsystem>();
uiSubsystem->ShowBaseUILayout();
uiSubsystem->HideBaseUILayout();
}
'디자인 패턴' 카테고리의 다른 글
컴포지트 패턴 (Composite Pattern) (0) | 2023.05.16 |
---|---|
템플릿 메소드 패턴 (Template Method pattern) (0) | 2023.05.06 |
어댑터 패턴 (Adaptor pattern) (0) | 2023.04.30 |
커맨드 패턴 (Command Pattern) (0) | 2023.04.23 |
싱글톤 패턴 (Singleton Pattern) (0) | 2023.04.16 |