디자인 패턴 : 팩토리 패턴

timothy jeong·2022년 7월 9일
0

디자인패턴

목록 보기
2/2

팩토리 패턴

팩토리 패턴이란 객체를 사용하는 코드에서 객체 생성 부분을 떼어내 추상화한 패턴이자 상속 관계에 있는 두 클래스에서 상위 클래스가 중요한 뼈대를 결정하고, 하위 클래스에서 객체 생성에 대한 구체적인 내용을 결정하는 패턴이다.

팩토리 패턴 왜 사용하나

OOP의 기본 원칙중 SOLID 에는 OCP(Open Closed Principle) 이라고 하여 프로그램이 확장에는 열려있고, 수정에는 닫혀있어야 한다는 원칙이 있다.

팩토리 패턴은 기능의 확장, 변화에 따라 쉽게 변화할 수 있는 구현체(하위 클래스)의 생성은 구현체가 담당하고, 그 구현체를 주입하는 역할을 팩토리 객체게 위임함으로써 기능의 변화, 확장에 따라 수정해야하는 코드량을 최소화할 수 있다는 장점이 있다.

장점

(1) 팩토리 패턴을 이용하면 상위 클래스와 하위 클래스가 분리되므로 결합도가 낮아진다.
(2) 상위 클래스에서는 하위 클래스에 대한 정보를 전혀 알 필요가 없으므로 유연성을 갖게된다.
(3) 객체 생성 로직이 따로 떼어져 있기 때문에 코드를 리팩터링하더라도 한 곳만 신경쓰면 된다.

단점

(1) 팩토리 패턴을 구현하기 위해서는 많은 서브 클래스가 만들어지므로 코드가 복잡해질 수 있다.

구현

java

Product 라는 상위 클래스가 구현체의 뼈대를 잡고, 구현체(하위 클래스)를 각각 정의한다. 그리고 팩토리 객체는 상위 클래스를 반환하도록 함으로써, Product에 의존하는 클래스에 손쉽게 의존성을 주입해줄 수 있다.

public class Main {
    public static void main(String[] args) {
        System.out.println(ProductFactory.getProduct(ProductName.RANDOM, 1000));
        System.out.println(ProductFactory.getProduct(ProductName.MILK, 2000));
        System.out.println(ProductFactory.getProduct(ProductName.APPLE, 4000));
    }
}

enum ProductName {
    MILK, APPLE, RANDOM
}

abstract class Product {
    public abstract int getPrice();

    @Override
    public String toString() {
        return "Hi this product is " + this.getPrice();
    }
}

class ProductFactory {
    public static Product getProduct(ProductName type, int price) {
        String hello;
        switch (type) {
            case MILK :
                return new MILK(price);
            case APPLE:
                return new APPLE(price);
            default:
               return new DefaultProduct(price);
        }

    }
}

class DefaultProduct extends Product {

    private final int price;

    public DefaultProduct(int price) {
        this.price = price;
    }

    @Override
    public int getPrice() {
        return this.price;
    }
}

class MILK extends Product {
    private final int price;

    public MILK(int price) {
        this.price = price;
    }

    @Override
    public int getPrice() {
        return this.price;
    }
}

class APPLE extends Product {
    private final int price;

    public APPLE(int price) {
        this.price = price;
    }
    @Override
    public int getPrice() {
        return this.price;
    }
}

kotlin

kotlin 을 사용하면 정말 코드량이 적어진다.

interface Currency {
    val code: String
}

class Euro(override val code: String = "EUR") : Currency
class UnitedStatesDollar(override val code: String = "USD") : Currency

enum class Country {
    UnitedStates, Spain, UK, Greece
}

class CurrencyFactory {
    fun currencyForCountry(country: Country): Currency? {
        return when (country) {
            Country.Spain, Country.Greece -> Euro()
            Country.UnitedStates          -> UnitedStatesDollar()
            else                          -> null
                }
    }
}

link : 코드 출처

javascript

class Product1 {
    constructor() {
        this.name = "Product1";
    };
}

class Product2 {
    constructor() {
        this.name = "Product2";
    };
}

class Factory1 {
    static createProduct() {
        return new Product1();
    };
}

class Factory2 {
    static createProduct() {
        return new Product2();
    };
}

const factories =  { Factory1, Factory2 }

class Factory {
    static createProduct(type) {
        const factory = factories[type];
        return factory.createProduct();
    };
}

const product = Factory.createProduct("Factory1")
console.log(product.name)
profile
개발자

0개의 댓글