Contents
Builder Pattern
- ๋ณต์กํ ๊ฐ์ฒด๋ฅผ ๋จ๊ณ๋ณ๋ก ๊ตฌ์ถํ๋ ์์ฑ ๋์์ธ ํจํด
์ฌ์ฉ ์ด์
alert
์ ๊ฒฝ์ฐ ์ํฉ์ ๋ฐ๋ผ ๋ค์ํ UI๊ฐ ๋์ฌ ์ ์๋ค.
- ์ฆ, ์ด๋ค Case์๋ โํ์ธโ, โ์ทจ์โ ๋ฒํผ ๋ชจ๋ ํ์ํ ์๋ ์๊ณ , ์ด๋ค Case์๋ โํ์ธโ ๋ฒํผ๋ง ํ์ํ ์ ์๋ค.
- ๋ฐ๋ผ์, ์ํฉ์ ๋ฐ๋ผ ์กฐํฉ๋ ์ ์๋ ๊ฒฝ์ฐ์ ์๊ฐ ๋ค์ํ ๊ฒฝ์ฐ ์ด
Builder Pattern
์ ์ฌ์ฉํ๋ ๊ฒ์ด ์ ์ ํ๋ค.
๊ธฐ๋ณธ ๊ตฌ์กฐ
- ๋น๋ ํจํด์ 4๊ฐ์ง ๊ธฐ๋ณธ ๊ตฌ์กฐ๋ฅผ ๊ฐ์ง๋ค.
- Builder: ๊ฐ์ฒด์ ๊ตฌ์ฑ ์์๋ฅผ ์ ์ํ๋ ์ธํฐํ์ด์ค
- Concrete Builder: ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ๊ณ , ๊ฒฐ๊ณผ๋ฌผ์ ๋ฐํํ๋ ๋ฐฉ์์ ์ ์
- Director: ์ธํฐํ์ด์ค๋ฅผ ์ฌ์ฉํ์ฌ ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ ๊ณผ์ ์ ์ ์
- Product: ๋น๋๋ฅผ ํตํด์ ์์ฑ๋๋ ์ต์ข ๊ฐ์ฒด
์ฅ์
- ๋ถ๋ฆฌ๋ ๊ตฌ์ถ ๊ณผ์ : ๊ฐ์ฒด์ ๊ตฌ์ถ๊ณผ ํํ์ ๋ถ๋ฆฌํ์ฌ ๋ณต์กํ ๊ฐ์ฒด๋ฅผ ์ฝ๊ฒ ์์ฑ
- ์ฌ์ฌ์ฉ์ฑ: ๋์ผํ ๊ตฌ์ถ ๊ณผ์ ์์ ๋ค์ํ ํํ ๊ฐ๋ฅ
- ๊ฐ๋ ์ฑ: ๊ฐ ๋จ๊ณ๊ฐ ๋ช ํํ ์ ์๋์ด ์์ด, ์ฝ๋์ ๊ฐ๋ ์ฑ์ด ์ข์์ง๋ค.
๋จ์
- ๋ณต์ก์ฑ ์ฆ๊ฐ: ๋จ์ํ ๊ฐ์ฒด์ ๋น๋ ํจํด์ ์ฌ์ฉํ๋ฉด ๋ถํ์ํ๊ฒ ๋ณต์ก์ฑ์ ์ฆ๋์ํฌ ์ ์๋ค.
1. Builder ๊ตฌํ
Builder
๋ ๊ฐ์ฒด์ ๊ตฌ์ฑ์์๋ฅผ ์ ์ํ๋Class
์ด๋ค.
Alert
์ ๊ฒฝ์ฐ,title
,message
,action
๊ณผ ๊ฐ์ ๊ธฐ๋ณธ ์์๋ฅผ ๊ฐ์ง๋ค.
- ๋ฐ๋ผ์, ์์ ๊ฐ์ ๊ตฌ์ฑ ์์๋ฅผ
protocol
์ ํ์ฉํด ์ ์ํด์ค๋ค.
// // Protocol+Builder.swift // AlertBuilderPattern // // Created by Dongwan Ryoo on 1/7/24. // import Foundation //class์์๋ง ์ค์ํ ์ ์์ protocol Builder: AnyObject { //alert์ title๊ณผ message var title: String? { get } var message: String? { get } //alert์ title, message, ConfirmAction์ ์ถ๊ฐํ๋ ๋ฉ์๋ func setTitle(_ text: String) -> Self func setMessage(_ text: String) -> Self func addConfirmAction(_ text: String, action: (() -> Void)?) -> Self }
2. Concrete Builder ๊ตฌํ
Builder
๋ฅผ ๊ตฌํํ์ผ๋, ์ด ์ธํฐํ์ด์ค๋ฅผ ์ฑํํConcrete Builder
๋ฅผ ๊ตฌ์ฑํ๋ค.
Concrete Builder
์ ํต์ฌ์ 1)์ธํฐํ์ด์ค ๊ตฌํํ๊ณ , 2)๊ฒฐ๊ณผ๋ฌผ์ ์ ์ํ๊ณ , 3)์ด๋ฅผ ๋ฐํํ ๋ฐฉ์์ ์ ์ํ๋ ๊ฒ์ด๋ค.
- ์ธํฐํ์ด์ค ๊ตฌํ
Builder protocol
์ ์ฑํํ๋ค.
import Foundation class AlertConcreteBuilder: Builder { var title: String? var message: String? func setTitle(_ text: String) -> Self { } func setMessage(_ text: String) -> Self { } func addConfirmAction(_ text: String, action: (() -> Void)?) -> Self { } }
2)๊ฒฐ๊ณผ๋ฌผ์ ์ ์
- ๋ฐํํ ๊ฒฐ๊ณผ๋ฌผ์ Customํ AlertController์ด๊ธฐ ๋๋ฌธ์, ๋ณ๋์
CustomAlertController
ํ์ผ์ ์์ฑํด์ค๋ค.
// // CustomAlertController.swift // AlertBuilderPattern // // Created by Dongwan Ryoo on 1/7/24. // import UIKit class CustomAlertController: UIViewController { }
- ๊ฒฐ๊ณผ๋ฌผ(
Alert
)์ ๋ค์ด๊ฐ UI ๋ฑ์ ์ ์ํด์ค๋ค.
import UIKit import SnapKit class CustomAlertController: UIViewController { private lazy var alertView = { let view = UIStackView() view.layer.cornerRadius = 16 view.backgroundColor = .bgGrey view.axis = .vertical view.alignment = .center return view }() private lazy var titleLabel = { let view = UILabel() view.font = UIFont.systemFont(ofSize: 16, weight: .bold) view.textAlignment = .center return view }() private lazy var messageLabel = { let view = UILabel() view.font = UIFont.systemFont(ofSize: 12) view.textAlignment = .center return view }() private lazy var confirmButton = { let view = UIButton() view.setTitleColor(.white, for: .normal) view.titleLabel?.font = UIFont.systemFont(ofSize: 14, weight: .bold) view.backgroundColor = .mainBlue view.layer.cornerRadius = 16 return view }() override func viewDidLoad() { addTarget() layouts() } } extension CustomAlertController { func layouts() { view.addSubview(alertView) alertView.snp.makeConstraints { $0.width.equalTo(312) $0.center.equalToSuperview() } alertView.addArrangedSubview(titleLabel) titleLabel.snp.makeConstraints { $0.top.equalToSuperview().offset(24) $0.width.equalTo(276) $0.centerX.equalToSuperview() } alertView.addArrangedSubview(messageLabel) alertView.setCustomSpacing(12, after: titleLabel) messageLabel.snp.makeConstraints { $0.width.equalTo(276) $0.centerX.equalToSuperview() } alertView.addArrangedSubview(confirmButton) alertView.setCustomSpacing(24, after: messageLabel) confirmButton.snp.makeConstraints { $0.centerX.equalToSuperview() $0.width.equalTo(276) $0.height.equalTo(44) } } } extension CustomAlertController { func addTarget() { confirmButton.addTarget(self, action: #selector(confirmButtonTapped), for: .touchUpInside) } @objc func confirmButtonTapped() { dismiss(animated: true) } }
- ๊ฒฐ๊ณผ๋ฌผ์ ๋ค์ด๊ฐ
title
,massage
๋ฅผ ๋ฐ์ ํ๋กํผํฐ๋ฅผ ์์ฑํ๋ค.
class CustomAlertController: UIViewController { var alertTitle: String? var alertMessage: String? private lazy var alertView = { let view = UIStackView() view.layer.cornerRadius = 16 view.backgroundColor = .bgGrey view.axis = .vertical view.alignment = .center return view }() . . . //๊ธฐ์กด ์ฝ๋
- ๋ฒํผ์
Action
์ ์ ์ํ ๊ตฌ์กฐ์ฒด๋ฅผ ๋ง๋ค์ด ์ค๋ค.
- ์ด๋, ๋ฒํผ์ ๋ค์ด๊ฐ
ํ ์คํธ
์Action
์ ๊ฐ์ด ์ ์ํด์ค๋ค.
struct Action { var text: String? var action: (()-> Void)? }
CustomAlertController
์action
ํ๋กํผํฐ๋ฅผ ์ถ๊ฐํด์ค๋ค.
class CustomAlertController: UIViewController { var alertTitle: String? var alertMessage: String? var confirmAction: Action? private lazy var alertView = { let view = UIStackView() view.layer.cornerRadius = 16 view.backgroundColor = .bgGrey view.axis = .vertical view.alignment = .center return view }() . . . //๊ธฐ์กด ์ฝ๋
- ์ธํฐํ์ด์ค์ ๊ตฌ์ฑ ์์(
title
,message
,action
)๋ฅผ UI์ ์ ์ฉํด์ค๋ค.
private lazy var titleLabel = { let view = UILabel() view.font = UIFont.systemFont(ofSize: 16, weight: .bold) view.textAlignment = .center view.text = alertTitle //Title return view }() private lazy var messageLabel = { let view = UILabel() view.font = UIFont.systemFont(ofSize: 12) view.textAlignment = .center view.text = alertMessage //Message return view }() private lazy var confirmButton = { let view = UIButton() view.setTitleColor(.white, for: .normal) view.titleLabel?.font = UIFont.systemFont(ofSize: 14, weight: .bold) view.backgroundColor = .mainBlue view.layer.cornerRadius = 16 view.setTitle(confirmAction?.text, for: .normal) //Button Title return view }() . . . @objc func confirmButtonTapped() { confirmAction?.action?() //Button Action dismiss(animated: true) }
- ์ง๊ธ๊น์ง ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ๊ณ , ๋ฐํํ ๊ฒฐ๊ณผ๋ฌผ(
CustomAlertController
)์ ์ ์ํ๋ค.
- ์ด์ ,
AlertConcreteBuilder
๋ก ๋์๊ฐ์ ๊ฒฐ๊ณผ๋ฌผ์ ๋ฐํํ ๋ฐฉ์์ ์ ์ํ๋ฉด ๋๋ค.
- ๊ฒฐ๊ณผ๋ฌผ ๋ฐํ ๋ฐฉ์ ์ ์
AlertConcreteBuilder
๋ก ๋์๊ฐ์ ์ ์๋ ๊ฒฐ๊ณผ๋ฌผ์ ์ธ์คํด์ค๋ฅผ ์์ฑํด์ค๋ค.
class AlertConcreteBuilder: Builder { var title: String? var message: String? private let alertViewController = CustomAlertController() func setTitle(_ text: String) -> Self { } func setMessage(_ text: String) -> Self { } func addConfirmAction(_ text: String, action: (() -> Void)?) -> Self { } }
Alert
์ ๊ฒฝ์ฐ ํน์ ViewController
๋ฅผ ๋ฃจํธ๋ก ํ๊ธฐ ๋๋ฌธ์RootViewController
๋ ํ๋ ์ ์ํด์ค๋ค.
class AlertConcreteBuilder: Builder { var title: String? var message: String? private let alertViewController = CustomAlertController() private var rootViewController: UIViewController? func setTitle(_ text: String) -> Self { } func setMessage(_ text: String) -> Self { } func addConfirmAction(_ text: String, action: (() -> Void)?) -> Self { } }
- ํ์ธ ๋ฒํผ์ ํด๋ฆญํ์ ๋์ ์ก์ ๋ ์ ์ํด์ค๋ค.
class AlertConcreteBuilder: Builder { private var title: String? private var message: String? private var addConfirmAction: Action? private let alertViewController = CustomAlertController() private var rootViewController: UIViewController? func setTitle(_ text: String) -> Self { } func setMessage(_ text: String) -> Self { } func addConfirmAction(_ text: String, action: (() -> Void)?) -> Self { } }
AlertConcreteBuilder
๋ฅผ ๊ฑฐ์ณ ๊ฒฐ๊ณผ๋ฌผ์ ์ ๋ฌํ ์์๋ค์ ๋ฉ์๋ ๋ด๋ถ์ ๊ตฌํํด์ค๋ค.
class AlertConcreteBuilder: Builder { var title: String? var message: String? private var addConfirmAction: Action? private let alertViewController = CustomAlertController() private var rootViewController: UIViewController? func setTitle(_ text: String) -> Self { title = text return self } func setMessage(_ text: String) -> Self { message = text return self } func addConfirmAction(_ text: String, action: (() -> Void)?) -> Self { addConfirmAction?.text = text addConfirmAction?.action = action return self } }
rootViewController
๋ฅผ ์ ์ํ ์์ฑ์๋ฅผ ๋ง๋ค์ด์ค๋ค.
- ๋ง์ง๋ง์ผ๋ก
present()
๋ฉ์๋๋ฅผ ํตํด ๊ฒฐ๊ณผ๋ฌผ์ ๋ฐํํด์ค๋ค.
class AlertConcreteBuilder: Builder { var title: String? var message: String? private var addConfirmAction: Action? private let alertViewController = CustomAlertController() private var rootViewController: UIViewController? init(_ viewController: UIViewController) { rootViewController = viewController } func setTitle(_ text: String) -> Self { title = text return self } func setMessage(_ text: String) -> Self { message = text return self } func addConfirmAction(_ text: String, action: (() -> Void)?) -> Self { addConfirmAction?.text = text addConfirmAction?.action = action return self } @discardableResult func present() -> Self { alertViewController.alertTitle = title alertViewController.alertMessage = message alertViewController.confirmAction = addConfirmAction alertViewController.modalPresentationStyle = .overFullScreen alertViewController.modalTransitionStyle = .crossDissolve rootViewController?.present(alertViewController, animated: true) return self } }
3. Product ๊ตฌ์ฑ
Director
๋ ์ง๊ธ ์ํฉ์์๋ ๋ณต์ก๋๋ง ๋๋ฆฌ๊ธฐ ๋๋ฌธ์ ์์ฑ X
ViewController
์Product
์์ฑ
// // ViewController.swift // AlertBuilderPattern // // Created by Dongwan Ryoo on 1/7/24. // import UIKit class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = .black } override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(true) showAlert() } func showAlert() { AlertConcreteBuilder(self) .setTitle("์๋ฆผ์ ํ์ธํด์ฃผ์ธ์.") .setMessage("๊ถํ์ ํ์ธํ๊ณ ์ถ์ต๋๋ค.") .addConfirmAction("ํ์ธ") { print("ํ์ธ ๋ฒํผ ํด๋ฆญ") } .present() } }
4. ์ต์ข ๊ฒฐ๊ณผ๋ฌผ
Share article