Notice
Recent Posts
Recent Comments
Link
관리 메뉴

김종권의 iOS 앱 개발 알아가기

[iOS - swift] 플러그인 패턴 (plugin pattern) 본문

iOS 응용 (SwiftUI)

[iOS - swift] 플러그인 패턴 (plugin pattern)

jake-kim 2024. 12. 27. 01:24

플러그인 패턴

  • 핵심 기능을 변경하지 않고도 새로운 기능을 추가하거나 확장할 수 있도록 하는 구조적 패턴
  • 유연성과 확장성이 높다는 장점

플러그인 패턴 구조

ex) 계산기 로직을 플러그인 패턴으로 만들기

  • PluginManager가 있고 여기서는 핵심 기능을 담당하며, 이곳에 추가하고 싶은 기능(플러그인)들을 등록하고 실행할 수 있는 관리자 역할
let pluginManager = PluginManager()
  • 플러그인 인스턴스를 만들어서 플러그인에 등록
let additionPlugin = AdditionPlugin()
let multiplicationPlugin = MultiplicationPlugin()

pluginManager.registerPlugin(additionPlugin)
pluginManager.registerPlugin(multiplicationPlugin)
  • PluginManager는 등록한 기능들을 실행하는 역할을 수행
    • PluginManager는 내부적으로 따로 로깅을 수행하면서, 플러그인 기능들을 수행
if let result = pluginManager.performOperation(ofType: AdditionPlugin.self, a: 5, b: 3) {
    print("Addition Result: \(result)") // Addition Result: 8.0
}

if let result = pluginManager.performOperation(ofType: MultiplicationPlugin.self, a: 5, b: 3) {
    print("Multiplication Result: \(result)") // Multiplication Result: 15.0
}

플러그인 패턴 구현

  • 프로토콜과 플러그인 선언
    • 기능을 수행하는 performOperation을 선언하고 덧셈 플러그인, 곱셈 플러그인을 정의
protocol CalculatorPlugin {
    func performOperation(_ a: Double, _ b: Double) -> Double
}

class AdditionPlugin: CalculatorPlugin {
    func performOperation(_ a: Double, _ b: Double) -> Double {
        return a + b
    }
}

class MultiplicationPlugin: CalculatorPlugin {
    func performOperation(_ a: Double, _ b: Double) -> Double {
        return a * b
    }
}
  • PluginManager에서는 이 플러그인들을 관리해야하고, 사용하는 쪽에서 플러그인 타입으로 특정 기능을 수행하게 하기위해서 key값을 ObjectIdentifier로 하는 딕셔너리 선언
    • perfomOperation에서는 타입을 받도록하여 타입의 ID를 기록해놓았다가 실행하는 방식
class PluginManager {
    private var plugins: [ObjectIdentifier: CalculatorPlugin] = [:]

    func registerPlugin<T: CalculatorPlugin>(_ plugin: T) {
        let key = ObjectIdentifier(T.self)
        plugins[key] = plugin
        print("PluginManager: Registered \(T.self) plugin.")
    }

    func performOperation<T: CalculatorPlugin>(ofType type: T.Type, a: Double, b: Double) -> Double? {
        let key = ObjectIdentifier(type)
        guard let plugin = plugins[key] as? T else {
            print("PluginManager: No plugin found for type \(T.self)")
            return nil
        }
        return plugin.performOperation(a, b)
    }
}

사용하는 쪽)

let pluginManager = PluginManager()

let additionPlugin = AdditionPlugin()
let multiplicationPlugin = MultiplicationPlugin()

pluginManager.registerPlugin(additionPlugin)
pluginManager.registerPlugin(multiplicationPlugin)

if let result = pluginManager.performOperation(ofType: AdditionPlugin.self, a: 5, b: 3) {
    print("Addition Result: \(result)") // Addition Result: 8.0
}

if let result = pluginManager.performOperation(ofType: MultiplicationPlugin.self, a: 5, b: 3) {
    print("Multiplication Result: \(result)") // Multiplication Result: 15.0
}

 

Comments