GoF์˜ ๋””์ž์ธ ํŒจํ„ด, ํ…œํ”Œ๋ฆฟ ๋ฉ”์„œ๋“œ ํŒจํ„ด์— ๋Œ€ํ•ด ์•Œ์•„๋ณธ๋‹ค.

ํ•ด๋‹น ๊ธ€์€, ๋‹ค์Œ์˜ ์ฝ”๋“œ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์ดํ•ดํ•˜๋Š” ๊ฒƒ์ด ํŽธ๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

ํ•ต์‹ฌ ์š”์•ฝ

  • ํ•˜๋‚˜์˜ ๊ธฐ๋Šฅ์„ ์ˆ˜ํ–‰ํ•˜๋Š”๋ฐ ๋‹จ๊ณ„๊ฐ€ ์ •ํ•ด์ ธ ์žˆ์„ ์‹œ (ํ…œํ”Œ๋ฆฟ)
  • ์ด๋ฅผ ๊ตฌํ˜„๊ณผ ๋ถ„๋ฆฌํ•˜์—ฌ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ํŒจํ„ด

์˜ˆ์‹œ

Code

main

//
//  main.swift
//  TemplateMethod
//
//  Created by Choiwansik on 2023/02/21.
//
 
import Foundation
 
internal func main() {
    let title = "ํ…œํ”Œ๋ฆฟ ๋ฉ”์„œ๋“œ"
 
    let content = [
        "ํ•˜๊ณ  ์žˆ๋Š”๋ฐ ์กธ๋ฆฌ๋„ค์š”ใ…•",
        "์–ผ๋งˆ ๋‚จ์ง€ ์•Š์•˜์œผ๋‹ˆ ๋์„ ๋ด์•ผํ•ฉ๋‹ˆ๋‹ค..",
        "์˜ค๋Š˜์€ 230221",
        "๋ฒŒ์จ 2์›”",
    ]
 
    let footer = "๋‚˜๋Š” ์™„์ˆ™"
 
    let article = Article(title: title, content: content, footer: footer)
 
    let simple = SimpleDisplayArticle(article: article)
    let caption = CaptionDisplayArticle(article: article)
 
    simple.display()
    print()
    caption.display()
}
 
main()
 
ํ…œํ”Œ๋ฆฟ ๋ฉ”์„œ๋“œ
ํ•˜๊ณ  ์žˆ๋Š”๋ฐ ์กธ๋ฆฌ๋„ค์š”ใ…•
์–ผ๋งˆ ๋‚จ์ง€ ์•Š์•˜์œผ๋‹ˆ ๋์„ ๋ด์•ผํ•ฉ๋‹ˆ๋‹ค..
์˜ค๋Š˜์€ 230221
๋ฒŒ์จ 2์›”
๋‚˜๋Š” ์™„์ˆ™

Title: ํ…œํ”Œ๋ฆฟ ๋ฉ”์„œ๋“œ
Content: 
ํ•˜๊ณ  ์žˆ๋Š”๋ฐ ์กธ๋ฆฌ๋„ค์š”ใ…•
์–ผ๋งˆ ๋‚จ์ง€ ์•Š์•˜์œผ๋‹ˆ ๋์„ ๋ด์•ผํ•ฉ๋‹ˆ๋‹ค..
์˜ค๋Š˜์€ 230221
๋ฒŒ์จ 2์›”
Footer: ๋‚˜๋Š” ์™„์ˆ™

Article

//
//  Article.swift
//  TemplateMethod
//
//  Created by Choiwansik on 2023/02/21.
//
 
import Foundation
 
public struct Article {
 
    internal let title: String
    internal let content: [String]
    internal let footer: String
    
}
 

DisplayArticleTemplate

//
//  DisplayArticleTemplate.swift
//  TemplateMethod
//
//  Created by Choiwansik on 2023/02/21.
//
 
import Foundation
 
internal protocol DisplayArticleTemplate {
 
    func display()
 
    func title()
    func content()
    func footer()
 
}
 
extension DisplayArticleTemplate {
 
    internal func display() {
        self.title()
        self.content()
        self.footer()
    }
 
}
 

SimpleDisplayArticle

//
//  SimpleDisplayArticle.swift
//  TemplateMethod
//
//  Created by Choiwansik on 2023/02/21.
//
 
import Foundation
 
internal class SimpleDisplayArticle: DisplayArticleTemplate {
 
    internal init(article: Article) {
        self.article = article
    }
 
    internal func title() {
        print(self.article.title)
    }
 
    internal func content() {
        self.article.content.forEach { print($0) }
    }
 
    internal func footer() {
        print(self.article.footer)
    }
 
    private let article: Article
 
}
 

CaptionDisplayArticle

//
//  CaptionDisplayArticle.swift
//  TemplateMethod
//
//  Created by Choiwansik on 2023/02/21.
//
 
import Foundation
 
internal class CaptionDisplayArticle: DisplayArticleTemplate {
 
    internal init(article: Article) {
        self.article = article
    }
 
    internal func title() {
        print("Title: \(self.article.title)")
    }
 
    internal func content() {
        print("Content: ")
        self.article.content.forEach { print($0) }
    }
 
    internal func footer() {
        print("Footer: \(self.article.footer)")
    }
 
    private let article: Article
 
}
 

ํ™œ์šฉ์„ฑ

  • ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ๊ตฌ์กฐ๋Š” ๊ณ ์ •๋˜์–ด ์žˆ์œผ๋‚˜, ์ผ๋ถ€ ๋‹จ๊ณ„๊ฐ€ ๋‹ค์–‘ํ•œ ๊ตฌํ˜„์„ ํ•„์š”๋กœ ํ•˜๋Š” ๊ฒฝ์šฐ.
  • ์—ฌ๋Ÿฌ ํด๋ž˜์Šค์—์„œ ๊ณตํ†ต์œผ๋กœ ์‚ฌ์šฉ๋˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด ์žˆ์„ ๋•Œ, ์ค‘๋ณต ์ฝ”๋“œ๋ฅผ ์ œ๊ฑฐํ•˜๊ณ  ์žฌ์‚ฌ์šฉ์„ฑ์„ ๋†’์ด๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ.
  • ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ๊ตฌ์กฐ์™€ ์ผ๋ถ€ ๋‹จ๊ณ„๋Š” ๊ณ ์ •๋˜์–ด ์žˆ์ง€๋งŒ, ๋‹ค๋ฅธ ์ผ๋ถ€ ๋‹จ๊ณ„๋ฅผ ์„ ํƒ์ ์œผ๋กœ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ.

๊ฒฐ๊ณผ

  1. hook ์—ฐ์‚ฐ์„ ํ†ตํ•ด, ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ์ผ๋ถ€ ๋‹จ๊ณ„๋ฅผ ์„ ํƒ์ ์œผ๋กœ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.
  2. ์ฝ”๋“œ ์ค‘๋ณต์„ ์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ๋‹ค.
  3. ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ๊ตฌ์กฐ๋ฅผ ๋ช…ํ™•ํ•˜๊ฒŒ ๋ถ„๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.
  4. ๊ฐ ๋‹จ๊ณ„์˜ ์ฑ…์ž„์„ ๋ช…ํ™•ํžˆ ํ•  ์ˆ˜ ์žˆ๋‹ค.

๋‹ค๋งŒ, ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ๊ตฌ์กฐ๊ฐ€ ๊ฐ„๋‹จํ•œ ๊ฒฝ์šฐ, ๊ตณ์ด ์ด ํŒจํ„ด์„ ์‚ฌ์šฉํ•  ํ•„์š”๋Š” ์—†๋‹ค.

Reference