본문 바로가기
Design Pattern/구조 패턴(Structural patterns)

Adapter Pattern, 어댑터 패턴

by codeyaki 2024. 2. 1.
반응형

어댑터 패턴이란?

어댑터 패턴이란, 디자인패턴 중 구조적 패턴으로 서로 호환되지 않는 인터페이스들을 기존의 코드를 변경하지 않고 연결할 수 있도록 변환하는 디자인패턴이다!

 

마치 평소에 220V 플러그를 사용하는 우리가 해외로 여행 갔을 때 110V 플러그 '어댑터'를 사용하는 것처럼 기존에 사용하던 것을 변경시키지 않고 어댑터만 추가하여 변경할 수 있도록 해주는 것이다.

 

왜 사용해야 하나요?

  • 기존 코드를 수정하지 않아 안정성을 유지할 수 있다
  • 기존 코드를 그대로 사용할 수 있기에 개발 시간을 단축할 수 있다
  • 서로 다른 클래스 간에 결합도를 줄여줄 수 있다

어떤 경우에 사용하나요?

  • 이미 존재하고 있는 클래스나 라이브러리를 수정하지 않고 새로운 시스템에서 사용해야 할 때 사용할 수 있다
  • 서로 다른 인터페이스를 가진 두 개의 클래스를 함께 사용해야 할 때 사용할 수 있다
  • 외부 라이브러리나 프레임워크를 현재 시스템에 통합해야 할 때 사용할 수 있다

문제점

  • 변환과정에서 오버헤드가 발생할 수 있다
  • 어댑터코드를 추가해야 하기 때문에 코드가 복잡해질 수 있다

 


 

구현 방법

1. 기존에 사용하던 클래스 RoundHole, RoundPeg

둥근 구멍에 맞는 둥근못은 정상적으로 사용할 수 있습니다.

package com.example.designpattern.stuctural.adapter.round;

public class RoundHole {
    private double radius;

    public RoundHole(double radius) {
        this.radius = radius;
    }

    public double getRadius() {
        return this.radius;
    }

    public boolean fits(RoundPeg peg) {
        boolean result;
        result = (this.getRadius() >= peg.getRadius());
        return result;
    }
}
package com.example.designpattern.stuctural.adapter.round;

public class RoundPeg {
    private double radius;

    public RoundPeg() {
    }

    public RoundPeg(double radius) {
        this.radius = radius;
    }

    public double getRadius() {
        return radius;
    }
}
package com.example.designpattern.stuctural.adapter;

import com.example.designpattern.stuctural.adapter.round.RoundHole;
import com.example.designpattern.stuctural.adapter.round.RoundPeg;

public class AdapterMain {
    public static void main(String[] args) {
        /* 둥근 못 -> 둥근 홀 */
        RoundHole roundHole = new RoundHole(5);
        RoundPeg roundPeg = new RoundPeg(5);
        if (roundHole.fits(roundPeg)) {
            System.out.println("잘 맞는다 ~~");
        }
    }
}

 

하지만 여기에 사각 못을 사용해야 한다면?

구멍과 못이 서로 호환되지 않게 된다. 하지만 현실에서는 사이즈만 맞는다면 사각못을 둥근 구멍에 박을 수 있다.

이를 해결하기 위해서 어댑터를 생성해 준다.

package com.example.designpattern.stuctural.adapter.adapters;

import com.example.designpattern.stuctural.adapter.round.RoundPeg;
import com.example.designpattern.stuctural.adapter.square.SquarePeg;

public class SquarePegAdapter extends RoundPeg {
    private SquarePeg peg;

    public SquarePegAdapter(SquarePeg peg){
        this.peg = peg;
    }

    @Override
    public double getRadius() {
        double result = (Math.sqrt(Math.pow((peg.getWidth() / 2), 2) * 2));
        return result;
    }
}

기존의 둥근 구멍에 사각못을 맞춰서 사각못의 대각선길이와 둥근 구멍의 지름을 비교해서 박을 수 있는지 확인하도록 만든다.

 

그럼 이제 문제없이 클라이언트는 사각 못을 사용할 수 있게 된다.

package com.example.designpattern.stuctural.adapter;

import com.example.designpattern.stuctural.adapter.adapters.SquarePegAdapter;
import com.example.designpattern.stuctural.adapter.round.RoundHole;
import com.example.designpattern.stuctural.adapter.round.RoundPeg;
import com.example.designpattern.stuctural.adapter.square.SquarePeg;

public class AdapterMain {
    public static void main(String[] args) {
        /* 둥근 못 -> 둥근 홀 */
        RoundHole roundHole = new RoundHole(5);
        RoundPeg roundPeg = new RoundPeg(5);
        if (roundHole.fits(roundPeg)) {
            System.out.println("잘 맞는다 ~~");
        }

        SquarePeg smallSquarePeg = new SquarePeg(2);
        SquarePeg largeSquarePeg = new SquarePeg(20);

        // boolean fits = roundHole.fits(smallSquarePeg); // 오류 발생 둥근 못만 넣을 수 있다.

        /* 어댑터를 이용해서 사각 못 -> 둥근 홀 */
        SquarePegAdapter smallSquarePegAdapter = new SquarePegAdapter(smallSquarePeg);
        SquarePegAdapter largeSquarePegAdapter = new SquarePegAdapter(largeSquarePeg);
        if (roundHole.fits(smallSquarePegAdapter)) {
            System.out.println("작은 사각못은 둥근 홀에 박을 수 있다.");
        }
        if (!roundHole.fits(largeSquarePegAdapter)) {
            System.out.println("큰 사각못은 둥근 홀에 박을 수 없다.");
        }

    }
}
반응형