반응형
목차
어떤 상황에서 쓰일까?
항상 나오는 예시.. 한국 전기제품 220V와 미국 전기제품 110V 사이에 꽂아서 전압을 맞추어주는 것을 어댑터라고한다!
소프트웨어에서도 동일하게, 서로 다른 인터페이스를 맞추어서 사용할 수 있게 해준다.
어댑터 패턴이란?
규격에 맞지 않는 객체를
클라이언트가 사용하는 인터페이스의 구현체로 바꾸어주는 패턴이다.
장점
- 기존 코드(Account)를 변경하지 않고 원하는 인터페이스 구현체(AccountUserDetails)를 만들어 재사용할 수 있다.
단점
- 새 클래스(AccountUserDetails)가 생겨 복잡도가 증가할 수 있다.
구현방법
기존코드
Security에서 제공하는 LoginHandler. Security 패키지에 있는 코드는 건드릴 수 없다고 가정한다!!!
public interface UserDetails {
String getUsername();
String getPassword();
}
public interface UserDetailsService {
UserDetails loadUser(String username);
}
public class LoginHandler {
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 IllegalArgumentException();
}
}
}
우리가 만든 Application에서 사용하는 계정정보
@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);
acoount.setEmail(username);
return account;
}
}
UserDetails를 Account와 호환시키고,
UserDetailsService를 AccountService와 호환시키려면 어떻게해야할까?
변경코드
//시큐리티 패키지에 있는 UserDetails를 구현한다
public class AccountUserDetails implments UserDetails {
Account account;
public AccountUserDetails(Account account){
this.account = account;
}
@Override
public String getUsername(){
return this.account.getName();
}
@Override
public String getPassword(){
return this.account.getPassword();
}
}
//시큐리티 패키지의 인터페이스를 구현한다
public class AccountUserDetailsService implements UserDetailsService {
AccountService accountService;
public AccountUserDetailsService(AccountService accountService){
this.accountService = accountService;
}
@Override
public UserDetails loadUser(String username){
Account account = accountService.findByAccountByUsername(username);
//우리 서비스에서 Account를 찾는다
return new AccountUserDetails(account);
//account를 넘겨주면 AccountUserDetails에서 Account를 UserDetails에 맞게 변환한다 (어댑터!)
}
}
public class App {
public static void main(String[] args) {
AccountService accountService = new AccountService();
UserDetailsService userDetailsService = new AccountUserDetailsService(accountService);
//Account를 UserDetails로 변환해주는 AccountUserDetailsService를 생성한다
LoginHandler loginHandler = new LoginHandler(userDetailsService);
//로그인 핸들러에 주입하여 Account가 UserDetails로 변환되도록 한다
String login = loginHandler.login("keesun", "keesun");
System.out.println(login);
}
}
LoginHandler <- UserDetailsService <- UserDetails
UserDetailsService <- AccountUserDetailsService <- AccountService
UserDtails <- AccountUserDetails <- Account
두개의 어댑터를 생성하여 Security패키지의 코드를 건들 수 없는 상황에서
우리의 애플리케이션과 호환되도록 처리할 수 있게되었다!
반응형
'Computer Science' 카테고리의 다른 글
Composite Pattern | 컴포짓 패턴 (0) | 2022.08.15 |
---|---|
Bridge Pattern | 브릿지 패턴 (0) | 2022.08.15 |
Prototype Pattern | 프로토타입 패턴 (0) | 2022.08.14 |
Abstract Factory | 추상 팩토리 패턴 (0) | 2022.08.14 |
Factory Method Pattern | 팩토리 메서드 패턴 (0) | 2022.07.29 |