
어댑터 패턴은 클래스를 바로 사용할 수 없는 경우에 유용하다. 예를 들어, 다른 곳에서 개발되었거나 수정할 수 없는 클래스를 사용할 때, 중간에서 변환 역할을 해주는 클래스가 필요하다. 어댑터 패턴은 이런 상황에서 호환되지 않은 인터페이스를 사용하는 클라이언트를 그대로 활용할 수 있게 해준다. 또한, 향후 인터페이스가 바뀌더라도 변경 내역은 어댑터에 캡슐화되므로 클라이언트 코드를 변경할 필요가 없다.

아이폰의 이어폰을 생각해보자. 일반적인 이어폰 잭을 아이폰에 사용하려면, 잭 자체가 맞지 않는다. 따라서 우리는 어댑터를 따로 구매해서 연결해야 이런 이어폰들을 사용할 수 있다. 이처럼 어댑터는 필요로 하는 인터페이스로 바꿔주는 역할을 한다.

이처럼 업체에서 제공한 클래스가 기존 시스템에 맞지 않으면, 기존 시스템을 수정할 것이 아니라 어댑터를 활용해 유연하게 해결할 수 있다.
만약 자동차 객체가 부족해서 보트 객체를 대신 사용해야 한다면, 두 객체는 인터페이스가 다르므로 바로 보트 객체를 사용하는 것은 불가능하다. 따라서 보트 어댑터를 생성해서 활용해야 한다.
package AdapterPattern;
public interface Car {
public void drive();
public void honk();
}
Car 인터페이스는 drive와 honk 메서드를 정의하고 있다. 이는 자동차의 기능을 나타낸다.package AdapterPattern;
public interface Boat {
public void sail();
public void soundHorn();
}
package AdapterPattern;
public class SpeedBoat implements Boat {
@Override
public void sail() {
System.out.println("The boat is sailing");
}
@Override
public void soundHorn() {
System.out.println("Boat horn sounds");
}
}
SpeedBoat 클래스는 Boat 인터페이스를 구현하며, sail과 soundHorn 메서드를 오버라이드하여 실제 보트의 동작을 정의하고 있다.package AdapterPattern;
public class BoatAdapter implements Car {
Boat boat;
public BoatAdapter(Boat boat) {
this.boat = boat;
}
@Override
public void drive() {
boat.sail();
}
@Override
public void honk() {
boat.soundHorn();
}
}
BoatAdapter 클래스는 Car 인터페이스를 구현하며, Boat 객체를 인스턴스 변수로 가진다.drive 메서드는 boat.sail()을 호출하여 보트의 sail 메서드를 실행하고, honk 메서드는 boat.soundHorn()을 호출하여 보트의 soundHorn 메서드를 실행한다.Boat 객체를 Car 객체처럼 사용할 수 있게 된다.package AdapterPattern;
public class AdapterTest {
public static void main(String[] args) {
SportsCar car = new SportsCar();
SpeedBoat boat = new SpeedBoat();
Car boatAdapter = new BoatAdapter(boat);
System.out.println("The boat says...");
boat.sail();
boat.soundHorn();
System.out.println("The Car says...");
testCar(car);
System.out.println("The BoatAdapter says...");
testCar(boatAdapter);
}
public static void testCar(Car car) {
car.drive();
car.honk();
}
}
AdapterTest 클래스는 main 메서드를 통해 어댑터 패턴을 테스트한다.SportsCar 객체와 SpeedBoat 객체를 생성하고, SpeedBoat 객체를 BoatAdapter로 감싸 Car 인터페이스로 변환한다.testCar 메서드는 Car 인터페이스를 인자로 받아 drive와 honk 메서드를 호출한다.Car 인터페이스를 구현함으로써, SpeedBoat 객체를 Car 객체처럼 사용할 수 있음을 보여준다.어댑터 패턴은 호환되지 않은 인터페이스를 사용하는 클래스를 변환하여 클라이언트가 사용할 수 있도록 해준다. 이를 통해 기존 시스템을 수정하지 않고도 새로운 클래스를 유연하게 통합할 수 있다. 어댑터 패턴은 특히 변경 가능한 인터페이스가 있을 때 유용하며, 클라이언트 코드의 안정성을 유지하면서도 다양한 클래스와의 통합을 가능하게 한다.