퍼사드 패턴(Facade Pattern)은 복잡한 서브시스템을 단순한 인터페이스로 감싸서 쉽게 사용할 수 있도록 해주는 디자인 패턴입니다. 클라이언트 코드가 여러 개의 서브시스템에 직접 접근하는 대신 단순한 인터페이스만 호출하여 원하는 기능을 사용할 수 있습니다.
┌────────────────────┐
│ 클라이언트 │
└────────▲──────────┘
│
▼
┌────────────────────┐
│ 퍼사드(Facade) │
│ - 단순한 인터페이스 │
└────────▲──────────┘
│
┌───────┴────────┐
│ │
▼ ▼
┌───────────┐ ┌───────────┐
│ XX Manager│ │ XX Manager│
└───────────┘ └───────────┘
장점
- 코드 의존성 감소: 여러 매니저 클래스를 직접 참조하는 대신, 하나의 퍼사드 클래스만 참조하도록 변경
- 모듈화 촉진: 서브시스템이 변경되더라도 퍼사드를 통해 동일한 인터페이스를 제공할 수 있어 시스템을 보다 모듈화할 수 있음.
- 캡슐화: 클라이언트가 세부 구현을 알 필요 없이 퍼사드만 사용하면 되므로 내부 변경이 있어도 영향을 최소화할 수 있음.
단점
- 확장성이 제한될 수 있음: 퍼사드 클래스가 너무 많은 기능을 포함하면 새로운 기능을 추가하거나 변경할 때 퍼사드 자체를 수정해야 함. 즉, 퍼사드가 하나의 거대한 클래스(슈퍼 클래스)가 될 위험이 있음.
- 유연성이 감소할 가능성: 클라이언트가 퍼사드만 사용하도록 설계하면 세부 매니저 클래스의 기능을 직접 활용하기 어려울 수 있음. 특정 기능을 세밀하게 제어해야 하는 경우 퍼사드가 오히려 불필요한 제약이 될 수 있음.
- 의존성 증가: 클라이언트가 퍼사드에만 의존하게 되면 퍼사드가 변경될 때 영향을 받을 수 있음.
예제 코드
다음은 여러 개의 매니저 클래스(오디오, UI, 게임 상태 등)를 퍼사드 패턴을 통해 하나의 인터페이스로 감싸는 예제입니다.
1. 개별 매니저 클래스
public class AudioManager : MonoBehaviour
{
public void PlaySound(string sound)
{
Debug.Log($"사운드 재생: {sound}");
}
}
public class UIManager : MonoBehaviour
{
public void ShowMessage(string message)
{
Debug.Log($"UI 메시지: {message}");
}
}
public class GameManager : MonoBehaviour
{
public void StartGame()
{
Debug.Log("게임 시작!");
}
}
위의 개별 매니저 클래스들은 서로 독립적으로 존재하며 클라이언트 코드가 각각의 클래스를 직접 호출해야 합니다. 하지만 이렇게 하면 코드 결합도가 높아지는 단점이 있습니다.
2. 퍼사드 클래스 구현
public class GameFacade : MonoBehaviour
{
private AudioManager audioManager;
private UIManager uiManager;
private GameManager gameManager;
private void Awake()
{
audioManager = FindObjectOfType<AudioManager>();
uiManager = FindObjectOfType<UIManager>();
gameManager = FindObjectOfType<GameManager>();
}
public void StartGameWithIntro()
{
uiManager.ShowMessage("게임을 시작합니다!");
audioManager.PlaySound("StartSound");
gameManager.StartGame();
}
}
이제 GameFacade 클래스가 여러 매니저 클래스를 감싸는 역할을 하므로 클라이언트 코드에서는 GameFacade 하나만 호출하면 됩니다.
3. 클라이언트 코드에서 사용하기
public class GameController : MonoBehaviour
{
private GameFacade gameFacade;
private void Start()
{
gameFacade = new GameFacade();
gameFacade.StartGameWithIntro();
}
}
GameController에서는 gameFacade.StartGameWithIntro();만 호출하면 내부적으로 필요한 매니저들이 자동으로 동작하게 됩니다. 위의 예시처럼 클래스를 생성자를 사용하거나 싱글톤 패턴을 활용할 수 있습니다.
결론
퍼사드 패턴을 활용하면 서브시스템(매니저 클래스들)을 직접 다루지 않고 단순한 인터페이스를 통해 쉽게 접근할 수 있습니다. 이를 통해 유지보수성과 확장성이 향상시킬 수 있습니다. 또한, 유연성을 위해 static을 활용하는 방법을 생각해 볼 수 있습니다.