Dev/디자인패턴

[타입스크립트로 살펴보는 디자인패턴 7] 어댑터 패턴

싯벨트 2024. 12. 29. 00:01
728x90

🙋‍♂️ 디자인패턴 구현코드 깃헙

어댑터 패턴(Adapter Pattern)

어댑터 패턴은 특정 클래스 인터페이스를 클라이언트에서 요구하는 다른 인터페이스로 변환한다.
인터페이스가 호환되지 않아 같이 쓸 수 없었던 클래스를 사용할 수 있게 도와준다.

일본 여행을 갈 때, 110v 어댑터를 챙겨가야 충전기 등을 사용할 수 있다. 어댑터 패턴은 정확하게 이런 역할을 한다. 인터페이스를 변환해주는 어댑터를 통해, 호환되지 않는 인터페이스를 사용하는 클라이언트를 그대로 활용할 수 있다. 또한, 변경 내역이 어댑터에 캡슐화되기 때문에 추후 인터페이스에 변경이 생기더라도 클라이언트를 바꿀 필요가 없다.

객체 어댑터 클래스 다이어그램

어댑터는 어댑티로 구성되어 있다. 즉, 어댑터에서 어댑티를 감쌀 때는 객체 구성(composition)을 사용한다. 그렇기 때문에 어댑티의 모든 서브클래스에 어댑터를 사용할 수 있다.

어댑터 패턴은 객체 어댑터와 클래스 어댑터 두 종류가 있다. 앞서 살펴본 다이어그램은 객체 어댑터이고, 클래스 어댑터는 아래와 같다. 클래스 어댑터는 다중상속이 가능한 언어에서 사용 가능하며 어댑터가 타겟과 어댑티 모두 서브클래스로 만들어서 사용한다.

클래스 어댑터 클래스 다이어그램

 

칠면조 어댑터를 통해 오리로 표현하기

코드

duck.ts

칠면조 어댑터가 구현할 타겟 인터페이스다.

export interface Duck {
    quack(): void;
    fly(): void;
}

turkey.ts

export interface Turkey {
    gobble(): void;
    fly(): void;
}

turkey.adapter.ts

타겟 인터페이스인 Duck을 구현했다. 기존 형식인 Turkey을 객체 구성을 사용해서 참조했다.

import { Duck } from "./duck";
import { Turkey } from "./turkey";

export class TurkeyAdapter implements Duck {
    constructor(private turkey: Turkey) {}

    quack(): void {
        this.turkey.gobble();
    }

    fly(): void {
        for (let i = 0; i < 5; i++) {
            this.turkey.fly();
        }
    }
}

duck.test.drive.ts

오리를 테스트하는 testDuck() 메서드에 칠면조 어댑터를 넣으면 정상적으로 동작한다.

import { Duck } from "./duck";
import { MallardDuck } from "./mallard.duck";
import { Turkey } from "./turkey";
import { TurkeyAdapter } from "./turkey.adapter";
import { WildTurkey } from "./wild.turkey";

class DuckTestDirve {
    duck: Duck = new MallardDuck();
    turkey: Turkey = new WildTurkey();
    turkeyAdapter: Duck = new TurkeyAdapter(this.turkey);

    test(): void {
        console.log("칠면조가 말하길");
        this.turkey.gobble();
        this.turkey.fly();

        console.log("\n오리가 말하길");
        this.testDuck(this.duck);

        console.log("\n칠면조 어댑터가가 말하길");
        this.testDuck(this.turkeyAdapter);
    }

    private testDuck(duck: Duck): void {
        duck.quack();
        duck.fly();
    }
}

new DuckTestDirve().test();

테스트 출력값

 

참고문서

헤드퍼스트 디자인패턴, 한빛미디어