Design Pattern

Factory Method Pattern

돌건 2022. 1. 15. 14:35

Factory Method Pattern

객체를 생성하기 위한 인터페이스를 정의하고,
어떤 클래스를 생성할 지는 서브 클래스가 결정하도록 하는 디자인 패턴

 

[팩토리 메서드 패턴 다이어그램]

출처: https://e7.pngegg.com/pngimages/649/269/png-clipart-factory-method-pattern-unified-modeling-language-class-diagram-factory-pattern-angle-white.png

 

Factory Method Pattern의 장단점

1. 확장에 열려있고 변경에 닫혀있는 객체 지향 원칙을 적용해 인스턴스를 생성하는 로직을 수정하지 않고, 새로운 인스턴스를 다른 방법으로 생성할 수 있도록 확장할 수 있다.

2. 인스턴스(Product), 팩토리(Creator) 간의 결합을 느슨하게 가져갈 수 있다. (확장성)

3. 클래스가 많아진다.

 

예제

1. 스마트폰 클래스 (Product)

public class SmartPhone {

    private String vendor;
    private String color;
    
    public String getVendor() {
        return this.vendor;
    }

    public void setVendor(String vendor) {
        this.vendor = vendor;
    }

    public String getColor () {
        return color;
    }

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

    @Override
    public String toString () {
        return "SmartPhone{" +
                "vendor='" + vendor + '\'' +
                ", color='" + color + '\'' +
                '}';
    }
}

 

2. 스마트폰 서브 클래스 (ConcreteProduct)

public class SamsungSmartPhone extends SmartPhone {

    public SamsungSmartPhone (String color) {

        setVendor( "Samsung" );
        setColor( color );
        System.out.println("삼성 스마트폰 생성...");
    }
}

//--------------------------------------------------

public class AppleSmartPhone extends SmartPhone {

    public AppleSmartPhone (String color) {

        setVendor( "Apple" );
        setColor( color );
        System.out.println("애플 스마트폰 생성...");
    }
}

 

3. 스마트폰 팩토리 인터페이스 (Creator)

public interface SmartPhoneFactory {

    default SmartPhone orderSmartPhone (String color) {

        return createSmartPhone(color);
    }

    SmartPhone createSmartPhone(String color);
}

 

4. 스마트폰 팩토리 서브 클래스 (ConcreteCreator)

public class SamsungSmartPhoneFactory implements SmartPhoneFactory {

    @Override
    public SmartPhone createSmartPhone (String color) {

        return new SamsungSmartPhone(color);
    }
}

//--------------------------------------------------------------------

public class AppleSmartPhoneFactory implements SmartPhoneFactory {

    @Override
    public SmartPhone createSmartPhone (String color) {

        return new AppleSmartPhone(color);
    }
}

 

5. 클라이언트

public class Client {

    public static void main (String[] args) {

        SmartPhoneFactory samsungSmartPhoneFactory = new SamsungSmartPhoneFactory();
        SmartPhoneFactory appleSmartPhoneFactory = new AppleSmartPhoneFactory();

        SmartPhone samsungSmartPhone = samsungSmartPhoneFactory.orderSmartPhone("용달블루");
        SmartPhone appleSmartPhone = appleSmartPhoneFactory.orderSmartPhone("그래파이트");

        System.out.println( "samsungSmartPhone = " + samsungSmartPhone );
        System.out.println( "appleSmartPhone = " + appleSmartPhone );
    }
}

 

6. 결과

위 예제를 통해 볼 수 있듯이 ConcreteCreator, ConcreteProduct를 수정하지 않고 새로운 인스턴스를 생성하는 로직을 추가할 수 있다. 따라서, 확장에는 열려 있고 변경에는 닫혀있는 객체 지향 원리를 적용할 수 있게 된다. 단, 새로운 인스턴스 생성 로직(Creator, Product)를 추가함에 따라 클래스의 수는 늘어나게 된다.

 

 

참고: 백기선 - 코딩으로 학습하는 GoF의 디자인 패턴 (인프런)