Design Pattern, Adapter

2022. 1. 23. 17:55ETC/Design Patterns

 

Object, Class Structural Pattern

Adapter Pattern

 

-----------------    INDEX     -----------------

 

Adapter Pattern ?

Structure

Sample Code: Java

관련 패턴

 

----------------------------------------------

 

 

Convert the interface of a class into another interface clients expect.
Adapter lets classes work together that couldn't otherwise because of incompatible interfaces.


- GoF Design Patterns

 

 

어댑터 패턴은 클래스의 인터페이스를 클라이언트가 필요로 하는 다른 인터페이스로 변환합니다.

호환성이 없는 인터페이스 때문에 함께 동작할 수 없는 클래스들이 함께 작동할 수 있도록 해줍니다.

 

 

Adapter

해외 여행가보신 적있으신가요?

여행을 갈 때 필수품 중 하나가 어댑터입니다.

 

https://www.juniper.net/documentation/hardware/junos-srx/srx5000/srx5600-hwguide/ac-power-specs.html

 

각 나라마다 사용하는 콘센트의 규격과 파워가 다르기 때문에

여행하고자 하는 나라의 콘센트와 호환시키기 위해 어댑터가 필요합니다.

 

adapt가 "맞추다, 적응하다" 라는 의미가 있기 때문에

dapter자체는 어떤 것들을 맞춰줄 수 있는 것으로 예상할 수 있습니다.

 

위에서 말하는 어댑터adapter는, 다른 전기나 기계 장치를 서로 연결해서 작동할 수 있도록 만들어 주는 결합 도구입니다.

 

 

오늘 다룰 Adapter Pattern도 동일합니다. 

서로 다른 두 인터페이스를 호환시켜주기 위한 중개 역할을 해줍니다.

 

개발을 하면서 인터페이스의 차이가 있다면 기존 코드를 사용할 수 없습니다.

하지만, 인터페이스가 일치하지 않는 문제는 협업을 하면서 여러 개발자들 사이에서든 외부 요인에 따라 어디서든 발생할 수 있죠.

이런 문제로 등장한 것이 바로 어댑터 패턴입니다.

 

 

어댑터 패턴은 다른 말로 래퍼 패턴wrapper pattern 이라고 하는데, 기존의 클래스를 새로운 클래스로 감싸는 기법입니다.

기존의 기능은 유지하면서 변경된 추가 코드를 삽입 래퍼 처리된 객체를 어댑터라고 합니다.

 

✔️ Adapter : 변환을 처리하는 객체

✔️ Adaptee : 변환을 받아 사용하는 객체

 

 

 

Structure

 

어댑터는 생성 scope에 따라 Class Adapter와 Object Adapter가 있습니다.

 

참고로 Scope는 Class와 Object로 나눌 수 있는데, 해당하는 구조 패턴의 특징은 아래와 같습니다.

Class Structural Scope는 상속을 통해 클래스들을 구성compose합니다.

Object Structural Scope는 객체를 조립assemble하는 방법에 대해 다룹니다.

 

 

Class Adapter

 

 

 

Class Adapter에서는 다중 상속을 통한 연결을 합니다.

위의 그림에서 볼 수 있듯이 Adapter가 Target과 Adaptee를 상속받아

Target의 request를 사용하는 것처럼 Adapter의 request를 사용하게 되면 내부 Adaptee의 specificRequest가 실행됩니다.

 

 

Object Adapter

 

 

 

Object Adapter는 구성을 통해 연결합니다.

Target을 상속받아 Adaptee를 속성으로 가져서 Request를 실행시키면 specificRequest가 실행됩니다.

 

 

 

 

둘은 굉장히 닮아 있는데요.

유일한 차이점은 Class Adapter의 경우 Target과 Adaptee의 subclass로 구성하고,

Object Adapter의 경우 composition을 사용하여 Adaptee에게 요청을 전달한다는 것입니다.

 

 

다중 상속

Class Adapter는 다중상속을 사용합니다.

다중 상속은 객체 지향 프로그래밍의 특징 중 하나이며, 둘 이상의 상위 클래스로부터 상속받는 것을 의미합니다.

 

다중 상속 기능을 모든 언어가 지원하는 것은 아닙니다.

메서드 충돌이 발생하며,  2개 이상의 클래스에서 동일한 메서드 명을 사용할 경우 어느 것을 기준으로 해야하는지 판단할 수 없다는 단점으로 지원하지 않는 언어들이 있는데요.

지원 여부를 기준으로 아래와 같이 구분할 수 있습니다. 

 

다중 상속을 지원하는 언어 :  C++, CommonLisp, Perl 6, 파이썬 등

다중 상속을 지원하지 않는 언어: Java, Ruby, Objective-C 등

 

 

Sample Code: Java

실제 예제로 Enumeration 과 Iterator 의 차이로 예시를 들어볼게요.

Enumeration과 Iterator은 자바에서 제공하는 컬렉션에 대해 각 컬렉션의 항목들을 순차적으로 접근하는데 사용합니다.

쉽게 말해 묶어놓은 그룹을 하나씩 순회할 때 사용합니다.

 

 

Enumeration interface는 hasMoreElements, nextElement라는 메서드를 가지고 항목에 접근합니다.

 

 

 

 

Iterator interface는 hasNext, next, remove라는 메서드를 가지고 항목에 접근합니다.

 

둘의 역할은 거의 동일합니다. Iterator는 이름도 간결하고 역할에 직관적이죠.

실제로, Enumeration은 자바 초기 버전에 나오고 Iterator은 그 이후에 나왔습니다.

 

실제 코드를 보며 살펴보겠습니다.

 

 

Adaptee - Enumeration (from)

Target    - Iterator (to)

Adapter - EnumerationIterator

 

 

Target

public interface Iterator<E> {

    boolean hasNext();

    E next();

    default void remove() {
        throw new UnsupportedOperationException("remove");
    }
    
    default void forEachRemaining(Consumer<? super E> action) {
        Objects.requireNonNull(action);
        while (hasNext())
            action.accept(next());
    }
}

 

 

Adaptee

public interface Enumeration<E> {

    boolean hasMoreElements();

    E nextElement();

    default Iterator<E> asIterator() {
        return new Iterator<>() {
            @Override public boolean hasNext() {
                return hasMoreElements();
            }
            @Override public E next() {
                return nextElement();
            }
        };
    }
}

 

 

Enumeration라는 인터페이스를 다른 인터페이스인 Iterator로 변경하는 작업을 한다고 할 때 어떻게 할지 생각해봅시다.

호환성이 없는 두 개체를 연결하는 일에 대해 감이 오시나요?

 

먼저 Class Adapter Pattern으로 적용해볼게요.

 

 

 

 

Adapter - Class 

먼저, EnumberationIterator(Adapter)는 Iterator(Target), Enumeration(Adaptee) 에게 다중 상속받습니다.

(자바에서는 인터페이스의 다중상속만 가능합니다. )

 

public class EnumerationIterator implements Iterator, Enumeration {
    
//    Enumeration method

    @Override
    public boolean hasMoreElements() {
        /* logic */
    }

    @Override
    public Object nextElement() {
        /* logic */
    }
    
    
//    Iterator method

    @Override
    public boolean hasNext() {
        return this.hasMoreElements();
    }

    @Override
    public Object next() {
        return this.nextElement();
    }

}

 

 

위와 같이 다중상속을 통해 Target의 기능 처럼 사용하여도 내부적으로 Adaptee의 기능을 실행하기 때문에

Target를 사용하는 것처럼 Adaptee를 사용할 수 있게된 것입니다.

 

 

 

 

Adapter - Object

이번에는 Object Adapter Pattern을 확인해보도록 하겠습니다.

 

먼저, EnumberationIterator(Adapter) 는 Iterator(Target)에게 상속받으며

Enumeration(Adaptee)를 속성으로 갖는 복합객체입니다.

 

public class EnumerationIterator implements Iterator {
    Enumeration<String> adaptee;
    
    @Override
    public boolean hasNext() {
        return this.adaptee.hasMoreElements();
    }

    @Override
    public Object next() {
        return this.adaptee.nextElement();
    }
}

 

위와 같이 Target을 Interface를 상속받고, Enumeration을 가지는 구성으로 덮어씌웠습니다.

 

 

각 구성에 대한 이해가 되었다면 정리를 하면서 개념을 선명히 만들어 볼게요.

 

 

Target

클라이언트가 사용할 domain-specific interface를 정의합니다.

 

Client

Target Interface를 상속받은 개체를 사용합니다.

 

Adaptee

조정이 필요한 기존 인터페이스를 정의합니다.

 

Adapter

Adaptee Interface를 Target Interface에 맞춥니다.



 

 

관련 패턴

C- Creational Patterns  |  S - Structural Patterns  |  B - Behavioral Patterns

 

 

S: Facade

여러개의 인터페이스를 사용할 경우 퍼사드 패턴과 유사한 특성을 가집니다.

 

 

S: Bridge

브리지는 기능 계층과 구현 계층을 연결하는 패턴으로, 서로 다른 클래스 연결 문제를 해결하는 것이 유사합니다.

하지만 브리지 패턴은 추상 개념을 이용하여 코드를 분리하는 반면,

어댑터 패턴은 기존의 인터페이스를 변경하는 것을 목적으로 함.

 

 

S: Decorator

장식자 패턴는 인터페이스를 변경하지 않고 기능을 추가합니다.

어댑터는 새로운 기능을 추가하기 보다 변경된 인터페이스로 맞춰 전달하는 역할입니다.

하지만 장식자는 기존의 기능에 새로운 기능이 추가된 객체를 전달합니다.

장식자 패턴은 객체의 동적 확장 개념을 사용합니다.

 

 

 

 

 

 

그럼 지금까지 Adapter Pattern에 대해 알아보았습니다.

오타나 잘못된 내용이 있다면 댓글로 남겨주세요!

감사합니다 ☺️ 

 

 

 

모든 Design Patterns 모아보기

 

Design Patterns

안녕하세요. GoF 디자인 패턴을 정리하고자 합니다. 디자인 패턴은 일주일 전부터 공부를 시작했는데, 스스로 설명하듯 적는게 익히는데 도움이 클 것같아 정말 오랜만에 시리즈로 포스팅하려

gngsn.tistory.com

 

 

 

'ETC > Design Patterns' 카테고리의 다른 글

Design Pattern, Singleton  (0) 2022.01.26
Design Pattern, Mediator  (0) 2022.01.24
Design Pattern, Observer  (0) 2022.01.21
Design Pattern, Proxy  (0) 2022.01.12
Design Pattern, Abstract Factory  (0) 2022.01.05