생성(Creational) 패턴
객체 생성 처리를 서브 클래스로 분리 해 처리하도록 캡슐화하는 패턴
객체를 생성하기 위해 인터페이스를 정의하지만, 어떤 클래스의 인스턴스를 생성할지에 대한 결정은 서브클래스가 내리도록 한다
Product.class
public abstract class Product {
public abstract void use();
}
IDCard.class
public class IDCard extends Product{
private String owner;
public IDCard(String owner) {
System.out.println(owner + "의 카드를 만듭니다.");
this.owner = owner;
}
@Override
public void use() {
System.out.println(owner + "의 카드를 사용합니다.");
}
public String getOwner() {
return owner;
}
}
Factory.class
public abstract class Factory {
public final Product create(String owner) {
Product p = createProduct(owner);
registerProduct(p);
return p;
}
protected abstract Product createProduct(String owner);
protected abstract void registerProduct(Product p);
}
create(String owner)
와 createProduct(String owner)
, Product를 등록할 registerProduct(Product p)
를 선언한다IDCardFactory.class
public class IDCardFactory extends Factory {
private List<String> owners = new ArrayList<>();
@Override
protected Product createProduct(String owner) {
return new IDCard(owner);
}
@Override
protected void registerProduct(Product p) {
owners.add(((IDCard) p).getOwner());
}
public List<String> getOwners() {
return owners;
}
}
Main.class
public static void main(String[] args) {
Factory factory = new IDCardFactory();
Product card1 = factory.create("홍길동");
Product card2 = factory.create("김정태");
Product card3 = factory.create("손수영");
card1.use();
card2.use();
card3.use();
}
홍길동의 카드를 만듭니다.
김정태의 카드를 만듭니다.
손수영의 카드를 만듭니다.
홍길동의 카드를 사용합니다.
김정태의 카드를 사용합니다.
손수영의 카드를 사용합니다.
현재 Factory는 Product의 IDCard 하나만 담당하고 있다. 하지만 차후 IDCard가 여러개 생간다면 그에 맞춰 Factory는 어떻게 구현해야할까?
S사, N사, K사 종류의 IDCard가 생겼다고 가정하자.
K_IDCard.class
public class K_IDCard extends Product{
private String owner;
public K_IDCard(String owner) {
System.out.println("K사의 " + owner + "의 카드를 만듭니다.");
this.owner = owner;
}
@Override
public void use() {
System.out.println("K사의 " + owner + "의 카드를 사용합니다.");
}
public String getOwner() {
return owner;
}
}
Factory.class
public abstract class Factory {
public final Product create(String company, String owner) throws ClassNotFoundException {
Product p = createProduct(company, owner); // 변경. company 구분자 추가
registerProduct(p);
return p;
}
protected abstract Product createProduct(String company, String owner) throws ClassNotFoundException; // // 변경. company 구분자 추가
}
registerProduct
는 제거했다IDCardFactory.class
public class IDCardFactory extends Factory {
private List<String> owners = new ArrayList<>();
@Override
protected Product createProduct(String company, String owner) throws ClassNotFoundException {
if ("S".equals(company)) { // 변경 - 구분자에 맞는 Class 반환
return new S_IDCard(owner);
} else if ("N".equals(company)) {
return new N_IDCard(owner);
} else if ("K".equals(company)) {
return new K_IDCard(owner);
} else {
throw new ClassNotFoundException("No Search IDCard. Please Check Company");
}
}
@Override
protected void registerProduct(Product p) {
owners.add(((K_IDCard) p).getOwner());
}
public List<String> getOwners() {
return owners;
}
}
Main.class
public static void main(String[] args) throws ClassNotFoundException {
Factory factory = new IDCardFactory();
Product card1 = factory.create("N", "홍길동");
Product card2 = factory.create("S", "김정태");
Product card3 = factory.create("K", "손수영");
card1.use();
card2.use();
card3.use();
}
N사의 홍길동의 카드를 만듭니다.
S사의 김정태의 카드를 만듭니다.
K사의 손수영의 카드를 만듭니다.
N사의 홍길동의 카드를 사용합니다.
S사의 김정태의 카드를 사용합니다.
K사의 손수영의 카드를 사용합니다.
참조: