✍️ 어댑터 패턴, 패턴 소개
어댑터 패턴은 일상생활에서도 흔히 찾아볼 수 있는데, 220V 코드를 110V 콘센트에 꽂을 때 흔히 돼지코라고 불리는 어댑터를 사용해 본 경험이 있을 것이다. 바로 이 돼지코가 어댑터 패턴과 유사한 실생활 사례라고 할 수 있다.
이제 소프트웨어적 측면에서 어댑터 패턴을 설명하면, Client가 사용하는 Interface는 정해져있는데 내가 작성한 코드(Adaptee)는 해당 Interface를 따르지 않을 때 Client와 Adaptee 사이의 간극을 Adapter로 메꿔서 Adaptee를 재사용할 수 있도록 하는 패턴이다.
정리하면 '기존 코드를 클라이언트가 사용하는 인터페이스의 구현체로 바꿔주는 패턴이다.'
언제나 그렇듯... 말로는 너무 어렵다 코드를 보자.
🍊 어댑터 패턴, 적용 전 코드
코드를 살펴보기 전에, UserDetails, UserDetailsService, LoginHandler는 security 패키지에서 제공하는 코드로 라이브러리 코드라고 생각해도 좋다.
여기, 유저의 이름과 패스워드를 반환하는 메서드를 추상화한 UserDetails 인터페이스가 있고
public interface UserDetails {
String getUsername();
String getPassword();
}
username을 받아서 UserDetails를 반환하는 메서드를 추상화한 UserDetailsService 인터페이스가 있다.
public interface UserDetailsService {
UserDetails loadUser(String username);
}
그리고 UserDetails와 UserDetailsService를 사용해서 Login을 처리하는 LoginHandler가 있다.
login 메서드는 굉장히 간단한데, UserDetailsService에서 username으로 읽어와서 UserDetails의 패스워드가 일치한지 판단해서 로그인을 처리한다.
public class LoginHandler {
private UserDetailsService userDetailsService;
public LoginHandler(UserDetailsService userDetailsService){
this.userDetailsService = userDetailsService;
}
public String login(String username, String password){
UserDetails userDetails = userDetailsService.loadUser(username);
if(userDetails.getPassword().equals(password)){
return userDetails.getUsername();
}else{
throw new RuntimeException();
}
}
}
Account 클래스는 일반적으로 우리가 애플리케이션을 만들 때 유저 정보를 담는 클래스라고 생각하면 된다.
@Data
public class Account {
private String name;
private String password;
private String email;
}
public class AccountService {
public Account findAccountByUsername(String username){
Account account = new Account();
account.setName(username);
account.setPassword(username);
account.setEmail(username);
return account;
}
public Account createNewAccount(String username){
// TODO, blah blah blah
return new Account();
}
}
다시 말하지만 UserDetails, UserDetailsService, LoginHandler는 security 패키지에서 제공하는 코드로 다른 애플리케이션에서도 공통으로 사용하는 일종의 라이브러리 코드고, Account와 AccountService는 애플리케이션에 구현이 따라 달라지는 코드로 이 둘의 직접적인 관계는 없다.
어찌 됐든, security 패키지가 제공하는 login 기능을 우리가 정의한 Account와 AccountService를 가지고도 돌아가도록 만드는 것이 목적이다.
✨ 어댑터 패턴, 코드 정리
그림과 함께 정리해 보자.
security 패키지가 제공하는 login 로직은 Client에 해당한다.
Client는 UserDetails와 UserDetailsService라는 정해진 인터페이스(Target)를 사용한다.
애플리케이션에서 정의한 Account와 AccountService는 Adaptee에 해당한다.
지금까지의 코드에서 비어있는 건 바로 Adapter로 Client와 Adaptee의 간극을 Adpater를 추가해서 메꿔줄 수 있다!
적용 코드는 다음 포스팅에서...
인프런의 백기선님의 강의 코딩으로 학습하는 GoF의 디자인 패턴을 참고해서 작성했습니다.
'Java > Design Pattern with Java' 카테고리의 다른 글
[구조 패턴] Chapter 7. Bridge Pattern (0) | 2023.11.12 |
---|---|
[구조 패턴] Chapter 6-2. Adapter Pattern : 패턴 적용하기 (0) | 2022.06.13 |
[객체 생성 패턴] Chapter 5-4. Prototype Pattern : Java에서 찾아보는 프로토타입 패턴 (0) | 2022.06.04 |
[객체 생성 패턴] Chapter 5-3. Prototype Pattern : 장단점 (0) | 2022.05.30 |
[객체 생성 패턴] Chapter 5-2. Prototype Pattern : 패턴 적용하기 (0) | 2022.05.30 |