Facade

chris·2021년 7월 10일
0

design pattern

목록 보기
9/11

Intent

Facade는 라이브러리, 프레임워크 또는 기타 복잡한 클래스 집합에 대한 단순화된 인터페이스를 제공하는 structural design pattern입니다.

Problem

정교한 라이브러리나 프레임워크에 속하는 광범위한 개체 집합으로 코드를 작동시켜야 한다고 상상해 보세요. 일반적으로 이러한 개체를 모두 초기화하고, 종속성을 추적하고, 올바른 순서로 Method를 실행하는 등의 작업을 수행해야 합니다.

결과적으로 클래스의 비지니스 논리가 타사 클래스의 구현 세부 정보와 밀접하게 연결되어 이해하고 유지 관리하기가 어렵습니다.

Solution

Facade는 많은 움직이는 부분을 포함하는 복잡한 하위 시스템에 대한 간단한 인터페이스를 제공하는 클래스입니다. Facade는 하위 시스템과 직접 작업하는 것과 비교하여 제한된 기능을 제공할 수 있습니다. 그러나 여기에는 클라이언트가 실제로 관심을 갖는 기능만 포함됩니다.

Facade를 갖는 것은 수십 가지 기능이 있는 정교한 라이브러리와 앱을 통합해야 할 때 편리하지만 그 기능은 아주 약간만 필요합니다.

예를 들어, 공야이와 함께 짧은 재미있는 비디오를 소셜 미디어에 업로드하는 앱은 잠재적으로 전문적인 비디오 변환 라이브러리를 사용할 수 있습니다. 그러나 실제로 필요한 것은 단일 Method인 encode(filename, format)가 있는 클래스뿐입니다. 이러한 클래스를 만들고 비디오 변환 라이브러리와 연결하면 첫 번째 Facade가 생깁니다.

Real-World Analogy


전화 주문을 하기 위해 상점에 전화를 걸명 교환원은 상점의 모든 서비스와 부서에 대한 Facade입니다. 교환원은 주문 시스템, 지불 게이트웨이 및 다양한 배송 서비스에 대한 간단한 음성 인터페이스를 제공합니다.

Structure

  1. Facade는 하위 시스템 기능의 특정 부분에 대한 편리한 액세스를 제공합니다. 클라이언트의 요청을 어디로 보내야 하는지, 움직이는 모든 부품을 어떻게 작동해야 하는지 알고 있습니다.

  2. Additional Facade 클래스는 관련 없는 기능으로 단일 외관을 오염시켜 또 다른 복잡한 구조를 만들 수 있는 것을 방지하기 위해 생성할 수 있습니다. Additional Facade는 클라이언트와 다른 Facade 모두에서 사용할 수 있습니다.

  3. Complex Subsystem은 수십 개의 다양한 객체로 구성됩니다. 그들 모두가 의미 있는 일을 하도록 하려면 올바른 순서로 개체를 초기화하고 적절한 형식의 데이터를 제공하는 것과 같은 하위 시스템의 구현 세부 정보를 자세히 살펴봐야 합니다.

    서브시스템 클래스는 Facade의 존재를 인식하지 못합니다. 그들은 시스템 내에서 작동하고 서로 직접 작동합니다.

  4. 클라이언트는 서브시스템 개체를 직접 호출하는 대신 Facade를 사용합니다.

Pseudocode

이 예에서 Facade pattenr은 복잡한 비디오 변환 프레임워크와의 상호 작용을 단순화합니다.

코드가 수십 개의 프레임워크 클래스와 직접 작동하도록 하는 대신 해당 기능을 캡슐화하고 코드의 나머지 부분에서 숨기는 Facade 클래스를 만듭니다. 이 구조는 또한 프레임워크의 향후 버전으로 업그레이드 하거나 다른 프레임워크로 교체하는 노력을 최소화하는 데 도움이 됩니다. 앱에서 변경해야 할 유일한 것은 Facade의 Method 구현입니다.

// These are some of the classes of a complex 3rd-party video
// conversion framework. We don't control that code, therefore
// can't simplify it.

class VideoFile
// ...

class OggCompressionCodec
// ...

class MPEG4CompressionCodec
// ...

class CodecFactory
// ...

class BitrateReader
// ...

class AudioMixer
// ...


// We create a facade class to hide the framework's complexity
// behind a simple interface. It's a trade-off between
// functionality and simplicity.
class VideoConverter is
    method convert(filename, format):File is
        file = new VideoFile(filename)
        sourceCodec = new CodecFactory.extract(file)
        if (format == "mp4")
            destinationCodec = new MPEG4CompressionCodec()
        else
            destinationCodec = new OggCompressionCodec()
        buffer = BitrateReader.read(filename, sourceCodec)
        result = BitrateReader.convert(buffer, destinationCodec)
        result = (new AudioMixer()).fix(result)
        return new File(result)

// Application classes don't depend on a billion classes
// provided by the complex framework. Also, if you decide to
// switch frameworks, you only need to rewrite the facade class.
class Application is
    method main() is
        convertor = new VideoConverter()
        mp4 = convertor.convert("funny-cats-video.ogg", "mp4")
        mp4.save()

Applicability

복잡한 서브 시스템에 대한 제한적이지만 간단한 인터페이스가 필요한 경우 Facade Pattern을 사용하십시오

종종 서브시스템은 시간이 지남에 따라 더 복잡해집니다. Design Pattern을 적용해도 일반적으로 더 많은 클래스가 생성됩니다. 서브 시스템은 다양한 상황에서 더 유연해지고 더 쉽게 재사용할 수 있지만 크라이언트에서 요구하는 구성 및 상용구 코드의 양은 점점 더 커집니다. Facade는 대부분의 클라이언트 요구 사항에 맞는 서브시스템의 가장 많이 사용되는 기능에 대한 바로 가기를 제공하여 이 문제를 해결하려고 시도합니다.

서브시스템을 계층으로 구성하려는 경우 Facade를 사용하십시오

서브시스템의 각 레벨에 대한 진입점을 정의하기 위해 파사드를 작성하십시오. 파사드를 통해서만 통신하도록 요구함으로써 여러 서브시스템간의 결합을 줄일 수 있습니다.

예를 들어 비디오 변환 프레임워크로 돌아가 보겠습니다. 비디오 및 오디오 관련의 두 가지 계층으로 나눌 수 있습니다. 각 레이어에 대해 파사드를 만든 다음 각 레이어의 클래스가 해당 파사드를 통해 서로 통신하도록 할 수 있습니다. 이 접근 방식은 Mediator 패턴과 매우 유사해 보입니다.

How to Implement

  1. 기존 서브시스템이 이미 제공하는 것보다 더 간단한 인터페이스를 제공할 수 있는지 확인하십시오. 이 인터페이스가 클라이엉트 코드를 여러 서브시스템의 클래스와 독립적으로 만든다면 올바른 길을 가고 있는 것입니다.

  2. 새 Facade 클래스에서 이 인터페이스를 선언하고 구현하십시오. Facade는 클라이언트 코드의 호출을 서브시스템의 적절한 개체로 Redirect해야 합니다. 클라이언트 코드가 이미 이 작업을 수행하지 않는 한 Facade는 서브시스템을 초기화하고 추가 수명 주기를 관리해야 합니다.

  3. 패턴의 이점을 최대한 활용하려면 모든 클라이언트 코드가 파사드를 통해서만 하위 시스템과 통신하도록 합니다. 이제 클라이언트 코드는 서브시스템 코드의 변경 사항으로부터 보호됩니다. 예를 들어 서브시스템이 새 버전으로 업그레이드 되면 Facade의 코드만 수정하면 됩니다.
  4. Facade가 너무 커지먼 동작의 일부를 새롭고 세련된 Facade 클래스로 추출하는 것을 고려하십시오.

Pros and Cons

O 서브시스템의 복잡성에서 코드를 분리할 수 있습니다.

X Facade는 앱의 모든 클래스에 결합된 a god object가 될 수 있습니다.

Releations with Other Patterns

  • Facade는 기존 개체에 대한 새 인터페이스를 정의하는 반면 Adapter는 기존 인터페이스를 사용 가능하게 만들려고 합니다. Adapter는 일반적으로 하나의 개체만 Wrapping하는 반면 Facade는 개체의 전체 하위 시스템과 함께 작동합니다.

  • Abstract Factory는 클라이언트 코드에서 서브시스템 객체가 생성되는 방식만 숨기고 싶을 때 Facade의 대안으로 사용할 수 있습니다.

  • Flyweight는 많은 작은 개체를 만드는 방법을 보여주는 반면 Facade는 전체 서브시스템을 나타내는 단일 개체를 만드는 방법을 보여 줍니다.

  • Facade와 Mediator는 비슷한 역할을 합니다. 밀접하게 연결된 많은 클래스 간의 협업을 구성하려고 합니다.

    • Facade는 객체의 서브시스템에 대한 단순화된 인터페이스를 정의하지만 새로운 기능을 도입하지는 않습니다. 서브시스템 자체는 Facade를 인식하지 못합니다. 서브시스템 내의 개체는 직접 통신할 수 있습니다.

    • Mediator는 시스템 구성 요소간의 통신을 중앙 집중화 합니다. 구성 요소는 Mediator 개체에 대해서만 알고 직접 통신하지 않습니다.

  • 대부분의 경우 단일 Facade 객체로 충분하기 때문에 Facade 클래스는 종종 싱글톤으로 변환될 수 있습니다.

  • Facade는 복잡한 엔티티를 버퍼링하고 자체적으로 초기화 한다는 점에서 Proxy와 유사합니다. Facade와 달리 Proxy는 서비스 객체와 동일한 인터페이스를 가지고 있어 상호 교환이 가능합니다.

profile
software engineer

0개의 댓글