본문 바로가기

소프트웨어 공학

(디자인 패턴) Adaptor 패턴

훈수/저작권 관련 지적 환영합니다 - 댓글 또는 audgnssweet@naver.com

 

Adaptor


프로그래머들이 가장 많이 사용하는 패턴 중 하나입니다.

 

1. 종류

- structural 패턴에 속합니다.

 

2. 사용 의도 (intent)

- 클래스의 인터페이스를 클라이언트가 기대하는 다른 인터페이스로 변환합니다. - 호환되지 않는 인터페이스가 함께 작동할 수 있습니다.

- 라이브러리를 사용하는데 내가 가진 인터페이스와 호환되지 않는다고 해서 라이브러리를 변경할 수는 없습니다. (외부 라이브러리는 보통 바이너리 형태로 제공)

- 우리가 가진 인터페이스를 바꾸는 것도 리스크가 큽니다 (많은 곳에서 해당 인터페이스를 사용하고 있을 수 있기 때문)

 

3. 장점

- 호환되지 않는 인터페이스와 협력하는 재사용 가능한 클래스를 만들 수 있습니다.

 

4. 사용 방식

- 두 가지 접근 방식이 있으나, 객체 어댑터에 대해서만 다루겠습니다.
• 클래스 어댑터

• 객체 어댑터

 

Object Adapter만 다루는 이유

 

class adapter에서는 adapter class가 target class와 adapter class를 모두 상속받습니다. 

Adapter가 Adaptee를 상속받는 것은 구현에서 편리할 수 있겠지만, 객체지향적 관점에서 상속관계가 명확하다고 하기 애매합니다.

그래서 Object Adapter를 사용하는 것을 권장합니다.

 

5. 구조도

 

출처: 학부 수업

object adapter 예제

client는 target만을 바라보고 호출하면, adapter가 내부적으로 adaptee를 호출합니다.

그래서 client는 adaptee가 호출된 것과 같은 효과를 볼 수 있습니다.

 

 

6. 구성요소

 

client - target을 사용하는 주체

target - domain-specific interface

adapter - 말 그대로 인터페이스를 adapt 해주는 것

adaptee - 사용해야 하나 호환되지 않는, 즉 adapt가 필요한 interface

 



 

내가 만든 예제


구성도

 

chef는 Cooker의 cookStreak()를 사용하지만, 내부적으로 CookerAdapter가 ExternalCooker의 cookStreakWell()를 호출하여 조금 다른 인터페이스를 맞춰주는 역할을 하고 있음을 확인할 수 있습니다.

 

 

코드

 

1. Chef

 

public class Chef {

    private final Cooker cooker;

    public Chef(Cooker cooker) {
        this.cooker = cooker;
    }

    public void cookSteak() {
        this.cooker.cookSteak();
    }

}

 

2. Cooker

 

public abstract class Cooker {

    public abstract void cookSteak();
}

 

3. CookerAdapter

 

public class CookerAdapter extends Cooker {

    private final ExternalCooker externalCooker;

    public CookerAdapter(ExternalCooker externalCooker) {
        this.externalCooker = externalCooker;
    }

    @Override
    public void cookSteak() {
        externalCooker.cookSteakWell(); // 내부적으로 external interface 호출
    }
}

 

4. 사용

 

        Cooker cooker = new CookerAdapter(new ExternalCookerImpl()); //Cooker를 구현한 Adapter를 주입받음
        Chef chef = new Chef(cooker);   //client는 Cooker만 바라봄
        chef.cookSteak();   //Cooker의 cookSteak를 호출했으나, ExternalCooker의 cookStreakWell이 호출

 

오늘은 Adapter Pattern에 대해 알아보았습니다.