전략 패턴
1. 전략 패턴을 사용한 이유?
현재 프로젝트에서는 소셜 회원가입/로그인 기능에서 카카오 플랫폼만 사용하고 있지만
추후에 다른 SNS 플랫폼을 사용할 수 있다.
추가적인 SNS 플랫폼을 사용한다면 API를 새로 만들어야 할 것이다.
그런데 SNS 플랫폼들은 표준화된 protocol인 oauth 2.0을 통해서
사용자의 SNS 프로필 정보에 대한 접근을 제공하고 있다.
그렇다면 추상화 인터페이스와 SNS 플랫폼 별로 이를 구현한 구현체를 만들고
런타임에 요청에 따라 구현체를 갈아끼울 수 있다면 API를 매번 만들 필요가 없다.
2. OAuth 2.0란?
oauth는 권한 위임을 위한 개방형 표준 protocol로
third-party application이 사용자의 리소스에 접근하기 위한 절차를 정의한다.
RFC 6479로 표준화된 규격이다.

3. 전략 패턴이란?
런타임에 알고리즘 전략을 선택해서 객체의 동작을 실시간으로 바뀌도록 할 수 있게 하는 행위 디자인 패턴이다.

전략 패턴 적용
1. 인터페이스
public interface SnsStrategy {
String getSnsEmail(String token)
String getSnsToken(String code)
SnsProvider getServiceType();
}
2. 구현체
@Component
@RequiredArgsConstructor
public class KakaoStrategyImpl implements SnsStrategy {
@Override
public String getSnsEmail(String token) throws Exception {
var kakaoInfo = fetchKakaoInfo(token);
return Optional.ofNullable(kakaoInfo)
.map(KakaoInfoDto::getKakao_account)
.map(KakaoInfoDto.Account::getEmail)
.orElseThrow(() -> new NotFoundException(NOT_EXIST_USER));
}
@Override
public String getSnsToken(String code) throws Exception {
var kakaoToken = fetchKakaoToken(code);
return Optional.ofNullable(kakaoToken)
.map(SnsTokenDto::getAccess_token)
.orElseThrow(() -> new NotFoundException(NOT_EXIST_USER));
}
@Override
public SnsProvider getServiceType() {
return SnsProvider.KAKAO;
}
}
3. Service
@Service
public class UserService {
private final Map<SnsProvider, SnsStrategy> snsStrategyMap;
public UserService(
List<SnsStrategy> snsStrategyList
) {
this.snsStrategyMap = snsStrategyList.stream()
.collect(Collectors.toMap(SnsStrategy::getServiceType, snsStrategy -> snsStrategy));
}
@Transactional(readOnly = true)
public User snsLogin(SnsLoginDto dto) throws Exception {
var snsStrategy = snsStrategyMap.get(dto.getServiceType());
String snsEmail = snsStrategy.getSnsEmail(dto.getAccessToken());
if (!dto.getEmail().equals(snsEmail)) {
throw new BaseException(SNS_LOGIN_FAIL);
}
return userStore.getUserByEmail(dto.getEmail());
}
}'프로젝트 > 집안일 관리 시스템' 카테고리의 다른 글
| [보안 강화] Refresh Token을 사용해보자 (2) | 2025.08.10 |
|---|---|
| [기능 구현] 메모 기능에서 WebSocket을 사용해보자 (0) | 2025.08.05 |
| [성능 개선] Batch 작업을 최적화해보자 (1) | 2024.12.04 |
| [성능 개선] 유니온 쿼리를 개선해보자 (0) | 2024.01.08 |
| [성능 개선] 데이터베이스로 날라가는 쿼리의 수를 줄여보자 (0) | 2024.01.07 |