어뎁터 패턴

임종혁·2025년 1월 4일

객체지향 어댑터란


어떤 인터페이스를 클라이언트에서 요구하는 형태로 적응시키는 역할

ex)

interface Duck {
	public void quack();
	public void fly();

}
class MallardDuck implements Duck{

	@Override
	public void quack() {
		System.out.println("꽥");
		
	}

	@Override
	public void fly() {
		System.out.println("날고 있어요");
	}
	

}
interface Turkey {
	public void gobble();
	public void fly();
}
class WildTurkey implements Turkey{

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

	@Override
	public void fly() {
		System.out.println("짧은 거리를 날고 있어요");
		
	}
}
class TurkeyAdapter implements Duck {
	
	Turkey turkey;
	
	public TurkeyAdapter(Turkey turkey) {
		this.turkey = turkey;
	}

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

	@Override
	public void fly() {
		turkey.fly();
		
	}
}
class DuckTestDrive {
	
	public static void main(String[] args) {
		Duck duck = new MallardDuck();
		
		Turkey turkey = new WildTurkey();
		Duck turkeyAdapter = new TurkeyAdapter(turkey);
		
		System.out.println("칠면조가 말하길");
		turkey.getClass();
		turkey.fly();
		
		
		System.out.println("오리가 말하길");
		testDuck(duck);
		
		System.out.println("칠면조 어뎁터가 말하길");
		testDuck(turkeyAdapter);
	}
	
	
	static void testDuck(Duck duck) {
		duck.quack();
		duck.fly();
	}

}

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

  1. 클라이언트에서 타깃 인터페이스로 메소드를 호출해서 어댑터에 요청을 보낸다
  2. 어댑터는 어댑티 인터페이스로 그 요청을 어댑티에 관한 하나 이상의 메소드 호출로 변환한다
  3. 클라이언트는 호출 결과를 받긴 하지만 중간에 어댑터가 있다는 사실을 모른다.

어댑터 패턴의 정의

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

즉 호환되지 않는 인터페이스를 사용하는 클라이언트를 그대로 활용할 수 있다.

  • 타깃은 duck

  • adapter는 터키 어뎁터

  • adaptee는 터키

  • 어댑티를 새로 바뀐 인터페이스로 감쌀때 객체 구성을 사용

객체 어댑터와 클래스 어댑터

클래스 어댑터를 사용해야하면 다중상속이 필요
자바에서는 다중 상속이 불가능

(클래스 어뎁터)


퍼사드 패턴

  • 인터페이스를 단순하게 바꾸려고 인터페이스를 변경
  • 퍼사드는 인터페이스를 단순하게 만들고 클라이언트와 구성 요소로 이루어진 서브시스템을 분리하는 역할
  • 퍼사드와 어댑터 모두 여러개의 클래스를 감쌀수 있다
  • 퍼사드는 인터페이스를 단순하게 만드는 용도
  • 어댑터는 인터페이스를 다른 인터페이스로 변환하는 용도로 사용
public class HomeTheaterFacade {
	Amplifier amp;
    Tuner tuner;
    StreamingPlayer player;
    Projector projector;
    TheaterLights lights;
    Screan screan;
    PopcornPopper popper;
    
    public HomeTheaterFacade(Amplifier amp, 
    	Tuner tuner, 
        StreamingPlayer player;
        Projector projector,
        Screen screen,
        TheaterLights lights,
        PopcornPopper popper) {
       this.amp = amp;
       this.tuner = tuner;
       this.player = player;
       this.projector = projecter;
       this.screen = screen;
       this.light = lights;
       this.popper = popper;
     
        
        
        }
        
        // 기타 메소드 
        
   public void wathchMoving(String movie) {
   	System.out.println("영화볼 준비");
    popper.on();
    popper.pop();
    lights.dim(10);
    screen.down();
    projector.on();
    projector.wideScreenMode();
    amp.on();
    amp.setStreamingPlayer(player);
    amp.setSurroundSound();
    amp.setVolume(5);
    player.on();
    player.play(movie);
   }
   
   public void endMovie() {
   	System.out.println("홈시어터를 끄는중");
    popper.off();
    lights.on();
    screen.up();
    porojector.off();
    amp.off();
    player.stop();
    player.off();
    
   
   }

}


퍼사드 패턴 정의

서브시템에 있는 일련의 인터페이스를 통합 인터페이스로 묶어 줍니다. 도한 고수준 인터페이스도 정의하므로 서브시스템을 더 편리하게 사용할 수 있습니다.

최소 지식 원칙

  • 객체 사이의 상호작용은 될 수 있으면 아주 가까운 친구 사이에서만 허용하는 편이 좋다

원칙을 지키지 않는 경우

public float getTemp() {
	Thermometer thermometer = station.getThermometer();
    reutrn thermometer.getTemperature();

}

원칙을 지키는 경우

public float getTemp() {
	return station.getTemperature();

}

최소 지식 원칙 단점

  • 객체사이의 의존성을 줄일수 있으며 소프트웨어 관리가 더 편해ㅣ지지만 메소드 호출을 처리하는 래퍼 클래스를 더 만들어야 함 그러면 시스템이 복잡해지고 개발 시간도 늘어나고 성능도 떨어짐

0개의 댓글