์ค๋ซ๋ง์ ๋ธ๋ก๊ทธ ๊ธ ๋จ๊ธฐ๊ธฐ.
์ฐธ๊ณ ์์ : gof์ ๋์์ธ ํจํด
๊ตฌ์ฑ ์์
- Builder
- Concrete Builder
- Director
Builder
Protocol
Concrete Builder
builder๋ฅผ ์ค์ํ ๊ตฌํ ํด๋์ค
Director
Concrete Builder๋ฅผ ์ด์ฉํ์ฌ ๊ฐ์ฒด๋ฅผ return
ํด์ฃผ๋ ๊ตฌํ ํด๋์ค
ํต์ฌ = Builder
Builder๋ product๋ฅผ ์์ฑ ๊ฐ์ ์ ํ ํ๋ ํจ์๋ builder๋ฅผ ๋ฐํํ๋ค. (Chain์ ์ฐ๊ธฐ ์ํจ.)
๋ฉ์๋ ์์ฑ์ ๋ฌถ์ ์ ์๋ ๋ถ๋ถ์ ๊ฐ์ด ๋ฌถ๋๋ค
- ex) UIButton์ ํ ๋๋ฆฌ๋ฅผ ๋ง๋ค๋ ๋ณดํต Color์ Width๋ ๋๋ค ์ ๋ ฅํ๊ฒ ๋๋ฏ๋ก ์ธ์๊ฐ์ Color์ Width๋ฅผ ๋ฃ์ด ํ๋๋ก ๋ฌถ๋๋ค.
์ฅ์
- Rxswift๋์ฒ๋ผ ์ฒด์ธ ๊ธฐ๋ฅ์ ์ด์ฉํ์ฌ, ๊ฐ์ฒด ์์ฑ๋ ํ์ํ ๋ชจ๋ ๊ฒ์ ํ ๋ผ์ธ(์ค๋ฐ๊ฟ์ ๋น์ฐ!)์ผ๋ก ์์ฑ์ด ๊ฐ๋ฅํ์ฌ, ํด๋น ์ฝ๋ ๋ถ์ฐ์ด ์ ๋ค.
- ์์ ์์์ฒ๋ผ Bolder์ Width์ Color๋ ๋ณดํต ๋ฌถ์ด์ ์ฒ๋ฆฌ๊ฐ ๊ฐ๋ฅํ๋ฏ๋ก ์ฝ๋ ๋ผ์ธ์ด ๋ ์ ์ด์ง๋ค.
- product๋ฅผ ์์ฑ์ ๋ฏธ๋ฆฌ ๋ฐ์ ์์ฑ ๊ฐ์ ์ด์ฉํด ํ์ ๊ฐ์ ๋๋ฝ ํ๋์ง ์ํ๋์ง ํ์ธ ๊ฐ๋ฅ.
๊ทธ๋ฌ๋ฉด Director๋?
๋ฐฐ์ฐ๋ฉด์ ๊ฐ์ธ์ ์ธ ์๊ฐ์ผ๋ก , Builder์ Concrete Builder๋ง์ผ๋ก ์์ ํ์ ๋ฏํ๋ค.
์ฒด์ธ ๊ธฐ๋ฅ์ ์ฐ๋ฉฐ, ์๊ธฐ๊ฐ Builder์ ์ถ์ํํ๋๋ก ๋ช ํํ๊ฒ ์๋ก์ด ๊ฐ์ฒด ์์ฑ์ด ๊ฐ๋ฅํด์ก์ผ๋ฉฐ,
ํ๋จ์ ๋ฒํผ๋ค์ด๋ผ๋๊ฐ ํน์ ๋ทฐ๋ค์ด ์์ฑํ๋ค๋ณด๋ฉด ๋ถ๋ช ๊ฐ์ ์ฝ๋๊ฐ ๋์ฌ๊ฒ์ด๋ค.
๊ทธ๋ผ, ์ด๋ฐ ๊ณตํต์ Concrete Builder๋ค์ ๊ด๋ฆฌํ๋ ๊ฒ์ด ํ์ํ๋ค ๋๋ผ๊ณ Builder๋ฅผ Returnํ๋ class๋ฅผ ๋ง๋ค๊ณ
์ด๋ฆ์ Director๋ผ๊ณ ๋ถ์ฌ์ค๊ฒ ๊ฐ๋ค๋ ๋๋์ ๋ฐ์๋ค. ๊ฐ์ธ์ ์ผ๋ก <
UML - Class Diagram
์์ ๊ฐ์ ๊ตฌ์กฐ๋ก ์ด๋ฃจ์ด์ ธ ์์ผ๋ฉฐ ๋์ฌ๊ฒจ ๋ณผ ๊ฒ์ ๋ค์๊ณผ ๊ฐ๋ค
- build๋ฅผ ํตํด ๊ฐ์ฒด๋ฅผ ๋๋ ค์ค๋ค.
- ํ
๋๋ฆฌ ์ ์ฉ์
width
์color
๋ฅผ ๊ฐ์ด ๋ฐ๋๋ค
๊ทธ๋ฆฌ๊ณ , Director๋ ๋ฏธ๋ฆฌ ์ ์ํ ๋ฒํผ์ Builder๋ฅผ ์ค์ํ ๊ฐ์ฒด๋ฅผ ๋ฐํ ํด์ค๋ค.
CODE
Builder & ConcreteBuilder
๋ฉ์๋๋ค์ค ์ผ๋ถ๋ง ์ฝ๋๋ก ๋ณด์
(ํ๋กํ ์ฝ์ ์์ ๊ทธ๋ฆผ์ผ๋ก ์ถฉ๋ถํ๋ฏ๋ก ์ฝ๋ ์๋ต.)
class ButtonConcreteBuilder: ButtonBuilder {
private var product = UIButton()
... ์๋ต
// ํ
์คํธ ์
๋ ฅ
func setTitle(_ title: String) -> ButtonBuilder {
self.product.setTitle(title, for: .normal)
return self
}
// ํ
๋๋ฆฌ ์ ์ฉ (์ปฌ๋ฌ์ ํญ์ ํ๋ฒ์ ๋ฐ์ ๋ณด๋ค ์ฝ๊ฒ ์ ์ฉ)
func setBolder(color: UIColor, width: CGFloat) -> ButtonBuilder {
self.product.layer.borderWidth = width
self.product.layer.borderColor = color.cgColor
return self
}
// ๊ฐ์ฒด ๋ฐํ
func build() -> UIButton? {
return self.product
}
}
๊ฐ๋จ.
Director
class ButtonDirector {
static func makeBottomButton() -> UIButton {
let titleColor = UIColor(red: 1, green: 192/255, blue: 0, alpha: 1)
let highLightColor = titleColor.withAlphaComponent(0.4)
let bgColor = UIColor(red: 51/255, green: 59/255, blue: 67/255, alpha: 1)
let font = UIFont.boldSystemFont(ofSize: 17)
let radius: CGFloat = 8
let screenFrame = UIScreen.main.bounds
let screenSize = screenFrame.size
let margin: CGFloat = 12.0
let height: CGFloat = 45.0
let size = CGSize(width: screenSize.width - (margin * 2), height: height)
let point = CGPoint(x: margin, y: screenSize.height - height - (margin * 2))
let frame = CGRect(origin: point, size: size)
// 1. Chain์ ์ด์ฉํ์ฌ ๊ฐ ์
ํ
let builder = ButtonConcreteBuilder()
.setBGColor(bgColor)
.setTitleColor(titleColor)
.setTitleHighlightedColor(highLightColor)
.setFont(font)
.setFrame(frame)
.setRadius(radius)
.setTitle("Bottom")
return builder.build()
}
}
Director๋ ํ๋กํ ์ฝ์ ์์ฑํ์ฌ ์ค์ํ๊ฒ ๋ง๋ค๋ฉด ์ข๊ฒ ์ง๋ง? ์๋ ์ผ๋จ ์ด๋ ๊ฒ ํฉ์๋ค. ๋ด๊ฐ ํ์ํ๊ฑด ๊ณตํต์ ์ผ๋ก ํ๋จ์์ ์ฐ์ผ ๋ฒํผ์ด๋๊น!
์ฌ๊ธฐ์ ๋ ์ฌ๊ฒจ ๋ณด์์ผํ ๊ฒ์ ์ฃผ์ ๋ถ๋ถ์ด๋ค.
์ฒด์ธ์ ์ด์ฉํ์ฌ ์ฐ๋ฌ์์ ๊ฐ์ ์ ์ฉ ํ ์ ์์ผ๋ฉฐ, ๋ถ์ฐ์ด ์๋จ์ ๋๋ ์ ์์๋ค.
๊ทธ๋ฆฌ๊ณ ๋ง๋ฌด๋ฆฌ๋ก build()
ํ์ฌ ๋ฒํผ ๊ฐ์ฒด ๋ฐํ.
์ฌ์ฉ
class ViewController: UIViewController {
...
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.addBottomButton()
}
private func addBottomButton() {
let bottomButton = ButtonDirector.makeBottomButton()
self.view.addSubview(bottomButton)
}
}
์์ ๊ฐ์ด ์์ฃผ ๊ฐ๋จํ๊ฒ Director
๋ฅผ ํตํด ํ๋ฉด์ ๋ฒํผ์ ์ถ๊ฐํ๋ค.
๊ฒฐ๊ณผ๋ ์๋์ ๊ฐ๋ค.
ํ์คํ
Builder ํจํด์ ๋ช ํํ๊ณ ํต์ผ์ฑ ์๊ฒ ๊ฐ์ฒด๋ฅผ ์์ฑํ ์ ์์ผ๋ฉฐ ๊ฐ๋จํ ์ปดํฌ๋ํธ์ ์ ๋นํ ๋๋.