목차
개요
내용
요약
하위 시스템들의 인터페이스를 묶은 통합 인터페이스를 제공하자. 퍼사드는 하위 시스템을 이용하기 쉽게 하기 위한 고수준 인터페이스를 제공합니다.
예시
컴파일러 프로그램을 만든다고 생각합시다. 프로그램 내에는 Scanner, Parser, Stream, ProgramNode 등등의 클래스가 있을 것입니다. 이 프로그램을 사용하는 사용자가 위 클래스들을 모두 공부한 다음 써야할 필요가 있을까요? 이 때 Compiler라는 퍼사드 클래스를 만들면 문제가 해결될 수 있습니다.
구조
이야깃거리
언제 써야 할까?
- 복잡한 하위 시스템에 대한 간단한 인터페이스를 제공하고 싶을 때
- 대부분의 패턴들은 적용되었을 때 더 많고 작은 클래스들을 만들면서 유지보수를 용이하게 하지만 한편으로 시스템을 사용하기 더 복잡하게 만듭니다. 이 떄 퍼사드를 사용할 수 있습니다.
- 라이브러리 사용자가 라이브러리의 구현 클래스에 많이 의존적일 때
- 하위 시스템에 레이어를 나누고 싶을 때. 퍼사드가 entrypoint 역할을 할 수 있습니다.
장단점
- (Pros) 하위 시스템으로부터 사용자를 지켜줍니다
- (Pros) 하위 시스템 컴포넌트들 사이에 커플링을 줄여줍니다. 복잡하거나 순환 의존관계를 없애줄 수 있습니다.
- (Cons) 하위 시스템을 너무 가려버리면, 유연함과 사용자의 커스터마이제이션을 막을 수 있습니다.
Case Study
Case 1. Slf4j
브릿지 패턴에서 나온 로깅 프레임워크인 slf4j 입니다. Logger라는 통합된 인터페이스로 하위 시스템을 가려줍니다.
Case 2. Micrometer
마이크로미터는 JVM에서 동작하는 오픈소스 라이브러리입니다. 공식 홈페이지에선 마이크로미터를 아래처럼 소개하고 있습니다.
Micrometer is ... Vendor-neutral application observability facade
위 소개를 단어 하나하나씩 뜯어봅시다.
- vendor-neutral -> vendor lock-in 없이 사용할 수 있다는 뜻입니다. 즉, observability를 구현하는 의존성이 바뀌어도 코드를 바꾸지 않아도 되게 해줍니다.
- observability -> 분산 시스템에서 observability란 프로그램의 실행, 모듈의 내부 상태, 그들간에 커뮤니케이션에 대한 데이터를 수집하는 능력입니다. 보통 광범위한 로깅과 추적이 요구됩니다.
- facade -> 이번 글에 나오는 퍼사드 패턴의 퍼사드와 동일한 개념입니다.
즉, 마이크로미터는 observability를 위한 퍼사드를 제공해주는 라이브러리라고 할 수 있습니다. 마이크로미터엔 여러가지 개념들과 사용법들이 나오는데, 나중에 이에 대해 다루기로 하고 지금은 퍼사드 패턴을 이해할 수 있는 한 예만 살펴봅시다. 아래 코드 스니펫은 마이크로미터의 컴포넌트 중 하나인 Tracer라는 클래스를 생성하기 위한 설정 코드입니다. 하나하나 이해할 필요는 없으니 한 번 살펴만 봅시다. 아래에 나오는 Brave라는 단어는 micrometer 퍼사드를 구현하는 벤더 중 하나입니다.
// [Brave component] Example of using a SpanHandler. SpanHandler is a component
// that gets called when a span is finished. Here we have an example of setting it
// up with sending spans
// in a Zipkin format to the provided location via the UrlConnectionSender
// (through the <io.zipkin.reporter2:zipkin-sender-urlconnection> dependency)
// Another option could be to use a TestSpanHandler for testing purposes.
SpanHandler spanHandler = ZipkinSpanHandler
.create(AsyncReporter.create(URLConnectionSender.create("http://localhost:9411/api/v2/spans")));
// [Brave component] CurrentTraceContext is a Brave component that allows you to
// retrieve the current TraceContext.
ThreadLocalCurrentTraceContext braveCurrentTraceContext = ThreadLocalCurrentTraceContext.newBuilder()
.addScopeDecorator(MDCScopeDecorator.get()) // Example of Brave's
// automatic MDC setup
.build();
// [Micrometer Tracing component] A Micrometer Tracing wrapper for Brave's
// CurrentTraceContext
CurrentTraceContext bridgeContext = new BraveCurrentTraceContext(this.braveCurrentTraceContext);
// [Brave component] Tracing is the root component that allows to configure the
// tracer, handlers, context propagation etc.
Tracing tracing = Tracing.newBuilder()
.currentTraceContext(this.braveCurrentTraceContext)
.supportsJoin(false)
.traceId128Bit(true)
// For Baggage to work you need to provide a list of fields to propagate
.propagationFactory(BaggagePropagation.newFactoryBuilder(B3Propagation.FACTORY)
.add(BaggagePropagationConfig.SingleBaggageField.remote(BaggageField.create("from_span_in_scope 1")))
.add(BaggagePropagationConfig.SingleBaggageField.remote(BaggageField.create("from_span_in_scope 2")))
.add(BaggagePropagationConfig.SingleBaggageField.remote(BaggageField.create("from_span")))
.build())
.sampler(Sampler.ALWAYS_SAMPLE)
.addSpanHandler(this.spanHandler)
.build();
// [Brave component] Tracer is a component that handles the life-cycle of a span
brave.Tracer braveTracer = this.tracing.tracer();
// [Micrometer Tracing component] A Micrometer Tracing wrapper for Brave's Tracer
Tracer tracer = new BraveTracer(this.braveTracer, this.bridgeContext, new BraveBaggageManager());
핵심은 마지막 문장입니다. Brave라는 구체적인 vendor를 사용했지만 마지막 결과물은 마이크로미터의 퍼사드 클래스인 Tracer입니다. 이런 방식으로 사용자는 brave가 아닌 opentelemetry 등의 vendor를 사용해도 똑같이 마이크로미터 Tracer를 얻을 수 있습니다.
출처
GoF Design Patterns
'Design Patterns' 카테고리의 다른 글
[Design Patterns] Proxy (0) | 2024.03.31 |
---|---|
[Design Patterns] Flyweight (1) | 2024.03.27 |
[Design Patterns] Decorator (0) | 2024.03.20 |
[Design Patterns] Composite (0) | 2024.03.17 |
[Design Patterns] Bridge (0) | 2024.03.16 |