Chapter 4. Factory Method : 인스턴스 생성을 하위 클래스에게 위임

sua·2022년 4월 9일
0
post-thumbnail

1. 예제 프로그램 - 신분증(ID 카드)을 만드는 공장
<Product.java>

package ch04.Sample.framework;

// 구체적인 제품들이 가져야 메소드를 정의한 추상 클래스
public abstract class Product {
    public abstract void use();
}

<Factory.java>

package ch04.Sample.framework;

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 product);
}

<IDCard.java>

package ch04.Sample.idcard;

import ch04.Sample.framework.*;

public class IDCard extends Product {
    private String owner;

    // private이나 public 으로 선언되어 있지 않으면, 
    // 같은 패키지에 속한 클래스들만이 이 생성자를 호출할 수 있다.
    IDCard(String owner) {
        System.out.println(owner + "의 카드를 만듭니다.");
        this.owner = owner;
    }
    public void use() {
        System.out.println(owner + "의 카드를 사용합니다.");
    }
    public String getOwner() {
        return owner;
    }
}

<IDCardFactory.java>

package ch04.Sample.idcard;

import ch04.Sample.framework.*;
import java.util.*;

public class IDCardFactory extends Factory {
	// Vector는 배열과 비슷하지만 전체 크기가 정해져 있지 않고
	// 원소를 추가하면 필요한 경우 크기가 늘어난다.
    private Vector owners = new Vector();

	// 이 공장의 제품인 IDCard를 생산한다.
    protected Product createProduct(String owner) {
        return new IDCard(owner);
    }

	// 생산된 제품의 owner를 등록(추가)한다.
    protected void registerProduct(Product product) {
        // product 를 IDCard로 형변환해야, getOwner()를 호출할 수 있다.
		owners.add(((IDCard)product).getOwner());
    }
    public Vector getOwners() {
        return owners;
    }
}

<Main.java>

package ch04.Sample;

import ch04.Sample.framework.*;
import ch04.Sample.idcard.*;

public class Main {
    public static void main(String[] args) {

      // IDCard( ) 생성자가 public이 아니라, 아래 문장은 오류가 발생한다.	
      //IDCard card1 = new IDCard("홍길동");

		// 공장을 세운다.
        Factory factory = new IDCardFactory();
        
		// 공장을 이용해서 제품(IDCard를 생산한다) 
		Product card1 = factory.create("홍길동");
        Product card2 = factory.create("이순신");
        Product card3 = factory.create("강감찬");

		// 생산된 제품을 사용한다.
        card1.use();
        card2.use();
        card3.use();
    }
}


2. 연습 문제 - IDCard 제품 생성시 Serial 번호를 붙인다
<Product.java>

package ch04.A2.framework;

public abstract class Product {
    public abstract void use();
}

<Factory.java>

package ch04.A2.framework;

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 product);
}

<IDCard.java>

package ch04.A2.idcard;

import ch04.A2.framework.*;

public class IDCard extends Product {
    private String owner;
    private int serial;
    IDCard(String owner, int serial) {
        System.out.println(owner + "(" + serial + ")" + "의 카드를 만듭니다.");
        this.owner = owner;
        this.serial = serial;
    }
    public void use() {
        System.out.println(owner + "(" + serial + ")" + "의 카드를 사용합니다.");
    }
    public String getOwner() {
        return owner;
    }
    public int getSerial() {
        return serial;
    }
}

<IDCardFactory.java>

package ch04.A2.idcard;
import ch04.A2.framework.*;
import java.util.*;

public class IDCardFactory extends Factory {
    private Hashtable database = new Hashtable();
    private int serial = 100;
    protected synchronized Product createProduct(String owner) {
        return new IDCard(owner, serial++);
    }
    protected void registerProduct(Product product) {
        IDCard card = (IDCard)product;
        database.put(card.getOwner(), new Integer(card.getSerial()));
    }
    public Hashtable getDatabase() {
        return database;
    }
}

<Main.java>

package ch04.A2;

import ch04.A2.framework.*;
import ch04.A2.idcard.*;

public class Main {
    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();
    }
}

profile
가보자고

0개의 댓글

관련 채용 정보