Notice
Recent Posts
Recent Comments
Link
Tags
- 스위프트
- Human Interface Guidelines
- 앱개발
- IOS
- CollectionView
- WWDC
- Combine+UIKit
- lineBreakStrategy
- Keychain
- 야곰아카데미
- GOF
- UILabel
- TOSS
- orthogonalScrollingBehavior
- UIKit
- HIG
- 애플
- DiffableDataSource
- Accessibility
- github
- Split View
- 전달인자 레이블
- 디자인패턴
- iTerm
- Apple
- 애플사이다
- iPad
- Swift
- LanguageGuide
- lineBreakMode
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- Today
- Total
애플사이다의 iOS 개발 일지
[디자인 패턴] Prototype - 의존성 없이 객체를 복사할 때 본문
GoF 디자인 패턴 중 하나인 Prototype 패턴을 정리했다.
- Ref : 도서 <Dive into Design Patterns>, Alexander Shvets 저
문제 상황
- 객체 A가 있고, 해당 객체의 복사본을 만들고 싶은 상황이다.
- 이때 새로운 객체 인스턴스를 생성하고, 원본 (객체 A)의 프로퍼티 값들을 새 객체에 모두 복사하는 방법이 있다.
- 문제점 : 객체의 프로퍼티 중 일부가 비공개라면 외부에서 접근할 수 없다. 또한 복사하려면 원본을 알아야 하므로 해당 객체에 대한 의존성이 생긴다.
패턴 설명
- 요약 : 의존성 없이 객체를 복사하는 생성 패턴이다.
- Prototype = 시제품, 시험용으로 만들어 본 샘플 제품
- 실제 산업의 프로토타입 : 대량 생산 이전에 테스트용으로 만드는 샘플 제품
- 프로그래밍의 프로토타입 : 세포 분열과 비슷함. ‘원본 세포’는 복사본을 만들어내기 위한 ‘프로토타입 역할’을 함
- 복제를 지원하는 객체를 ‘프로토타입’이라고 부른다.
- 매번 객체를 처음부터 새로 만들지 않는다.
- ‘복제되는 객체’에게 복제 프로세스를 위임한다. (설정값을 지정하여 미리 만들어둔 프로토타입을 복제해서 쓴다.)
- Prototype Protocol : clone 메서드를 정의한다. (반환타입은 Prototype Protocol 자기 자신이다.)
- ConcretePrototype : clone 메서드를 구현한다. (원본 객체의 프로퍼티값을 복사한다.)
- Client : Prototype Protocol을 채택한 모든 객체의 복사본을 생성 가능하다.
예시 코드
// MARK: - Prototype Protocol
protocol Prototype {
init(prototype: Self)
}
extension Prototype {
func clone() -> Self {
return type(of: self).init(prototype: self)
}
}
// MARK: - Concrete Prototype
class ConcretePrototype1: Prototype {
var name: String
var weight: Double
init(name: String, weight: Double) {
self.name = name
self.weight = weight
}
required convenience init(prototype: ConcretePrototype1) {
self.init(name: prototype.name, weight: prototype.weight)
}
func printStatus() {
print("ConcretePrototype1 - name \(name) / weight \(weight)")
}
}
class ConcretePrototype2: Prototype {
var name: String
var weight: Double
init(name: String, weight: Double) {
self.name = name
self.weight = weight
}
required convenience init(prototype: ConcretePrototype2) {
self.init(name: prototype.name, weight: prototype.weight)
}
func printStatus() {
print("ConcretePrototype2 - name \(name) / weight \(weight)")
}
}
// MARK: - Client
class Client {
func main() {
let concrete1 = ConcretePrototype1(name: "con1", weight: 1.0)
let concrete2 = ConcretePrototype2(name: "con2", weight: 2.0)
print("Original")
concrete1.printStatus()
concrete2.printStatus()
let copied1 = concrete1.clone() // 완전히 새로운 객체 (원본의 참조가 복사된 게 아님)
let copied2 = concrete2.clone()
print("Clone")
copied1.printStatus()
copied2.printStatus()
print("---")
copied1.weight += 10.0 // 원본에 영향을 미치지 않음
concrete1.printStatus() // 1
copied1.printStatus() // 11
}
}
//Original
//ConcretePrototype1 - name con1 / weight 1.0
//ConcretePrototype2 - name con2 / weight 2.0
//Clone
//ConcretePrototype1 - name con1 / weight 1.0
//ConcretePrototype2 - name con2 / weight 2.0
//---
//ConcretePrototype1 - name con1 / weight 1.0
//ConcretePrototype1 - name con1 / weight 11.0
장점
- 복사할 객체에 대한 의존성을 없앤다.
- 중복되는 initializer 코드를 제거할 수 있다. (만들어 둔 프로토타입을 복제해서 쓰면 되므로)
- 복잡한 객체를 쉽게 생성한다.
- 복잡한 객체에 대한 설정값을 처리할 때 상속 대신 사용 가능한 방법이다.
단점
- 순환 참조를 하는 복잡한 객체를 복제하는 것은 어려울 수 있다.
- Reference
🍎 포스트가 도움이 되었다면, 공감🤍 / 구독🍹 / 공유🔗 / 댓글✏️ 로 응원해주세요. 감사합니다.
'프로그래밍 철학' 카테고리의 다른 글
[디자인 패턴] Command - 실행할 작업을 덩어리로 관리할 때 (0) | 2023.07.02 |
---|---|
[toss] iOS 개발자를 위한 SLASH23 리뷰 (7) | 2023.06.18 |
[toss] iOS 개발자를 위한 SIMPLICITY23 리뷰 - 디자이너와 친해지기 (7) | 2023.06.04 |
[디자인 패턴] Singleton (0) | 2023.03.26 |
[디자인 패턴] Builder - 초기화 과정이 복잡할 때 (0) | 2023.02.20 |
Comments