rainsister
  • 신비한 비 Blog
  • Design Pattern
    • Adapter Pattern
    • Proxy Pattern
    • Mediator Pattern
    • Visitor Pattern
    • State Pattern
    • Memento Pattern
    • Factory Pattern
    • Template Pattern
    • Strategy Pattern
    • Bridge Pattern
  • springboot 2.x
    • 메시징 - 큐
      • RabbitMQ 기본설정
      • RabbitMQ 지연 큐(delayed queue)
    • Log
      • 기본 Log 설정 및 Logback 설정
      • Log4j2 사용해보기
      • tinylog 모듈 사용해보기
    • 기타 Database 에 대한 기본가이드
      • PostgreSQL
      • InfluxDB
      • MongoDB
    • 수행속도 UP! 각종 cache 어노테이션 사용법
      • Redis를 사용하여 Cache 관리하기
      • EhCache 사용해보기
      • Thread내캐쉬사용 및 Cache 어노테이션 사용법
    • Database Connection
      • Springboot 2.5 이후 data init script 초기화에 대한 변경
      • JTA 로 JPA 다중 DataSource 트랜잭션 처리 하기
      • Flyway 로 DataBase 형상 관리해보자
      • 트랜잭션 기초읽기
      • MyBatis 의 다중 DataSource
      • Spring Data JPA 다중 DataSource
      • JdbcTemplate 다중 DataSource
      • XML 로 Mybatis 설정하기
      • Mybatis 로 Mysql 연결하기
      • ORM(Spring data jpa)
      • Druid datasource 연결
      • Hikari 설정
      • JdbcTemplate 로 db 접근
    • rest api
      • XML에 대한 요청 및 응답 처리
      • SpringFox 3 및 Swagger 설정
      • 프로젝트 구동 시 RequestMappingHandler 로그 설정
      • Swagger 의 api들을 분류하는 법
      • 간단한 Restful API 만들고 테스트 코드 작성
      • Swagger2 구성하여 API 문서 자동화하기
      • JSR-303 그리고 validation
    • 설정
      • 시작
      • 멀티환경구성에 대한 새로운 방법
      • 멀티환경구성에 대한 새로운 include
      • 프로젝트 설정파일
      • 민감한 정보에 대한 암호화
  • java버전별차이
    • JAVA18
    • JAVA9
    • JAVA10
    • JAVA11
    • JAVA14
    • JAVA15
    • JAVA17
    • JAVA16
  • spring노하우
    • BeanUtils 권장하지 않는이유
    • 개인정보 암호화
    • Springboot 3가지 CROS 설정
    • Springboot 내장된 유용한 Utils
    • Spring Security WebSecurityConfigurerAdapter 가 deprecated 된 이슈해결하기
    • 아직도 HttpUtil ? SpringBoot 3.0의 HTTP Client Util 을 사용해보라
    • JDBC 소스를 뽀개기
    • spring-boot-configuration-processor 는 뭐하는놈임?
    • Apache BeanUtils vs Spring BeanUtils 성능비교
  • Effetive Java 3th
    • Finalizer & Cleaner
Powered by GitBook
On this page
  • 정의
  • UML
  • 역할
  • 장단점
  • Class Adapter
  • Object Adapter
  • Interface Adapter
  • 데모
  1. Design Pattern

Adapter Pattern

PreviousDesign PatternNextProxy Pattern

Last updated 8 months ago

정의

구조 모델 중 하나는 한 클래스의 인터페이스를 고객이 원하는 다른 인터페이스로 변환하는 것.Adapter 모드는 인터페이스가 호환되지 않아 함께 작업할 수 없었던 어떤 클래스가 함께 작업할 수 있도록 함.

UML

역할

  • Target : 다른 클래스를 어떤 인터페이스로 변환할지 정의합니다. 즉, 우리가 원하는 인터페이스입니다.

  • Adaptee : 무엇을 Target 으로 전환 할지 , 여기서 "무엇"이 바로 Adaptee 임. 이미존재 하고 잘 돌아가는 소스(클래스 혹은 메서드, 객체)임.

  • Adapter : 해당 패던의 핵심역할, Target , Adaptee 는 이미 존재하는 기존 소스이지만 Adapter는 새로 만드려는 그러니까 만들어야 하는 놈. 역할은 아주 간단함( 바로 extends 혹은 기타 클래스 관련 방식으로 Adaptee -> Target 으로 전환한다.

장단점

Class Adapter

  • 장점: Adaptee 클래스를 필요에 따라 다시 쓸 수 있는 방법은 Adapter의 유연성을 향상.

  • 단점: 한계가 있다.클래스 어댑터는 Target 클래스를 상속해야 하고 자바는 단일 상속만 지원하므로 Adaptee 클래스는 인터페이스여야 함.

Object Adapter

  • 장점: 동일한 Adapter가 Adaptee 클래스와 그 하위 클래스를 모두 대상 인터페이스에 적응할 수 있음.

  • 단점: Adaptee의 동작을 재정의해야 하는 경우 Adaptee의 하위 클래스를 재정의하고 어댑터를 결합해야 합니다.

Interface Adapter

  • 장점 : 유연하고 편리한 선택적 재작성 인터페이스 방법이 가능.

  • 단점: 익명 내부 클래스 형식이기 때문에 코드 다중화에 도움이 되지 않음.

데모

이해를 돕기위해 아래와 같은 사례가 있다고 가정한다. 우리가 타국으로 여행을 가서 숙소에 체크인하고 방으로 들어갔는데 전원코드가 한국식 아닌 모드 유럽식이다...뭐 이때 한국식 어댑터를 사용할수 없으니 미리? 챙겨간 어댑터를 쓰거나 혹은 카운터에 요구하면된다. 대충 직감이 올것이다. 어떤 내용을 얘기하려고 하는지, 왜냐? 우리는 똑똑한 개발자니까!

Target

@AllArgsConstructor
@Data
public class KoreanStandard {
    public String getKoreanStandard() {
        return "KoreanAdapter";
    }
}

Adaptee

public interface BritishStandard {
    String getBritishStandard();
}

Adapter

public class StandardAdapter extends KoreanStandard implements BritishStandard {
    @Override
    public String getBritishStandard() {
        return this.getKoreanStandard();
    }
}

LapTop Client

public class LapTop {
    public void charge(BritishStandard britishStandard) {
        if ("KoreanAdapter".equals(britishStandard.getBritishStandard())) {
            System.out.println("충전시작합니다!");
        } else {
            System.out.println("충전실패!");
        }
    }
}

Test

public class AdapterTest {
    public static void main(String[] args) {
        // 충전중!
        new LapTop().charge(new StandardAdapter());
    }
}

조금더 유연하게 대응하기 위해서 아래와 같이 소스를 수정한다.

@AllArgsConstructor
public class StandardAdapter implements BritishStandard {
    private KoreanStandard koreanStandard;

    @Override
    public String getBritishStandard() {
        return koreanStandard.getKoreanStandard();
    }
}

테스트 코드 수정

public class AdapterTest {
    public static void main(String[] args) {
        // 충전중!
        new LapTop().charge(new StandardAdapter(new KoreanStandard()));
    }
}

한발 더 나아가서 우리는 실제 인터페이스 내의 모든 메서드를 구현할 필요없을때 우리는 interface 보다 추상 클래스를 사용해볼수 있다.

Adaptee

public interface BritishStandard {
    String getBritishStandard();

    String getTypeC();

    String getUSB();
}

그리고 나서 Adapter 도 아래와 같이 변경해 준다.

@AllArgsConstructor
public abstract class StandardAdapter extends KoreanStandard implements BritishStandard {

    @Override
    public String getBritishStandard() {
        return null;
    }

    @Override
    public String getTypeC() {
        return null;
    }

    @Override
    public String getUSB() {
        return null;
    }
}

테스트

public class AdapterTest {
    public static void main(String[] args) {
        StandardAdapter standardAdapter= new StandardAdapter() {
            @Override
            public String getBritishStandard() {
                return new KoreanStandard().getKoreanStandard();
            }
        };
        // 충전성공!
        new LapTop().charge(standardAdapter);
    }
}

끝!