dev/🧩 디자인패턴

어댑터 패턴이란? (Adapter Pattern)

wugawuga 2022. 11. 15. 20:37

어댑터 패턴이란?

특정 인터페이스를 클라이언트에서 요구하는 다른 인터페이스로 변환
호환되지 않아서 쓸 수 없던 클래스 사용가능

 

예제 코드를 보면서 얘기하자

public class Test {
    public static void main(String[] args) {
        Animal cat = new Cat();
        Animal dog = new Dog();

        DoorMan man = new DoorMan();
        man.쫓아내(cat);
        man.쫓아내(dog);
    }
}
-----------------------------------------
고양이 쫓아내
강아지 쫓아내

public interface Animal {
    String getName();
}

public class Cat implements Animal {
    private final String name = "고양이";

    @Override
    public String getName() {
        return name;
    }
}

public class Dog implements Animal {
    private final String name = "강아지";

    @Override
    public String getName() {
        return name;
    }
}

public class DoorMan {
    public void 쫓아내(Animal animal) {
        System.out.println(animal.getName() + " 쫓아내");
    }
}

Cat, Dog 클래스는 Animal 인터페이스를 구현하고 있다

 

이때 문지기는 쫓아내 메소드를 수행하면서 강아지와 고양이를 내쫓고 있는데

사람만 들여보내고 싶을 때, 예를 들어 로봇호랑이가 있다고 가정을 하자

 

public class RobotTiger {
    private final String name = "로봇호랑이";

    public String getName() {
        return name;
    }
}

public class Test {
    public static void main(String[] args) {
        Animal cat = new Cat();
        Animal dog = new Dog();

        DoorMan man = new DoorMan();
        man.쫓아내(cat);
        man.쫓아내(dog);

        RobotTiger robotTiger = new RobotTiger();
        man.쫓아내(robotTiger);
    }
}

로봇호랑이가 왔을 때도 내보내고 싶지만 Animal 타입이 아니기 때문에 에러발생

이때 어댑터 패턴을 적절히 사용할 수 있다

 

public class RobotAdapter implements Animal {
    private final RobotTiger robotTiger;

    public RobotAdapter(RobotTiger robotTiger) {
        this.robotTiger = robotTiger;
    }

    @Override
    public String getName() {
        return robotTiger.getName();
    }
}

public class Test {
    public static void main(String[] args) {
        Animal cat = new Cat();
        Animal dog = new Dog();

        DoorMan man = new DoorMan();
        man.쫓아내(cat);
        man.쫓아내(dog);

        // Animal 타입이 아니기 때문에 에러발생
        RobotTiger robotTiger = new RobotTiger();
//        man.쫓아내(robotTiger);

        // 이때 어댑터 패턴 적용
        RobotAdapter adapter = new RobotAdapter(robotTiger);
        man.쫓아내(adapter);
    }
}
-----------------------------------------
고양이 쫓아내
강아지 쫓아내
로봇호랑이 쫓아내

물론 어댑터 패턴 적용을 위한 클래스를 만들지 말고 RobotTiger 클래스에서 Animal 을 구현하면 되지 않는 것인가!!

이런 고민을 했지만

이는 OCP 원칙을 지키지 못하는 것이기에 고치는 건 옳지 않다고 보고 있다

 

RobotTiger 가 Robot 인터페이스를 구현하고 어댑터에서 인터페이스 끼리 연결을 시켜 줄 수도 있다

 

public class RobotAdapter implements Animal {
    private final Robot robot;

    public RobotAdapter(Robot robot) {
        this.robot = robot;
    }

    @Override
    public String getName() {
        return robot.getModelName();
    }
}

public interface Robot {
    String getModelName();
}

public class RobotTiger implements Robot {
    private final String name = "로봇호랑이";

    @Override
    public String getModelName() {
        return name;
    }
}