팩토리 방식으로 코드를 짜면 뷰컨트롤러의 부하를 조금이나마 줄일 수 있을 것..

protocol AlertFactoryService { }

protocol AlertActionDelegate { }

팩토리와 액션의 delegate를 위한 프로토콜을 만들어준다

class AlertImplementation: AlertFactoryService {
    weak var delegate: AlertActionDelegate?
    
    func build() {
    }
}

다음엔 팩토리를 컨펌하는 alert의 구현물을 만든다.

struct AlertViewData {
    let title: String
    let message: String
    let style: UIAlertController.Style
    let enableOkAction: Bool
    let okActionTitle: String
    let okActionStyle: UIAlertAction.Style
    let enableCancelAction: Bool
    let cancelActionTitle: String
    let cancelActionStyle: UIAlertAction.Style

		init(title: String,
         message: String,
         style: UIAlertController.Style = .alert,
         enableOkAction: Bool,
         okActionTitle: String,
         okActionStyle: UIAlertAction.Style,
         enableCancelAction: Bool = false,
         cancelActionTitle: String,
         cancelActionStyle: UIAlertAction.Style = .cancel) {
        self.key = key
        self.title = title
        self.message = message
        self.style = style
        self.enableOkAction = enableOkAction
        self.okActionTitle = okActionTitle
        self.okActionStyle = okActionStyle
        self.enableCancelAction = enableCancelAction
        self.cancelActionTitle = cancelActionTitle
        self.cancelActionStyle = cancelActionStyle
    }
}

그 다음 alert에 맞는 데이터를 구현해주고

protocol AlertFactoryService {
    var delegate: AlertActionDelegate? { get set }
    func build(alertData: AlertViewData) -> UIViewController
}

protocol AlertActionDelegate {
    func okAction()
    func cancelAction()
}

아까 만든 팩토리 프로토콜과 delegate 프로토콜에 인터페이스를 만들어준다.

이제 팩토리 구현물을 작업해 주자

class AlertImplementation: AlertFactoryService {
    weak var delegate: AlertActionDelegate?
    
    func build(alertData: AlertViewData) -> UIViewController {
        let vc = UIAlertController(title: alertData.title, 
                                   message: alertData.message, 
                                   preferredStyle: alertData.style)
        
        if alertData.enableOkAction {
            let okAction = UIAlertAction(
                           title: alertData.okActionTitle,
                           style: alertData.okActionStyle) 
            { (_) in
               self.delegate?.okAction(key)
            }
            vc.addAction(okAction)
        }
        
        if alertData.enableCancelAction {
            let cancelAction = UIAlertAction(
                               title: alertData.cancelActionTitle,
                               style: alertData.cancelActionStyle) 
            { (_) in
               self.delegate?.cancelAction(key)
            }
            vc.addAction(cancelAction)
        }
        return vc
    }
}

이제 뷰컨에서 alert를 쓸 때 필요한 delegate 프로토콜을 컨펌해서 사용할 수 있다.

class ViewController: UIViewController {
  private var alertFactory: AlertFactoryService = 
  AlertImplementation()
override func viewWillAppear(_ animated: Bool) { 
     alertFactory.delegate = self 
     displayAlert()
  }
  func displayAlert() {
    let alertData = AlertViewData(title: "Check Out This Alert", 
                            message: "Did You Like This Medium?",  
                            style: .alert, 
                            enableOkAction: true, 
                            okActionTitle: "Follow Now!", 
                            okActionStyle: .default, 
                            enableCancelAction: true, 
                            cancelActionTitle: "Follow Later!", 
                            cancelActionStyle: .cancel)
    
    let alert = alertFactory.build(alertData: alertData)
    present(alert, animated: true, completion: nil)
  }
}
extension ViewController: AlertActionDelegate {
  func okAction(_ key: AlertOkCancelActionKeys) {
     print("Thanks for the Follow!")
  }
  func cancelAction(_ key: AlertOkCancelActionKeys) {
     print("Thanks for thinking about it!")
  }
}

간단한 실습을 진행해 보았다.