CS (Computer Science)

[CS스터디] 디자인 패턴 - 팩토리 패턴 (factory pattern)

공삼이 2023. 4. 3. 17:13

팩토리 패턴 factory

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

상위클래스, 하위클래스가 분리되어 느슨한 결합을 가지며 상위 클래스에서는 인스턴스 생성 방식에 대해 전혀 알 필요가 없기 때문에 더 많은 유연성을 갖게 된다.

객체 생성 로직이 따로 떼어져 있기 때문에 코드를 리팩터링하더라도 한 곳만 고칠 수 잇게 되니 유지 보수성이 증가.

상위 클래스 : 레시피 같은 거!!! 라떼 레시피, 아메리카노 레시피,,,

하위 클래스 : 레시피 토대로 생산하는 공장 같은 거!!

자바스크립트

const num = new Object(42)
const str = new Object('abc')
num.constructor.name; //Number
str.constructor.name; //String

숫자를 전달하거나 문자열을 전달함에 따라 다른 타입의 객체를 만든다.

전달 받은 값에 따라 다른 객체를 생성하며, 인스턴스의 타입 등을 정한다.

class Latte{
	constructor() {
		this.name = "latte"
	}
}

class Espresso {
	constructor() {
		this.name = "Espresso"
	}
}

class LatteFactory {
	static createCoffee(){
		return new Latte()
	}
{

class EspressoFactory {
	static createCoffee(){
		return new Espresso()
	}
}

const factoryList = {LatteFactory, EspressoFactory}

class CoffeeFactory {  //상위 클래스
	static createCoffee(type){
		const factory = factoryList[type]
		return factory.createCoffee()
	}
}

const main = () => {
	//라떼 커피를 주문한다.
	const coffee = CoffeFactory.createCoffee("LatteFactory")
	//커피 이름을 부른다.
	console.log(coffee.name) //latte
}

main()

CoffeeFactory라는 상위 클래스가 뼈대 결정.

하위 클래스 LatteFactory가 구체적인 내용 결정.

의존성 주입이라고도 볼 수 있다. 왜냐?? 상위 클래스에서 하위클래스의 인스턴스를 생성하는 것이 아니라, 하위 클래스에서 생성한 인스턴스를 상위 클래스에 주입하고 있음!

CoffeeFactory를 보면 static으로 createCoffee()라는 정적 메서드를 정의하고 있다. 정적 메서드를 쓰면 클래스의 인스턴스 없이 호출이 가능하여 메모리 절약이 가능. 개별 인스턴스에 묶이지 않으며 클래스 내의 함수를 정의할 수 있는 장점이 있다.

자바

abstract class Coffee { 
    public abstract int getPrice(); 
    
    @Override
    public String toString(){
        return "Hi this coffee is "+ this.getPrice();
    }
}

class CoffeeFactory { 
    public static Coffee getCoffee(String type, int price){
        if("Latte".equalsIgnoreCase(type)) return new Latte(price);
        else if("Americano".equalsIgnoreCase(type)) return new Americano(price);
        else{
            return new DefaultCoffee();
        } 
    }
}
class DefaultCoffee extends Coffee {
    private int price;

    public DefaultCoffee() {
        this.price = -1;
    }

    @Override
    public int getPrice() {
        return this.price;
    }
}
class Latte extends Coffee { 
    private int price; 
    
    public Latte(int price){
        this.price=price; 
    }
    @Override
    public int getPrice() {
        return this.price;
    } 
}
class Americano extends Coffee { 
    private int price; 
    
    public Americano(int price){
        this.price=price; 
    }
    @Override
    public int getPrice() {
        return this.price;
    } 
} 
public class HelloWorld{ 
     public static void main(String []args){ 
        Coffee latte = CoffeeFactory.getCoffee("Latte", 4000);
        Coffee ame = CoffeeFactory.getCoffee("Americano",3000); 
        System.out.println("Factory latte ::"+latte);
        System.out.println("Factory ame ::"+ame); 
     }
} 
/*
Factory latte ::Hi this coffee is 4000
Factory ame ::Hi this coffee is 3000
*/