어답터패턴
- 구조패턴
- 서로 다른 형식을 가진 객체를 하나의 형식으로 통합할 수 있도록 하는 패턴
- 서로 일치하지 않는 인터페이스를 갖는 클래스를 함께 사용하는 방법
활용성
- 기존 클래스를 사용하고 싶은데 인터페이스가 맞지 않을 때
- 이미 만든 것을 재사용 하려고 하지만 이 재사용 가능한 라이브러리를 수정할 수 없을 때
구조
요소
- 타겟
- 사용자가 사용할 응용 분야에 종속적인 인터페이스를 정의
- 클라이언트
- 타겟 인터페이스를 만족하는 객체와 동작할 대상
- 어답티
- 인터페이스 적응이 필요한 기존 인터페이스를 정의
- 어답터
- 타겟 인터페이스에 어답티의 인터페이스를 적용시키는 객체
장점
- 단일 책임 원칙. 프로그램의 기본 비즈니스 로직에서 인터페이스 또는 데이터 변환 코드를 분리할 수 있습니다.
- 개방/폐쇄 원칙. 클라이언트 코드가 클라이언트 인터페이스를 통해 어댑터와 작동하는 한, 기존의 클라이언트 코드를 손상시키지 않고 새로운 유형의 어댑터들을 프로그램에 도입할 수 있습니다.
단점
- 다수의 새로운 인터페이스와 클래스들을 도입해야 하므로 코드의 전반적인 복잡성이 증가, 때로는 코드의 나머지 부분과 작동하도록 서비스 클래스를 변경하는 것이 더 간단하다.
예시 코드
final class kakaoLogin {
func excute(id: String) {
excute()
}
private func excute() {
print("kakaoLogin")
}
}
extension kakaoLogin: LoginApdapter {
func excute(id: String, phone: String) {
excute()
}
}
final class naverLogin {
func excute(id: String) {
print("naverLogin: \\(id)")
}
}
final class appleLogin: LoginApdapter {
func excute(id: String, phone: String) {
print("naverLogin: \\(id), \\(phone)")
}
}
extension naverLogin: LoginApdapter {
func excute(id: String, phone: String) {
excute(id: id)
}
}
protocol LoginApdapter {
func excute(id: String, phone: String)
}
let kakao: LoginApdapter = kakaoLogin()
let naver: LoginApdapter = naverLogin()
let apple: LoginApdapter = appleLogin()
func login(flatform: LoginApdapter, id: String, phone: String) {
flatform.excute(id: id, phone: phone)
}
login(flatform: kakao, id: "kakao", phone: "123")
login(flatform: naver, id: "naver", phone: "123")
login(flatform: apple, id: "apple", phone: "123")
참고