팩토리메소드(factory method) 패턴

객체를 생성하는 인터페이스를 만들고, 서브클래스에 객체 생성을 위임하는 객체 생성 패턴이다.
주 목적은 객체를 생성하는 Creator, 생성되는 객체인 Product간에 결합도를 낮춰
Creator와 Product간의 의존성을 줄이는 것이다.

예시

WhiteShip을 생성하는 공장에서 BlackShip을 새로 개발하려한다.

팩토리 메소드 구현 예제

객체를 생성하는 인터페이스

public interface ShipFactory {
    Ship orderShip(String name, String email);

    Ship createShip();

}

인터페이스에서 생성할 객체

public class Ship {

    private String name;

    private String color;

    private String logo;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public String getLogo() {
        return logo;
    }

    public void setLogo(String logo) {
        this.logo = logo;
    }

    @Override
    public String toString() {
        return "Ship{" +
                "name='" + name + '\'' +
                ", color='" + color + '\'' +
                ", logo='" + logo + '\'' +
                '}';
    }
}

겍체생성 공통 과정 추상클래스

public abstract class DefaultShipFactory implements ShipFactory{

    @Override
    public Ship orderShip(String name, String email) {
        validate(name, email);
        prepareFor(name);
        Ship ship = createShip();
        sendEmailTo(email, ship);

        return ship;
    }

    private static void validate(String name, String email) {
        if (name == null || name.isBlank()) {
            throw new IllegalArgumentException("배 이름을 지어주세요.");
        }
        if (email == null || email.isBlank()) {
            throw new IllegalArgumentException("연락처를 남겨주세요.");
        }
    }

    static void prepareFor(String name) {
        System.out.println(name + " 만들 준비 중");
    }

    static void sendEmailTo(String email, Ship ship) {
        System.out.println(ship.getName() + " 다 만들었습니다.");
    }
}

구체적인 생성할 객체들

public class WhiteShip extends Ship{

    public WhiteShip() {
        setColor("white");
        setName("WhiteShip");
        setLogo("\uD83D\uDEE5");
    }

}
public class BlackShip extends Ship {

    public BlackShip() {
        setColor("black");
        setLogo("⚓");
        setName("BlackShip");
    }
}

구체적인 객체들을 생성해주는 클래스들

public class WhiteShip extends Ship{

    public WhiteShip() {
        setColor("white");
        setName("WhiteShip");
        setLogo("\uD83D\uDEE5");
    }

}
public class BlackShipFactory extends DefaultShipFactory {

    @Override
    public Ship createShip() {
        return new BlackShip();
    }
}

클라이언트 코드

ShipFactory factory = new WhiteShipFactory();
Ship whiteShip = factory.orderShip("WhiteShip", "keesun@mail.com");
factory = new BlackShipFactory();
Ship blackShip = factory.orderShip("BlackShip", "keesun@mail.com");

클라이언트코드에서는 factory만 변경하면 product가 변경된다.

단, 구체적인 클래스를 정의해야하므로, 클래스가 많아지는 단점이 존재한다.

예제는 이곳 에서 확인하실수 있습니다.