반응형
4. 각 패턴별 이해
4.1. 추상 팩토리(Abstract Factory)
- 구체적인 클래스를 지정하지 않고 관련성을 갖는 객체들의 집합을 생성하거나 서로 독립적인 객체들의 집합을 생성할 수 있는 인터페이스를 제공
- 관련성 있는 여러 종류의 객체를 일관된 방식으로 생성하는 경우에 유용
4.1.1. 구조
4.1.2. 참여 객체
- AbstractFactory: 개념적 제품에 대한 객체를 생성하는 오퍼레이션으로 인터페이스를 정의한다.
- 실제 팩토리 클래스의 공통 인터페이스
- ConcreateFactory: 구체적인 제품에 대한 객체를 생성하는 오퍼레이션을 구현한다.
- AbstractFactory 클래스의 추상 메서드를 오버라이드함
- AbstractProduct: 개념적 제품 객체에 대한 인터페이스를 정의한다.
- 제품의 공통 인터페이스 이용
- ConcreateProduct: 구체적으로 팩토리가 생성할 객체를 정의하고, AbstractProduct 가 정의하고 있는 인터페이스를 구현한다.
- 구체적인 팩토리 클래스에서 생성되는 제품
- Client: AbstractFactory 와 AbstractProduct 클래스에 선언된 인터페이스를 사용한다.
/*
해당 코드는 swift로 작성됨.
ConcreateFactory: 버튼, 모터에 대한 인터페이스를 구상
ConcreateProduct: 자동차 창문을 올렸다 내리는 버튼과 모터, 간이 엘레베이터를 올리고 내릴 수 있는 버튼과 모터라는 구체적인 제품 클래스
AbstractFactory: 버튼과 모터를 특정 군에 맞게 생산해 낼 수 있는 인터페이스
AbstractProduct: 자동차 창문용 제품군, 간이 엘레베이터 제품군을 생산해내는 클래스
*/
// ConcreateFactory1
protocol Button {
var standard: String { get }
func up() -> String
func down() -> String
}
// ConcreateFactory2
protocol Motor {
var standard: String { get }
func rotateCounterClockwise() -> String
func rotateClockwise() -> String
}
// ConcreateProduct 1 A
class CarWindowButton: Button {
var standard: String
init() {
self.standard = "자동차용 창문 버튼"
}
func up() -> String {
return "자동차 창문을 위로 올립니다."
}
func down() -> String {
return "자동차 창문을 아래로 내립니다."
}
}
// ConcreateProduct 1 B
class ElevatorUpDownButton: Button {
var standard: String
init() {
self.standard = "간이 엘리베이터용 버튼"
}
func up() -> String {
return "간이 엘리베이터를 위로 올립니다."
}
func down() -> String {
return "간이 엘리베이터를 아래로 내립니다."
}
}
// ConcreateProduct 2 A
class CarWindowMotor: Motor {
var standard: String
init() {
self.standard = "자동차용 창문 모터"
}
func rotateCounterClockwise() -> String {
return "모터가 반시계 방향으로 돌아갑니다."
}
func rotateClockwise() -> String {
return "모터가 시계 방향으로 돌아갑니다."
}
}
// ConcreateProduct 2 B
class ElevatorMotor: Motor {
var standard: String
init() {
self.standard = "엘리베이터용 모터"
}
func rotateCounterClockwise() -> String {
return "모터가 반시계 방향으로 돌아갑니다."
}
func rotateClockwise() -> String {
return "모터가 시계 방향으로 돌아갑니다."
}
}
// AbstractFactory
protocol ProductFactory {
var storage: [Any] {get set}
func createButton() -> Button
func createMotor() -> Motor
func checkProduct()
}
// Abstract Product A
class CarWindowProduct: ProductFactory {
var storage: [Any] = [Any]()
func createButton() -> Button {
let tmpButton = CarWindowButton()
print("이 버튼의 규격은 \(tmpButton.standard) 이고, up을 누려면 \(tmpButton.up()) 그리고 down을 누르면 \(tmpButton.down())\n")
storage.append(tmpButton)
return tmpButton
}
func createMotor() -> Motor {
let tmpMotor = CarWindowMotor()
print("이 모터의 규격은 \(tmpMotor.standard) 이고, \(tmpMotor.rotateClockwise()) 그리고 \(tmpMotor.rotateCounterClockwise())\n")
storage.append(tmpMotor)
return CarWindowMotor()
}
func checkProduct() {
var bCount = 0
var mCount = 0
for product in storage {
switch product {
case is Button:
bCount += 1
break
case is Motor:
mCount += 1
break
default:
print("unknow product")
}
}
print("버튼은 \(bCount) 개 이고, 모터는 \(mCount) 개 이다.\n")
}
}
// Abstract Product B
class ElevatorProduct: ProductFactory {
var storage: [Any] = [Any]()
func createButton() -> Button {
let tmpButton = ElevatorUpDownButton()
print("이 버튼의 규격은 \(tmpButton.standard) 이고, up을 누려면 \(tmpButton.up()) 그리고 down을 누르면 \(tmpButton.down())\n")
storage.append(tmpButton)
return tmpButton
}
func createMotor() -> Motor {
let tmpMotor = ElevatorMotor()
print("이 모터의 규격은 \(tmpMotor.standard) 이고, \(tmpMotor.rotateClockwise()) 그리고 \(tmpMotor.rotateCounterClockwise())\n")
storage.append(tmpMotor)
return tmpMotor
}
func checkProduct() {
var bCount = 0
var mCount = 0
for product in storage {
switch product {
case is Button:
bCount += 1
break
case is Motor:
mCount += 1
break
default:
print("unknow product")
}
}
print("버튼은 \(bCount) 개 이고, 모터는 \(mCount) 개 이다.\n")
}
}
let abstractProductA = CarWindowProduct()
let productAButton1 = abstractProductA.createButton()
let productAMotor1 = abstractProductA.createMotor()
let productAButton2 = abstractProductA.createButton()
abstractProductA.checkProduct()
let abstractProductB = ElevatorProduct()
let productBButton1 = abstractProductB.createButton()
let productBMotor1 = abstractProductB.createMotor()
abstractProductB.checkProduct()
/* 결과
이 버튼의 규격은 자동차용 창문 버튼 이고, up을 누려면 자동차 창문을 위로 올립니다. 그리고 down을 누르면 자동차 창문을 아래로 내립니다.
이 모터의 규격은 자동차용 창문 모터 이고, 모터가 시계 방향으로 돌아갑니다. 그리고 모터가 반시계 방향으로 돌아갑니다.
이 버튼의 규격은 자동차용 창문 버튼 이고, up을 누려면 자동차 창문을 위로 올립니다. 그리고 down을 누르면 자동차 창문을 아래로 내립니다.
버튼은 2 개 이고, 모터는 1 개 이다.
이 버튼의 규격은 간이 엘리베이터용 버튼 이고, up을 누려면 간이 엘리베이터를 위로 올립니다. 그리고 down을 누르면 간이 엘리베이터를 아래로 내립니다.
이 모터의 규격은 엘리베이터용 모터 이고, 모터가 시계 방향으로 돌아갑니다. 그리고 모터가 반시계 방향으로 돌아갑니다.
버튼은 1 개 이고, 모터는 1 개 이다.
*/
반응형