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
}