퍼사드 패턴 개념 정리(강의 - 얄팍한 코딩사전)
객체지향 디자인 패턴 중 하나인 퍼사드 패턴에 대한 개념 정리 및 예제 코드
들어가며
개발을 진행하다 보면 복잡한 하위 시스템을 관리하는 일이 빈번해진다. 여러 클래스가 상호작용하는 시스템에서는 이러한 복잡성을 줄이기 위한 방법이 필요하다. 이를 해결하기 위한 디자인 패턴 중 하나가 퍼사드(Facade) 패턴이다. Facade 패턴은 복잡한 시스템을 단순화하고, 클라이언트에게 간단한 인터페이스를 제공하여, 시스템의 복잡성을 숨기면서도 쉽게 사용할 수 있도록 한다.
이 포스트는 ‘얄팍한 코딩사전’ 유튜브 채널의 01. 퍼사드(Facade) 패턴 강의를 참고하여 작성되었다. 강의는 Java로 진행되지만, 이 포스트에서는 예제 코드를 C++로 작성했다. 퍼사드 패턴에 대한 내용을 이해할 수 있도록 설명하며, 코드를 통해 개념을 구체화 했다.
선수 지식
클래스, 객체, static, 추상 클래스, 인터페이스 등
Facade 패턴
Facade 패턴은 복잡한 시스템의 여러 클래스나 인터페이스를 단순화하여 사용할 수 있도록 도와주는 패턴이다. 이 패턴은 복잡한 하위 시스템을 하나의 간단한 인터페이스로 감싸서 클라이언트가 더 쉽게 접근할 수 있도록 설계된다.
Facade 패턴의 역할
Facade 패턴의 주요 역할은 복잡한 시스템의 내부 구조를 숨기고, 단순한 인터페이스를 제공하는 것이다. 이를 통해 사용자는 여러 클래스를 개별적으로 관리할 필요 없이, 하나의 Facade 클래스만을 통해 모든 작업을 처리할 수 있다.
언제 Facade 패턴을 사용해야 하는가?
- 복잡한 시스템을 더 간단하게 사용할 때: 여러 시스템이 상호작용하는 환경에서 클라이언트는 복잡한 시스템을 모두 이해할 필요 없이, Facade 클래스를 통해 필요한 기능만 사용할 수 있다.
- 유지보수를 쉽게 하고 싶을 때: 시스템이 복잡해지거나 확장될 경우, 개별 클래스를 직접 다루는 것이 어려워질 수 있다. Facade 패턴을 통해 시스템의 변화가 클라이언트에게 영향을 미치지 않도록 캡슐화할 수 있다.
Facade 패턴의 구조
Facade 패턴의 구조는 다음과 같다. 좌측에서 우측으로 갈 수록 하위 시스템에서 상위 시스템으로 가는 것이라 할 수 있다.
(클래스1, 클래스2, 클래스3) > (Facade 클래스) > (클라이언트)
강의에서는 건물의 외벽에 비유하여 설명하였다.
건물 외벽에는 손님이 주문을 받고 음식을 내어주는 창구가 있다. 창구 뒤에는 다양한 공간(예: 주방, 계산대, 포장대 등)이 있으며, 손님은 이 내부 공간을 알 필요 없이 창구를 통해 모든 서비스를 제공받는다. 즉, Facade 패턴은 여러 요소들로 구성된 시스템을 단일 창구(Facade 클래스)를 통해 간편하게 사용할 수 있게 해준다.
이를 게임에 비유하면 이해가 쉬워진다.
게임으로 Facade 설명하기
게임에서 플레이어는 “전투 시작”, “스킬 사용”, “아이템 구매” 등의 다양한 기능을 수행해야 한다. 이때 각각의 세부적인 시스템(전투 시스템, 상점 시스템, 그래픽, 사운드 등)을 일일이 제어하려면 상당히 복잡해질 수 있다. 하지만 Facade 패턴을 사용하면 이러한 복잡한 과정을 하나의 간단한 인터페이스로 묶을 수 있다. 예를 들어, GameManager
클래스에서 “StartBattle()”, “UseSkill()” 등의 메소드만 호출하면 복잡한 여러 시스템이 자동으로 사용할 수 있다.
전투를 시작하려면 전투 시스템, 그래픽 시스템, 사운드 시스템이 함께 작동해야 하지만, 플레이어는 단순히 StartBattle()
메소드만 호출하면 된다. 물론, 실제 게임에서는 버튼 클릭이나 인터렉션으로 해당 메소드를 호출할 수 있다.
Facade 패턴이 필요한 이유
- 복잡한 시스템을 단순하게 사용 가능: 플레이어는 복잡한 게임 시스템을 알 필요 없이, 하나의 명령(혹은 버튼 클릭)으로 여러 시스템을 손쉽게 조작할 수 있다.
- 유지보수의 편리함: 게임 개발자가 내부 시스템을 수정하더라도, Facade 클래스를 사용하는 클라이언트(플레이어)는 이 변경 사항을 직접적으로 알 필요가 없다. 따라서 코드 유지보수가 용이해지고, 코드를 더 깔끔하게 유지하면서 새로운 기능을 쉽게 추가할 수 있다.
이처럼 Facade 패턴은 시스템의 복잡성을 숨기고 클라이언트에게 단순화된 인터페이스를 제공함으로써, 개발자와 사용자 모두에게 편리한 환경을 제공한다.
예제 코드
한 눈에 코드를 보기 위해 선언부(.h)와 구현부(.cpp)로 분리하지 않고, main.cpp에서 통합하여 코드를 구현했다.
실제로 C++로 코딩할 때는 선언부와 구현부를 나눠서 코딩하는 것을 추천한다. 프로젝트가 커질 수록 선언부와 구현부로 나눠서 작업해야 유지 보수하기 편리하고, 효율적이기 때문이다.
이 코드는 Facade 패턴을 적용한 간단한 게임 프로세스이다.
BattleSystem(), ShopSystem(), SkillSystem()은 각각 게임의 세부 시스템을 담당하는 클래스들이다. GameManager
는 Facade 역할을 하며, 복잡한 하위 시스템들을 하나의 인터페이스로 묶어준다. StartGame()
메소드만 호출하면 전투 시작, 스킬 사용, 아이템 구매와 같은 여러 시스템을 동시에 실행할 수 있다.
Q&A
Q1. Facade 패턴을 사용해야 하는 가장 큰 이유는 무엇인가?
- A1: Facade 패턴의 가장 큰 장점은 복잡한 시스템을 단순화하여 사용할 수 있다는 점이다. 클라이언트는 복잡한 하위 시스템의 내부 동작을 알 필요 없이, 간단한 인터페이스를 통해 시스템을 사용할 수 있다. 이는 개발자나 사용자가 시스템을 더 쉽게 이해하고 관리할 수 있도록 도와준다.
Q2. Facade 패턴이 적용되지 않으면 어떤 문제가 발생할 수 있는가?
- A2: Facade 패턴이 적용되지 않으면, 클라이언트는 각 시스템의 세부 사항을 모두 알아야 하고, 각각의 클래스와 메소드를 직접 호출해야 하기 때문에 복잡성이 높아진다. 이로 인해 코드가 난잡해지고, 변경할 때마다 여러 클래스를 수정해야 하는 문제가 발생할 수 있다.
Q3. Facade 패턴은 다른 디자인 패턴과 함께 사용할 수 있는가?
- A3: 그렇다, Facade 패턴은 다른 패턴들과 함께 사용할 수 있다. 예를 들어, Singleton 패턴을 사용해 Facade 객체를 전역적으로 하나만 생성하거나, Adapter 패턴을 사용해 기존 인터페이스를 Facade 패턴에 맞게 조정할 수 있다. Facade 패턴은 시스템의 복잡성을 줄이기 위해 다른 패턴과 함께 사용할 때 더 유용하다.
Q4. Facade 패턴을 적용하는 것이 항상 좋은가?
- A4: Facade 패턴은 복잡한 시스템을 단순화하는 데 유용하지만, 모든 경우에 적용할 필요는 없다. 시스템이 충분히 단순하거나 하위 시스템을 직접 사용하는 것이 더 직관적이고 효율적일 경우, Facade 패턴을 굳이 도입할 필요가 없다. 그러나 시스템이 복잡해지고 여러 시스템이 상호작용할 때는 Facade 패턴을 사용하면 유지보수성과 확장성을 높일 수 있다.
Q5. Facade 패턴과 직접 서브시스템을 사용하는 것의 차이점은 무엇인가?
- A5: Facade 패턴을 사용하면 클라이언트는 복잡한 서브시스템을 직접 다룰 필요 없이, 하나의 인터페이스만 통해 모든 작업을 처리할 수 있다. 서브시스템을 직접 사용하는 경우, 클라이언트는 각 시스템의 세부 구현을 알아야 하고, 각 클래스와 메소드를 개별적으로 호출해야 하기 때문에 코드의 복잡도가 높아진다고 할 수 있다.
Q6. Facade 패턴이 유용한 실제 사례는 무엇인가?
- A6: 게임 개발에서 그래픽, 오디오, 물리 엔진 같은 복잡한 서브시스템을 관리할 때 Facade 패턴을 사용할 수 있다. 예를 들어, 전투 시스템이 여러 서브시스템을 연동해야 하는 경우, 전투 시작 시 하나의 Facade 클래스가 여러 서브시스템을 동시에 초기화하고 조작하는 방식으로 사용된다. 이 외에도 스마트 홈 시스템에서 여러 기기(온도 조절기, 조명, 커피 메이커 등)를 하나의 인터페이스로 제어하는 데도 유용하다.
결론
Facade 패턴은 복잡한 시스템을 하나의 단순한 인터페이스로 통합하여 클라이언트가 쉽게 사용할 수 있도록 만드는 디자인 패턴이다. 복잡한 하위 시스템의 세부 사항을 감추고, 클라이언트는 이 Facade 인터페이스를 통해 필요한 기능만을 호출함으로써 효율적으로 시스템을 사용할 수 있다.
이 패턴은 복잡한 시스템을 단순화하고, 유지보수를 쉽게 하며, 확장성을 높일 수 있다는 장점이 있다. 게임 시스템, 스마트 홈, 대규모 소프트웨어 시스템 등 여러 분야에서 널리 활용될 수 있으며, 클라이언트가 시스템의 세부 사항을 몰라도 쉽게 상호작용할 수 있는 환경을 제공한다.
따라서, 시스템이 복잡해질수록 Facade 패턴을 사용하여 코드의 복잡성을 줄이고, 유지보수성과 확장성을 높이는 것이 좋다. 이러한 장점 덕분에 Facade 패턴은 객체지향 프로그래밍에서 자주 사용되는 중요한 디자인 패턴 중 하나이다.
함께 보면 좋은 자료
함께 보면 좋은 자료는 다음과 같다.
- SOLID 원칙과 객체지향 설계의 기본 정리(강의 - 얄팍한 코딩사전) by Kinesis - 객체지향 설계 원칙인 SOLID에 대한 상세 설명
- Design Patterns in C++ by Refactoring.Guru - 리팩토링, 디자인 패턴, SOLID 원칙에 대해 재밌게 공부할 수 있는 플랫폼(개념 이해를 목적으로 공부하면 도움이 된다)
참고 자료
본 포스트를 작성할 때 참고한 자료들이다.
- 유튜브 채널 얄팍한 코딩사전: 01. 파사드(Facade) 패턴 - 본 포스트는 이 강의를 참고하여 작성되었다.