팩토리패턴

HS K·2023년 2월 13일
0
post-custom-banner

팩토리패턴

객체를 사용하는 코드에서 객체 생성 부분을 떼어내 추상화한 패턴

  • 상속 관계에 있는 두 클래스에서 상위 클래스가 중요한 뼈대를 결정하고, 하위 클래스에서 객체 생성에 관한 구체적인 내용을 결정하는 패턴

※ 상위 클래스와 하위 클래스가 분리되기 때문에 느슨한 결합을 가지며, 상위 클래스에서는 인스턴스 생성방식에 대해 전혀 알 필요가 없기 때문에 더 많은 유연성을 갖게된다.
그리고 객체 생성 로직이 따로 떼어져 있기 때문에 코드를 리팩토링 하더라도 한 곳만 고칠 수 있게된다.


라떼 레시피와 아메리카노 레시피, 우유 레시피라는 구체적인 내용이 들어 있는 하위 클래스가 컨베이어 벨트를 통해 전달되고, 상위 클래스인 바리스타 공장에서 이 레시피들을 토대로 우유 등을 생산하는 생산공정을 만들어보자.


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

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

class LatteFactory {
    static createCoffee() {
        return new Latte()
    }
}
//Latte를 만드는 구체적인 방법이 들어가있으며, Latte를 리턴 

class EspressoFactory {
    static createCoffee() {
        return new Espresso()
    }
}
//Espresso를 만드는 구체적인 방법이 들어가있으며, Espresso를 리턴 

class CoffeeFactory {
    static createCoffee(type) {
        const factory = factoryList[type]
        return factory.createCoffee()
    }
}
/*createCoffee라는 뼈대를 만들어서 어떤 type(latte, espresso, americano)
중에 하나의 인자를 받아서 인자를 기반으로 선택을 한다.
latteFactory인지, EspressoFactory인지 하위 클래스를 결정한다.
그리고 그 하위 클래스로부터 하위 클래스의 createCoffee라는 메소드를 호출한다.
*/

/*핵심은 coffeeFactory라는 메소드가 정해져있고, 그 메소드를 호출하는게 아니라, 
Factory를 하나 정해서 그 메소드를 호출한다. 이게 팩토리 패턴이다.*/

const factoryList = { LatteFactory, EspressoFactory }

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

/*여기에선 LatteFactory의 구체적인 메소드를 호출한다. */ 
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
*/

요약 : 상위 클래스가 중요한 뼈대이고, 상위 클래스는 하위 클래스를 호출하는 것만. 객체 생성에 관한 구체적인 행동은 하위 클래스가 결정한다.

profile
주의사항 : 최대한 정확하게 작성하려고 하지만, 틀릴내용이 있을 수도 있으니 유의!
post-custom-banner

0개의 댓글