구조적 디자인 패턴: Facade, Flyweight, 그리고 Proxy
구조적 디자인 패턴은 클래스와 객체를 조직화하는 데 도움을 줍니다.
오늘은 여러분의 도구 상자를 완성할 마지막 세 가지 패턴을 다룹니다.
1. Facade 패턴 Facade는 복잡한 시스템을 단순화합니다. 복잡하게 얽힌 클래스 그룹에 대해 하나의 단순한 인터페이스를 제공합니다.
영화관을 생각해 보세요. 영화를 보려면 조명을 어둡게 하고, 프로젝터를 켜고, 커튼을 열어야 합니다. 다섯 가지 서로 다른 시스템을 호출하는 대신, 하나의 메서드인 theater.watch_movie()를 호출하면 됩니다.
다음과 같은 경우에 사용하세요:
- 복잡한 서브시스템을 단순화하고 싶을 때.
- 대규모 API를 위한 단일 진입점이 필요할 때.
- 클라이언트를 내부 로직으로부터 분리하고 싶을 때.
2. Flyweight 패턴 Flyweight는 메모리를 절약합니다. 수천 개의 유사한 객체가 있을 때 유용합니다.
모든 객체에 모든 세부 정보를 저장하는 대신 데이터를 분할합니다. 공유되고 변하지 않는 데이터(내재적 상태, intrinsic state)는 한 곳에 보관하고, 고유한 데이터(외재적 상태, extrinsic state)는 별도로 관리합니다.
다음과 같은 경우에 사용하세요:
- 메모리 사용량이 실제 문제가 될 때.
- 텍스트 에디터의 문자나 게임의 파티클처럼 수백만 개의 유사한 객체를 관리할 때.
- 성능 향상을 위해 객체 풀링(object pooling)을 사용하고 싶을 때.
3. Proxy 패턴 Proxy는 다른 객체를 대신하는 대리인 역할을 합니다. 클라이언트와 실제 객체 사이에 위치하여 접근을 제어합니다.
Proxy는 다음과 같은 역할을 할 수 있습니다:
- 지연 로딩(Lazy load): 사용자가 클릭할 때만 무거운 이미지를 로드합니다.
- 접근 제어: 사용자가 데이터베이스를 삭제할 권한이 있는지 확인합니다.
- 활동 로그 기록: 특정 서비스를 누가 사용하는지 추적합니다.
- 결과 캐싱: 비용이 많이 드는 로직을 실행하는 대신 저장된 데이터를 반환합니다.
다음과 같은 경우에 사용하세요:
- 비용이 많이 드는 작업을 지연시켜야 할 때.
- 민감한 서비스를 보호해야 할 때.
- 원본 클래스를 변경하지 않고 로깅이나 보안 기능을 추가하고 싶을 때.
요약 표
• Adapter: 호환되지 않는 시스템이 함께 작동하도록 합니다. • Bridge: 추상화와 구현을 분리합니다. • Composite: 트리 구조를 구축합니다. • Decorator: 클래스를 수정하지 않고 동작을 추가합니다. • Facade: 복잡한 서브시스템을 단순화합니다. • Flyweight: 메모리 절약을 위해 데이터를 공유합니다. • Proxy: 객체에 대한 접근을 제어합니다.
황금률: 코드를 유지보수하기 쉽게 만들기 위해 이 패턴들을 사용하세요. 단순히 과시하기 위해 사용해서는 안 됩니다.
다음으로, 행동 디자인 패턴(Behavioral Design Patterns) 시리즈를 시작합니다.