구조 패턴(Structure Pattern)이란?

삼각김밥·2023년 9월 4일

구조 패턴(Structure Pattern)

구조 패턴이란?

  • 구조패턴은 클래스나 객체를 조합해 더 큰 구조를 만드는 패턴이다.
  • 서로 다른 인터페이스를 지닌 2개의 객체를 묶어 단일 인터페이스를 제공하거나 객체들을 서로 묶어 새로운 기능을 제공하는 패턴이다.

구조 패턴 특징

  • 서로 독립적으로 개발한 클래스 라이브러리를 마치 하나인 것처럼 사용할 수 있다.
  • 여러 인터페이스를 합성하여 서로 다른 인터페이스들의 통일된 추상을 제공한다.
  • 인터페이스나 구현을 복합하는 것이 아니라 객체를 합성하는 방법을 제공한다.

구조 패턴 종류

  1. 어댑터 패턴(Adapter Pattern)
    : 인터페이스가 호환되지 않는 클래스들을 함께 이용할 수 있도록, 타 클래스의 인터페이스를 기존 인터페이스에 덧 씌운다.

  2. 브릿지 패턴(Bridge Pattern)
    : 추상화와 구현을 분리해 둘을 각각 따로 발전시킬 수 있다.

  3. 합성 패턴(Composite Pattern)
    : 0개, 1개 혹은 그 이상의 객체를 묶어 하나의 객체로 이용할 수 있다.

  4. 데코레이터 패턴(Decorator Pattern)
    : 기존 객체의 메서드에 새로운 행동을 추가하거나 오버라이드 할 수 있다.

  5. 파사드 패턴(Facade Pattern)
    : 많은 분량의 코드에 접근할 수 있는 단순한 인터페이스를 제공한다.

  6. 플라이웨이트 패턴(Flyweight Pattern)
    : 다수의 유사한 객체를 생성,조작 하는 비용을 절감할 수 있다.

  7. 프록시 패턴(Proxy Pattern)
    : 접근 조절, 비용 절감, 복잡도 감소를 위해 접근이 힘든 객체에 대한 대역을 제공한다.

어댑터 패턴(Adapter Pattern)

어댑터 패턴이란?

  • 호환성이 없는 인터페이스 때문에 함께 동작할 수 없는 클래스들이 함께 동작하도록 해주는 패턴.
  • 기존에 있는 시스템에 새로운 써드파티 라이브러리가 추가된다던지, 레거시 인터페이스를 새로운 인터페이스로
    교체하는 경우에 코드의 재사용성을 높일 수 있는 패턴.

어댑터 패턴의 구조

Adapter Pattern Structure

어댑터 패턴의 적용

  • 기존 클래스를 사용하고 싶지만 그 인터페이스가 나머지 코드와 호환되지 않을 때 사용.
    • 레거시 클래스, 타사 클래스 또는 특이한 인터페이스가 있는 다른 클래스 간의 변환기 역할을 하는 중간 레이어 클래스
  • 부모 클래스에 추가할 수 없는 어떤 공통 기능들이 없는 여러 기존 자식 클래스들을 재사용하려는 경우에 사용.
    • 데코레이터 패턴과 매우 유사.

어댑터 패턴의 장점

  • SRP. 프로그램의 기본 비즈니스 로직에서 인터페이스 또는 데이터 변환 코드를 분리할 수 있음.
  • OCP. 클라이언트 코드가 클라이언트 인터페이스를 통해 어댑터와 작동하는 한, 기존의 클라이언트 코드를 손상시키지 않고
    새로운 유형의 어댑터들을 도입할 수 있음.

브릿지 패턴(Bridge Pattern)

브릿지 패턴이란?

  • 구현부에서 추상층을 분리하여 각자 독립적으로 변형할 수 있게 하는 패턴.
  • 추상적 개념과 구체적 구현을 서로 다른 두개의 인터페이스로 구현하는 디자인 패턴이다.

브릿지 패턴의 구조

Bridge Pattern Structure

  • Abstraction
    : 기능 계층의 최상위 클래스이며 추상 인터페이스를 정의한다.
    Implementor에 대한 레퍼런스를 유지한다.
    구현 부분에 해당하는 클래스를 인스턴스를 가지고 해당 인스턴스를 통해 구현부분의 메서드를 호출한다.

  • RefinedAbstraction
    : Abstraction에 의해 정의된 인터페이스를 확장한다.(extends) 기능 계층에서 새로운 부분을 확장한 클래스이다.

  • Implementor
    : 구현 클래스를 위한 인터페이스를 정의한다. Abstraction의 기능을 구현하기 위한 인터페이스를 정의한다.

  • ConcreteImplementor
    : Implementor 인터페이스를 구현 즉, 실제 기능을 구현한다.

합성 패턴(Composite Pattern)

합성 패턴이란?

  • 객체들의 관계를 트리 구조로 구성하여 전체-부분 계층을 표현하는 패턴.
  • 여러 개의 객체들로 구성된 복합 객체와 단일 객체를 클라이언트에서 구별 없이 다루게 한다.
  • 전체-부분의 관계를 갖는 객체들 사이의 관계를 정의할 때 유용하다.
  • 클라이언트는 전체와 부분을 구분하지 않고 동일한 인터페이스를 사용할 수 있다.

합성 패턴의 구조

Composite Pattern Structure

  • Component
    : Leaf와 Composite를 같은 타임으로 취급하기 위한 인터페이스.
    Leaf 클래스와 전체에 해당하는 Composite 클래스에 공통 인터페이스를 정의한다.

  • Leaf
    : 구체적인 부분 클래스로 단일 객체를 표현한다. 트리구조로 따지면 가장 밑단에 존재하는 나뭇잎이다.

  • Composite
    : 복합 객체 그룹을 표현할 클래스로 전체 클래스이다. 자식으로 여러개의 Component 타입 멤버를 수용할 수 있도록 구현되어야 한다.

합성 패턴의 적용

  • 트리와 같은 객체 구조를 구현해야 할 때 사용.
  • 클라이언트 코드가 단순 요소들과 복합 요소들을 모두 균일하게 처리하고 싶을 때 사용.

데코레이터 패턴(Decorator Pattern)

데코레이터 패턴이란?

  • 객체의 결합을 통해 기능을 동적으로 유연하게 확장 할 수 있게 해주는 패턴.
  • 객체에 추가적인 요건을 동적으로 첨가하며 기능 확장이 필요할 때 서브클래싱 대신 쓸 수 있는 유연한 대안.
  • 기본 기능에 추가할 수 있는 기능의 종류가 많은 경우 각 추가 기능을 Decorator 클래스로 정의 한 후 필요한 Decorator 객체를
    조합함으로써 추가 기능의 조합을 설계 하는 방식.

데코레이터 패턴의 구조

Decorator Pattern Structure

  • Component
    : ConcreteComponent와 Decorator가 구현할 인터페이스. 두 객체를 동등하게 다루기 위해 존재.

  • ConcreteComponent
    : Decorate를 받을 객체. 기능 추가를 받을 기본 객체

  • Decorator
    : Decorate를 할 객체의 추상 클래스 or 인터페이스. 기능 추가를 할 객체는 이 객체를 상속받음.

  • ConcreteDecorator
    : Decorator를 상속받아 구현할 다양한 기능 객체. ConcreteComponent를 감싸는 용도.

데코레이터 패턴의 적용

  • 객체들을 사용하는 코드를 훼손하지 않으면서 런타임(동적)에 추가 행동들을 객체들에 할당해야 할 때 사용.
  • 상속을 사용하여 객체의 행동을 확장하는 것이 어색하거나 불가능할 때 사용

파사드 패턴(Facade Pattern)

파사드 패턴이란?

  • Facade(외관)는 건물의 정면을 의미하는 단어로 소프트웨어의 커다란 코드 부분에 대하여 간략화된 인터페이스를 제공해주는
    디자인 패턴이다.
  • 파사드 객체는 복잡한 소프트웨어 바깥쪽의 코드가 라이브러리의 안쪽 코드에 의존하는 일을 감소시켜 주고
    복잡한 소프트웨어를 사용 할 수 있게 간단한 인터페이스를 제공한다.

파사드 패턴의 구조

Facade Pattern Structure

  • Client
    : 클라이언트는 하위 시스템 객체들을 직접 호출하는 대신 파사드를 사용.

  • Facade
    : 클라이언트의 요청을 어디로 보내야 하는지와 움직이는 모든 부품을 어떻게 작동해야 하는지를 알고 있다.

  • Additional Facade
    : 하나의 파사드를 관련 없는 기능들로 오염시켜 복잡한 구조로 만드는 것을 방지할 수 있다.

  • Subsystem class
    : 하위 시스템 클래스들은 파사드의 존재를 인식하지 못한다.

파사드 패턴의 적용

  • 복잡한 하위 시스템에 대한 제한적이지만 간단한 인터페이스가 필요할 때 사용.
  • 하위 시스템을 계층들로 구성하려는 경우 사용.

플라이웨이트 패턴(Flyweight Pattern)

플라이웨이트 패턴이란?

  • 클래스의 인스턴스를 한 개만 가지고 여러 개의 가상 인스턴스를 제공하고 싶을 때 사용하는 패턴.
  • 인스턴스를 가능한 공유시켜 쓸데없이 new 연산자를 통한 메모리 낭비를 줄이는 방식.
  • 생성 된 객체 수를 줄이고 메모리 사용 공간을 줄여서 성능을 향상시키는데 사용한다.

플라이웨이트 패턴의 구조

Flyweight Pattern Structure

  • Flyweight
    : 공유에 사용할 클래스들의 인터페이스를 선언한다. 플라이웨이트 내부에 저장된 상태를 고유한(intrinsic) 상태라고 하며,
    플라이웨이트의 메서드에 전달된 상태를 공유한(extrinsic) 상태라고 한다. 여러 Context에서 사용될 수 있다.

  • Context
    : 공유한(extrinsic) 상태를 포함하며 모든 원본 객체들에서 고유(intrinsic)하다. 컨텍스트가 플라이웨이트 객체 중
    하나와 쌍을 이루면 원래 객체의 전체 상태를 나타낸다.

  • FlyweightFactory
    : 기존 플라이웨이트들의 풀을 관리한다. 클라이언트는 플라이웨이트를 직접 만들지 않고 원하는 플라이웨이트의 내부 상태의 일부를 전달하여
    팩토리를 호출한다.

플라이웨이트 패턴의 적용

  • 많은 수의 객체들을 지원해야 해서 사용할 수 있는 RAM을 거의 다 사용했을 때 사용.
  • 생성된 객체가 오래도록 메모리에 상주하며 사용되는 횟수가 많을 경우 사용.

프록시 패턴(Proxy Pattern)

프록시 패턴이란?

  • 실제 기능을 수행하는 객체(Real Object) 대신 가상의 객체(Proxy Object)를 사용해 로직의 흐름을 제어하는 디자인 패턴.
  • 프록시 패턴을 사용하는 경우는 어떤 클래스의 객체 생성이 오래 걸리는 경우 그 일을 분업하여 Proxy 클래스에서 처리 할 수 있는
    부분은 처리를 하고 처리할 수 없는 작업에 대해서만 실제 클래스의 객체를 생성하고 위임하는 방식을 취한다.
  • RealSubject가 원격 시스템에서 돌아가거나 그 객체의 생성 비용이 많이 들어 실제 사용 시점에 객체를 생성하거나 실제 객체에 접근을
    제한 및 제어를 해야 할 때 사용한다.

프록시 패턴의 구조

Proxy Pattern Structure

  • ServiceInterface
    : Proxy와 Service(RealSubject)가 구현해야하는 인터페이스. 두 객체를 동일하게 다루기 위해 존재

  • Proxy
    : RealSubject 와 클라이언트의 요청 사이에 존재하는 객체. ServiceInterface(Subject)를 구현함으로써 클라이언트는
    Proxy와 RealSubject의 차이를 모른다.

  • Service
    : 실질적으로 요청에 대해 주된 기능을 수행하는 객체(RealSubject). Proxy 객체는 내부적으로 이 객체를 로직에 맞게 사용한다.(위임)

프록시 패턴의 특징

  • 원래 하려던 기능을 수행하며 그 외의 부가적인 작업(로깅, 인증, 네트워크 통신 등)을 수행할 수 있다.
  • 비용이 많이 드는 연산(DB쿼리, 대용량 텍스트 파일 등)을 실제로 필요한 시점에 수행할 수 있다.
  • 실제 객체의 리소스가 무거운 경우, 프록시 객체에서 간단한 처리를 하거나 기본 객체를 캐싱 처리함으로써 부하를 줄일 수 있다.
  • 실제 객체에 대한 수정 없이 클라이언트에서의 사용과 기본 객체 사이의 일련의 로직을 프록시 객체를 통해 넣을 수 있다.
  • 프록시는 기본 객체와 요청 사이에 있기 때문에 일종의 보안 역할도 한다.
  • 사용자 입장에서는 프록시 객체나 실제 객체나 사용법이 유사함으로 구조나 코드 구현이 간단하다.

프록시 패턴의 종류

  • 원격 프록시: 원격 객체에 대한 접근 제어가 가능하다.
  • 가상 프록시: 객체의 생성비용이 많이 들어 미리 생성하기 힘든 객체에 대한 접근 및 생성시점 등을 제어한다.
  • 보호 프록시: 접근 권한을 제어해야하는 객체에 대한 접근을 제어한다.
  • 방화벽 프록시: 네트워크 자원에 대한 접근을 제어함으로써 '나쁜' 클라이언트들로부터 보호한다.
  • 스마트 레퍼런스 프록시: 주 객체가 참조될 때마다 추가 행동을 제공한다.
    • 객체 참조에 대한 선 작업, 후 작업 등
  • 캐싱 프록시: 비용이 많이 드는 작업의 결과를 임시로 저장하고, 추후 여러 클라이언트에 저장된 결과를 실제 작업처리 대신 보여주고 자원을 절약한다.
  • 동기화 프록시: 여러 스레드에서 주 객체에 접근하는 경우에 안전하게 작업을 처리한다.
  • 복잡도 숨김 프록시: 복잡한 클래스들의 집합에 대한 접근을 제어하고 복잡도를 숨긴다.
  • 지연 복사 프록시: 클라이언트에서 필요로 할 때까지 객체가 복사되는 것을 지연시킴으로써 객체의 복사를 제어한다.
profile
완벽하지 않기에 기록한다.

0개의 댓글