CS(Computer Science)/Design Pattern

어댑터 패턴

환성 2023. 1. 8. 22:36
728x90
코드를 재사용하기 위해 구조를 변경하는 패턴

 

  • 사용 방법 : 상속
  • 호환되지 않은 인터페이스를 사용하는 클라이언트 그대로 활용 가능
  • 향후 인터페이스가 바뀌더라도, 변경 내역은 어댑터에 캡슐화 되므로 클라이언트가 바뀔필요가 없다.
  • 기능상 문제없이 동작하는 코드가 단지 인터페이스 차이 때문에 사용할 수 없는 경우 많이 응용되는 패턴이다. 또한 기존 코드에 오류가 있거나 보정 작업이 필요한 경우에도 유용하다.

 

어댑터

  • 객체 어댑터, 클래스 어댑터
  • 클래스 어댑터 패턴 쓰려면 다중 상속이 필요, 자바에서는 다중 상속이 불가능
  • 밑 그림과 같이 클래스 어댑터에서는 어댑터를 만들 때 타겟과 어댑터 모두의 서브 클래스로 만들고,객체 어댑터 에서는 구성을 통해서 어댑티에 요청을 전달한다는 점을 제외하면 별다른 차이점이 없다.

 

클라이언트에서 어댑터를 사용하는 법

  1. 클라이언트에서 타겟 인터페이스를 사용하여 메소드를 호출함으로써 어댑터에 요청을 한다.
  2. 어댑터에서는 어댑티 인터페이스를 사용하여 그 요청을 어댑티 에 대한 하나 이상의 메소드를 호출로 변환한다.
  3. 클라이언트에서는 호출 결과를 받긴 하지만 중간에 어댑터가 껴 있는지는 전혀 알지 못한다.

 

클래스 어댑터

클래스 어댑터

객체 어댑터

객체 어댑터

 

 

코드로 이해하는 어댑터 패턴

오리와 칠면조 인터페이스 생성
만약 오리 객체가 부족해서 칠면조 객체를 대신 사용해야 한다면?
두 객체는 인터페이스가 다르므로, 바로 칠면조 객체를 사용하는 것은 불가능하다.
따라서 칠면조 어댑터를 생성해서 활용해야 한다.
//Duck.java
package AdapterPattern;

public interface Duck {
	public void quack();
	public void fly();
}
//Turkey.java
package AdapterPattern;

public interface Turkey {
	public void gobble();
	public void fly();
}
//WildTurkey.java
package AdapterPattern;

public class WildTurkey implements Turkey {

	@Override
	public void gobble() {
		System.out.println("Gobble gobble");
	}

	@Override
	public void fly() {
		System.out.println("I'm flying a short distance");
	}
}
//TurkeyAdapter.java
package AdapterPattern;

public class TurkeyAdapter implements Duck {

	Turkey turkey;

	public TurkeyAdapter(Turkey turkey) { //Adapter 정의
		this.turkey = turkey;
	}

	@Override
	public void quack() {
		turkey.gobble();
	}

	@Override
	public void fly() {
		turkey.fly();
	}

}
//DuckTest.java
package AdapterPattern;

public class DuckTest {

	public static void main(String[] args) {

		MallardDuck duck = new MallardDuck();
		WildTurkey turkey = new WildTurkey();
		Duck turkeyAdapter = new TurkeyAdapter(turkey);

		System.out.println("The turkey says...");
		turkey.gobble();
		turkey.fly();

		System.out.println("The Duck says...");
		testDuck(duck);

		System.out.println("The TurkeyAdapter says...");
		testDuck(turkeyAdapter);

	}

	public static void testDuck(Duck duck) {

		duck.quack();
		duck.fly();

	}
}

 

장점

  • 기존 클래스를 감싼 새로운 클래스를 생성하고 객체의 인터페이스를 재구성한다.
  • 객체를 구성으로 결합하면 느슨한 연결 방식으로보다 많은 유연성을 확보할 수 있다.
  • 복잡한 객체 구조를 깔끔하게 정리하는 데 유용하다.

 

단점

  • 어댑터는 클라이언트에서 사용하는 인터페이스 방식으로 메소드를 새로 생성한다. 
  • 어댑터가 새로운 메소드를 재구성할 때 추가 코드가 필요하다.
  • 프로젝트에서 어댑터 패턴을 적용한다고 코드의 성능이 개선되지 않는다. 

 

출처 :

https://gyoogle.dev/blog/design-pattern/Adapter%20Pattern.html

'CS(Computer Science) > Design Pattern' 카테고리의 다른 글

옵저버 패턴  (4) 2023.01.12
팩토리 메소드 패턴  (0) 2023.01.09
템플릿 메소드 패턴  (0) 2023.01.09
싱글톤 패턴  (0) 2023.01.08