지난시간엔 템플릿 메소드 패턴에 대해 알아보았다.
팩토리 메소드 패턴은 구조가 비슷한데 인스턴스를 템플릿 메소드 패턴처럼 다루는 패턴이다.
(안봐도 되긴한데 보고오면 더 좋다, 템플릿메소드패턴)
팩토리 메소드 패턴은 인스턴스 생성방법을 상위 클래스에서 형태만 정의하고 하위 클래스에서 정확하게 구현하는 패턴이다
이는 객체 생성을 특정 클래스의 인스턴스를 해당 클래스의 생성자를 통해서 만드는것이 아닌 특정 메소드를 통해서 객체를 생성(싱글톤에서 사용하는 방식) 하기에 가능한 형태이다.
템플릿 메소드 패턴처럼 팩토리 메소드 패턴에도 팩토리 메소드라는 존재가 있다
여기서 객체를 생성하고 템플릿메소드처럼 객체 생성에 필요한 클래스 내 추상 함수를 호출해서 구현한다.
추상적인 구조는 이미지와 같다.
다음과 같은 구조의 소스코드이다
package framework;
public abstract class Product {
public abstract void use();
}
package framework;
public abstract class Factory {
public final Product create(String owner) {
Product p = createProduct(owner);
//Product p = this.createProduct(owner);
registerProduct(p);
return p;
}
protected abstract Product createProduct(String owner);
protected abstract void registerProduct(Product product);
}
package idcard;
public class IDCard extends Product {
private String owner;
IDCard(String owner) {
System.out.println(owner + "의 카드를 만듭니다.");
this.owner = owner;
}
@Override
public void use() {
System.out.println(this + "을 사용합니다.");
}
@Override
public String toString() {
return "[IDCard:" + owner + "]";
}
public String getOwner() {
return owner;
}
}
package idcard;
public class IDCardFactory extends Factory {
//객체 생성
@Override
protected Product createProduct(String owner) {
return new IDCard(owner);
}
@Override
protected void registerProduct(Product product) {
System.out.println(product + "을 등록했습니다");
}
}
import framework.Factory;
import framework.Product;
import idcard.IDCardFactory;
public class Main {
public static void main(String[] args) {
Factory factory = new IDCardFactory();
Product card1 = factory.create("Youngjin Kim");
Product card2 = factory.create("Heungmin Son");
Product card3 = factory.create("Kane");
card1.use();
card2.use();
card3.use();
}
}
Factory가 Creator
IDCardFactory가 Concreatecreator
Product는 그대로
IDCard는 ConcreateProduct의 역할을 수행한다.
전체적으로 factory가 생성을 Product가 틀의 역할을 맡는 느낌이라고 생각하면 된다.
import Foundation
// Product 프로토콜 정의
//CustomStringConvertible: java의 toString()을 대체 하기 위해 print할때 문자열을 수정할 수 있게 해주는 프로토콜
protocol Product: CustomStringConvertible {
func use()
}
// Factory 프로토콜 정의
protocol Factory {
func createProduct(owner: String) -> Product
func registerProduct(product: Product)
}
// Factory 프로토콜 확장, 기본 구현 메소드인 create를 위해서 확장을 사용함
extension Factory {
func create(owner: String) -> Product {
let product = createProduct(owner: owner)
registerProduct(product: product)
return product
}
}
// IDCard 클래스
class IDCard: Product {
private let owner: String
init(owner: String) {
self.owner = owner
print("\(owner)의 카드를 만듭니다.")
}
func use() {
// self를 사용하여 출력
print("\(self) 을 사용합니다.")
}
// CustomStringConvertible을 사용하여 self를 출력
var description: String {
return "[IDCard: \(owner)]"
}
func getOwner() -> String {
return owner
}
}
// IDCardFactory 클래스
class IDCardFactory: Factory {
func createProduct(owner: String) -> Product {
return IDCard(owner: owner)
}
func registerProduct(product: Product) {
// self를 사용하여 출력
print("\(product) 을 등록했습니다.")
}
}
// 메인 실행
let factory = IDCardFactory()
let card1 = factory.create(owner: "Youngjin Kim")
let card2 = factory.create(owner: "Heungmin Son")
let card3 = factory.create(owner: "Kane")
card1.use()
card2.use()
card3.use()
swift에는 추상클래스가 없어서 프로토콜을 사용하고 기본구현이 필요했던 create()메소드의 경우 extension의 기본구현 기능을 이용해서 구현했다
또한 toString()을 이용한 콘솔 출력방법이 Swift에서는 지원하지 않으므로 CustomStringConvertible프로토콜을 이용해서 print되는 텍스트를 수정하도록 하였다.