어댑터 (Adapter) 패턴

Lee InnJie·2022년 8월 10일
0

Design Pattern

목록 보기
7/22

어댑터(Adapter) 패턴

클라이언트가 사용하는 인터페이스가 전혀 다르며 정해져 있고, 기존의 코드를 호환하여 재사용할 수 있도록 구현체로 변경해주는 패턴.
클라이언트는 타겟 인터페이스만으로 사용하고, 구현체를 담당하는 Adaptee와 타겟 사이의 Adapter를 활용한다.


ex) Security package

Security package는 다른 애플리케이션에서도 사용할 수 있지만, AccountService는 특정 애플리케이션에서만 사용한다. 즉, Security package타겟에 해당하며, Account와 관련한 특정 애플리케이션에서 사용하는 코드Adaptee에 해당한다. 따라서 두 코드들을 호환이 가능하도록 Adapter를 구현해야하 한다.

Code

public class LoginHandler {
	//target
	UserDetailService userDetailService;
    
    public LoginHandler(UserDetailService userDetailService) {
    	this.userDetailService = userDetailService;
    }
    
    public String login(String username, String password) {
    	//target
    	UserDetails userDetails = userDetailService.loadUser(username);
        
        if(userDetails.getPassword().equals(password)) {
        	return userDetails.getUsername();
        } else {
        	throw new IllegarArgumentException();
        }
    }
}

어댑터를 만드는 방법은 각 인터페이스 구성요소에 임의로 수정할 수 없는 상황에 대해 별도의 클래스를 구현하거나, 타겟 인터페이스를 상속하여 직접 구현하는 방법으로 구분할 수 있다.

직접 구현하는 어댑터
장점 : 새로운 클래스를 만들지 않아 코드의 복잡도를 줄일 수 있다.
단점 : 단일 체계의 원칙의 관점에서는 맞지 않고, 기존의 코드를 변경한다.


장단점

장점

  • 기존 코드를 변경하지 않고 원하는 인터페이스 구현체를 만들어 재사용할 수 있다.
  • 기존 코드의 일과 특정 인터페이스 구현체로 변환하는 작업을 각기 다른 클래스로 분리하여 관리할 수 있다. (단일 책임의 원칙)
  • Open-Closed Principal에 가까운 패턴이다.

단점

  • 새 클래스가 생겨 복잡도가 증가하여 경우에 따라서는 기존 코드가 해당 인터페이스를 구현하도록 수정하는 것이 좋은 선택이 될 수 있다.

적용

asList()

List<String> strings = Arrays.asList("a", "b", "c");

배열을 리스트로 변경하는 경우, 상이한 인터페이스를 변환하는 경우에 적용된다.

Collections.enumeration()

파라미터를 Collection으로 받으며 enumeration으로 변경하는 동작을 수행한다.

Enumeration<String> enmeration = Collections.enumeration(string);

Collections.list

ArrayList<String> list = Collections.list(enumeration);

FileInputStream

// String -> InputStream
// InputStream -> InputStreamReader
try (InputStream is = new FileInputStream("input.txt");
	InputStreamReader isr = new InputStreamReader(is);
    BufferedReader reader = new BufferedReader(isr)) {
    	while(reader.ready()) {
        	System.out.println(reader.readLine());
        }
    }catch(IOException e) {
    	throw new RuntimeException(e);
    }
}

Spring Security

예제와 비슷함

Spring MVC - Handler interface

@Controller
public class HelloController {
	@GetMapping("/hello")
    public String hello() {
    	return "hi";
    }
}

DispatcherServlet을 보면 Object 타입을 받아 Handler로 보내 요청을 처리하고, 모델과 View가 나오며 데이터를 넣어 렌더링을 한다.
Handler는 요청을 처리하며, 구성에 따라 다른 Handler Adapter를 사용하게 된다. Handler는 이벤트에 따라 다르게 처리하고, Handler Adaptersms 다양한 형태의 Handler를 지원할 수 있도록 Spring MVC가 고안한 interface이다.

profile
⌒_⌒

0개의 댓글