본문 바로가기
아이폰 개발/디자인 패턴

swift 디자인패턴 - Adapter Pattern

by 인생여희 2021. 8. 21.

swift 디자인패턴 - Adapter Pattern

 

 

언제 사용하나?

 

1.연관성 없는 두객체를 묶어서 사용해야할때.

2.타사의 라이브러리 or 모듈을 사용해야 할때.

3.같은 프로젝트에서 다른팀이 구현해 놓은 클래스의 기능을 가져다 사용할때.

 

4.A 팀이 신용카드를 등록하고 조회하는 클래스를 만들어 놓았다.

B 팀은 Adapter Pattern 을 만들어서 그 기능을 가져온 다음에 가공해서 사용하면된다.

 

 

해결 목표?

이미 주어진 알고리즘(Math 클래스)을 나만의 요구사항에 맞춰서 사용할 수 있다.

 

Adapter의 사전적 의미?

기계. 기구등을 다목적으로 사용하기 위한 부가적인 기구

 

기본 설계

 

 

요구사항

 

예제 1

import UIKit

/// 이미주어진 알고리즘 or 타사의 라이브러리 or 다른 팀의 모듈
class Math{
    /// 두배
    public static func twoTime(num:Double) -> Double{ return num * 2 }
    /// 절반
    public static func half(num:Double) -> Double{ return num / 2 }
}
/// Adaptee
/// 인터페이스 정의
protocol Adapter{
    func twiceOf(f : Float) -> Float
    func halfOf(f : Float) -> Float
}

/// 우리팀에서 Math 클래스를 참조해서 커스터마이징 한 클래스
class AdapterImpl : Adapter{
    //let math = Math() // 이렇게 객체를 만들어서도 사용가능!
    /// 원하는 기능 [1]
    func twiceOf(f: Float) -> Float {
        return Float(Math.twoTime(num: Double(f)))
    }
    /// 원하는 기능 [2]
    func halfOf(f: Float) -> Float {
        return Float(Math.half(num: Double(f)))
    }
}
/// 사용
let adapter = AdapterImpl()
let twice = adapter.twiceOf(f: 100.0)
let half = adapter.halfOf(f: 80.0)
print(twice)
print(half)

 

추가로 로그를 찍는 함수를 넣어야 된다고 하면?

Math 알고리즘에 로그를 넣으면 저 함수를 사용하는 모든 사용자들의 콘솔에 로그가 찍히게 된다.

그래서 AdapterImpl 클래스의 해당함수안에 구현해주면 기존의 타사모듈에 영향을 주지 않고 사용할 수 있다.

 

 

예제2

 

Adapter(어댑터) 디자인 패턴은 호환되지 않는 인터페이스를 가진 두 개의 객체가 함께 동작할 수 있도록 해주는 구조 설계 패턴이다.

 

특정 객체의 인터페이스를 변환하여 다른 객체에 적응시켜 사용할 수 있게 도와준다.

 

 

import UIKit
import Foundation

//외부 라이브러리 및 외부 시스템 객체(기존 객체)
class Adaptee {
    public func specificRequest() -> String{
        return "Adaptee's 특정 request."
    }
}
/// Adapter가 구현하는 추상 인터페이스 객체.
///클라이언트는 타겟(Target)의 인터페이스를 통해서 Adaptee의 인터페이스를 사용하게 된다.
class Target {
    func request() -> String {
        return "- - -"
    }
}
/// Adaptee(기존 객체, 타사 모듈)와 클라이언트 중간에서 연결시켜주는 역할을 한다.
/// 타겟(Target) 인터페이스를 구현하며 클라이언트는 타겟 인터페이스를 통해 어댑터에 요청을 보낸다.
class Adapter:Target{
    
    private var adaptee: Adaptee
    
    init(_ adaptee: Adaptee) {
        self.adaptee = adaptee
    }
    override func request() -> String {
        /// [!] 타사 모듈 함수 호출
        return self.adaptee.specificRequest()
    }
    
}

let adaptee = Adaptee()         //타사 모듈
let adapter = Adapter(adaptee)   //Target을 구현한 어댑터
adapter.request()

 

 

 

참고

https://github.com/jaicoco/Swift_Design_Pattern_Study

https://www.youtube.com/watch?v=gJDZ7pcvlAU&list=PLsoscMhnRc7pPsRHmgN4M8tqUdWZzkpxY&index=3

https://joycestudios.tistory.com/33