안녕하세요. 살빼고싶은 개발자 진쓰입니다. 어댑터 패턴에 대해서 포스팅 시작하겠습니다.



- 의도

이미 제공되는 기능이 형태가 달라, 필요로하는 형태로 변경하고자 할 때 사용합니다.



- 활용

기존의 클래스를 사용해야 하나 인터페이스가 수정되어야 하는경우 사용합니다.  (인터페이스 수정은 지양해야됩니다.)


기존 라이브러리 모양을 달리하여 재사용하고자 할 경우 사용합니다. (라이브러리를 직접 수정할수는 없죠.)



역시 예제상황과 코드리뷰로 배워보도록 하겠습니다.



- 예제 상황

-LED Framework를 제공되어졌다. 

LED를 끄고 RGB 색상으로 켜고 하는 메소드들을 제공받았다.(Framework)

하지만, 우리하드웨어는 켜있는 상태에서 다른 색상을 켜면 색이 섞이는 현상이 생겨서, 무조건 한번 끄고 색상을 켜는 기능을 추가로 하고싶다.


Framework자체를 수정해버리면, 하드웨어가 바뀌면 또다시 Framework를 되돌려야 하는 부담감이 있다. 




- 코드리뷰


소스코드 구성




 ILedFramework.java

개발자가 제공받을 LedFramework.java 의 api를 추출하여 인터페이스를 생성했습니다. 

 public interface ILedFramework {

    //기존메소드, 기존의기능에서 수정할 메소드 구현, 완전 새로운 메소드 구현
    public void ledOff();
    public void ledOn(String color);    
    public void ledBlink(String color1);
}



 LedFramework.java

개발자가 받은 API입니다. 문제가 있죠?(색이 섞이는 현상코드로 구현되어있음)

 //adatee

public class LedFramework {
    public int state = 0;
    public String curColor;
    
    public void ledOn(String color){
       if(state==0){
           System.out.println("LED "+color+" ON");
           curColor=color;
           state=1;
       }
       else{
           if(curColor.equals(color)){
               System.out.println("LED "+color+" ON");
               state=1;
               return;
           }
           //색이 섞인 경우발생.
           
           if(color.equals("RED")){
               curColor=curColor+" RED";
               System.out.println("LED "+curColor+" ON");        
           }
           else if(color.equals("BLUE")){
               curColor=curColor+" BLUE";
               System.out.println("LED "+curColor+" ON");
           }
           else if(color.equals("GREEN")){
               curColor=curColor+" GREEN";
               System.out.println("LED "+curColor+" ON");    
           }   
           
       }
    }
    public void ledOff(){
       System.out.println("Led Off");   
       state = 0;
       curColor="";
    }
    
}



 LedFrameworkAdpater.java

1. LedframeWork는 implements 하였습니다. 

2. LedFramework(색이 섞이는 문제가 있는부분) 를 has a 관계로 가지고있습니다. 

3. ledOn을 보시면 기존의 ledOn을 호출하기전 ledOff를 먼저 호출하도록 수정하였습니다. 

4. ledBlink라는 새로운 기능을 추가하기도 했습니다.


 public class LedFrameworkAdpater implements ILedFramework{

    //1. 확장하려는 클래스를 멤버변수로 선언.
    public LedFramework led;
    //2. 생성자에서 생성.
    public LedFrameworkAdpater(){
       led = new LedFramework();
    }
    
    //3. 기존메소드, 기존의기능에서 수정할 메소드 구현, 완전 새로운 메소드 구현
    @Override
    public void ledOff() {
       led.ledOff();
    }
    @Override
    public void ledOn(String color) {
       ledOff();
       led.ledOn(color);
    }
    @Override
    public void ledBlink(String color1) {
       for(int i=0;i<10;i++){
           ledOff();
           led.ledOn(color1);
       }
    }
    
    
}



 Main.java

led프레임워크를 그대로 사용하는 경우와, 어댑터 패턴을 적용한 객체를 생성해서 사용하는 예제를 볼 수 있다. 

 public class Main {

    public static void main(String[] args) {
       // TODO Auto-generated method stub
       LedFramework led = new LedFramework();
       led.ledOn("RED");
       led.ledOff();
       led.ledOn("RED");
       led.ledOn("BLUE");
       led.ledOn("GREEN");
       led.ledOff();
       led.ledOn("GREEN");
       
       System.out.println("LED프레임워크 -> 어댑터 패턴 적용\n\n\n\n");
    
       ILedFramework newLed = new LedFrameworkAdpater();
       newLed.ledOff();
       newLed.ledOn("RED");
       newLed.ledOn("BLUE");
       newLed.ledOn("GREEN");
       newLed.ledBlink("GREEN");
    }
}



결과화면


Adpater패턴 적용 전 


 Red를 켜고 Blue를 켜버리면, Red와 Blue가 섞이게 된다.

 Adpater패턴 적용 후


색이 안섞이는것을 볼 수있다.

 


 



.


- UML

> UML 설명

ILedFramework 인터페이스로, 기존에 제공받은 LedFrameWork api와 더불어 유저가 추가하고싶은 ledBlink()메소드도 선언하였습니다.



LedFrameworkAdpater.java 는 ILedFramework를 implements하였으며 프레임워크(LedFramework)를 has a 관계로 가지고있습니다.

ledOn은 기존의 기능에 새로 추가된 내용을 덧 붙혔으며, ledBlink는 기존 LedFramework가 없는 기능입니다.


어댑터 패턴의 장점을 보실 수 있습니다.(플랫폼에 알맞게 수정, 확장)




- 정리

지금 포스팅된 어댑터 패턴은 Object Adapter 패턴입니다. 일반적으로 많이 사용됩니다.


오브젝트 어댑터 패턴을 사용하면, Adaptee 클래스의 하위 클래스에 대해서도 소스코드 변경없이, 이를 활용하여 새로운 기능 추가가 편리해집니다.




정독해주셔서 감사합니다.

항상 정성을 다해서 포스팅 하도록 하겠습니다 :)

+ Recent posts