Design Patterns

Design Pattern, Factory Method

hyunki.Dev 2023. 3. 26. 20:49

๐Ÿ“Œ ๋“ค์–ด๊ฐ€๋ฉฐ

 ๋””์ž์ธ ๋ฉ”์„œ๋“œ ํŒจํ„ด์€ ์ด๋ฒˆ ์ด์ง์„ ์œ„ํ•ด ๊ฐœ๋ฐœํ–ˆ๋˜ ์‚ฌ์ „๊ณผ์ œ ์„œ๋น„์Šค์—์„œ๋„ ๊ทธ๋ ‡๊ณ  ์‹ค๋ฌด์—์„œ๋„ ์ •๋ง ๋งŽ์ด ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š” ํŒจํ„ด์ž…๋‹ˆ๋‹ค. ๊ทธ๋งŒํผ ํ™•์žฅ์„ฑ์ด ์ข‹๊ธฐ ๋•Œ๋ฌธ์— ๊ณ„์† ํ™œ์šฉํ•˜๊ฒŒ ๋˜๋Š” ๊ฒƒ ๊ฐ™์€๋ฐ ์ด๋ก ์ ์œผ๋กœ๋Š” ํ•œ๋ฒˆ๋„ ์ •๋ฆฌํ•ด๋ณธ ์ ์ด ์—†์–ด ์ด๋ฒˆ ํฌ์ŠคํŒ…์„  ํ†ตํ•ด ์ด๋ก ์ ์ธ ๋‚ด์šฉ์„ ์ •๋ฆฌํ•ด๋‘๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค. 

 

Factory Method Pattern(ํŒฉํ† ๋ฆฌ ๋ฉ”์„œ๋“œ ํŒจํ„ด)

ํŒฉํ† ๋ฆฌ ๋ฉ”์„œ๋“œ ํŒจํ„ด์€ ์ƒ์œ„ ํด๋ž˜์Šค์—์„œ ๊ฐ์ฒด์˜ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ •์˜ํ•˜๊ณ , ํ•˜์œ„ ํด๋ž˜์Šค๊ฐ€ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ• ์ง€๋ฅผ ๊ฒฐ์ •ํ•˜๋„๋ก ํ•˜๋Š” ํŒจํ„ด์ž…๋‹ˆ๋‹ค. ๊ฐ์ฒด๋ฅผ ํ•˜์œ„ ํด๋ž˜์Šค์—์„œ ์ƒ์„ฑ๋˜๋„๋ก ์‹œํ‚ค๋Š” ๊ฒƒ์ด์ฃ . ์ด๋Š” ๋‹ค์‹œ ๋งํ•ด ๋ถ€๋ชจ ํด๋ž˜์Šค์—์„œ ๊ฐ์ฒด๋“ค์„ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋Š” ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ œ๊ณตํ•˜์ง€๋งŒ, ์ž์‹ ํด๋ž˜์Šค๋“ค์ด ์ƒ์„ฑ๋  ๊ฐ์ฒด๋“ค์˜ ์œ ํ˜•์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ์ƒ์„ฑ ํŒจํ„ด์ž…๋‹ˆ๋‹ค.

 

 

์ด๋Ÿฌํ•œ Factory Method Pattern๋Š” Factory์™€ Template Method Pattern์ด ๊ฒฐํ•ฉ๋œ ํ˜•ํƒœ์ž…๋‹ˆ๋‹ค.

 

vs Simple Factory 

Factory Method Pattern์€ Simple Factory์— ์ถ”์ƒํ™”๊ฐ€ ๋”ํ•ด์ง„ ๊ฐœ๋…์ž…๋‹ˆ๋‹ค.

Simple Factory๋Š” ๋ถ„๋ฆฌ๋œ ํด๋ž˜์Šค์— ์ƒ์„ฑ ์ฝ”๋“œ๋ฅผ ์ง์ ‘ ๊ตฌํ˜„ํ–ˆ๋‹ค๋ฉด,

Factory Method๋Š” ์ถ”์ƒํ™”๋œ ์ƒ์œ„ ํด๋ž˜์Šค ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ•˜์œ„ ํด๋ž˜์Šค์—์„œ ์ง์ ‘ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

 

vs Template Method

Factory Method ํŒจํ„ด์€ Template Method ํŒจํ„ด๊ณผ ์œ ์‚ฌํ•œ ๋ชจ์Šต์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

Factory Method๋„ ์‹ค์ œ ์ƒ์„ฑ๋˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ํ•˜์œ„ ๋ฉ”์„œ๋“œ๋กœ ์œ„์ž„ํ•˜๋Š”๋ฐ, ์‹ค์ œ ๊ตฌํ˜„์„ ์œ„์ž„ํ•œ๋‹ค๋Š” ์ธก๋ฉด์—์„œ Template Method ํŒจํ„ด๊ณผ ์œ ์‚ฌํ•˜๋‹ค๊ณ  ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

Template Method ๊ณผ์˜ ๊ด€๊ณ„๋ฅผ ์ •๋ฆฌํ•˜์ž๋ฉด,

๊ณตํ†ต์  : ์ถ”์ƒํ™”๋ฅผ ์‚ฌ์šฉํ•ด ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋ฉฐ, ์ƒ์œ„ ํด๋ž˜์Šค์—์„œ ์ •์˜๋ฅผ ๊ฒฐ์ •ํ•˜๊ณ  ํ•˜์œ„ ํด๋ž˜์Šค์— ๊ตฌ์ฒด์ ์ธ ์ฒ˜๋ฆฌ๋ฅผ ์œ„์ž„ํ•ฉ๋‹ˆ๋‹ค.

์ฐจ์ด์  : ํ•ด๊ฒฐํ•˜๋ ค๋Š” ๋ชฉ์ ์— ๋”ฐ๋ผ ๋‘ ํŒจํ„ด์— ์ฐจ์ด๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

 

 

Parameterized

Parameterized Factory Method

 

๋งค๊ฐœ๋ณ€์ˆ˜ ํŒฉํ† ๋ฆฌ๋ž€ ์ž…๋ ฅ ๋งค๊ฐœ๋ณ€์ˆ˜์— ๋”ฐ๋ผ ๋‹ค๋ฅธ ํด๋ž˜์Šค์˜ ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ธฐ๋Šฅ์„ ๋งํ•ฉ๋‹ˆ๋‹ค.

๋Œ€ํ˜• ํ”„๋กœ๊ทธ๋žจ์„ ๊ฐœ๋ฐœํ•˜๋‹ค ๋ณด๋ฉด ์ƒ๊ฐ๋ณด๋‹ค ๋งŽ์€ ์ˆ˜์˜ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ด์•ผ ํ•˜๊ธฐ๋„ ํ•˜๊ณ ,

๊ฐ์ฒด ๊ด€๊ณ„ ์„ค์ •์ด ๋ณต์žกํ•ด์ง€๊ณ  ๊ฐ์ฒด ์ƒ์„ฑ์„ ์ฒ˜๋ฆฌํ•˜๋Š” ์ฝ”๋“œ ์œ„์น˜๋„ ๋ถ„์‚ฐ๋ฉ๋‹ˆ๋‹ค.

 

ํŒฉํ† ๋ฆฌ ๋ฉ”์„œ๋“œ์—์„œ ์ž…๋ ฅ๋ฐ›์€ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ฒ˜๋ฆฌํ•  ๋•Œ ๋งค๊ฐœ๋ณ€์ˆ˜์— ๋งž๋Š” ํด๋ž˜์Šค๋ฅผ ์„ ํƒํ•˜์—ฌ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. 

 

public abstract class Pizza {
    public abstract decimal GetPrice();

    public enum PizzaType {
        HamMushroom, Deluxe, Seafood
    }

    public static Pizza PizzaFactory(PizzaType pizzaType) {
        switch (pizzaType) {
            case PizzaType.HamMushroom:
                return new HamAndMushroomPizza();

            case PizzaType.Deluxe:
                return new DeluxePizza();

            case PizzaType.Seafood:
                return new SeafoodPizza();
        }

        throw new System.NotSupportedException("The pizza type " + pizzaType.ToString() + " is not recognized.");
    }
}

 

Factory Method  ํŠน์ง•

 

โœ”๏ธ DIP, Dependency Inversion Principle.(์˜์กด ๊ด€๊ณ„ ์—ญ์ „์˜ ์›์น™)

 

DIP๋Š” ๊ตฌ์ฒดํ™”์— ์˜์กดํ•˜์ง€ ๋ง๊ณ  ์ถ”์ƒํ™”์— ์˜์กดํ•˜๋ผ๋Š” ์›์น™์ž…๋‹ˆ๋‹ค.

Factory Method๋Š” ์ถ”์ƒํ™”๋œ ๊ฐ์ฒด๋ฅผ ์ •์˜ํ•ด์„œ ํ•˜์œ„ ํด๋ž˜์Šค์—์„œ ๊ตฌํ˜„ํ•˜๋Š” ํŒจํ„ด์ž…๋‹ˆ๋‹ค.

Factory Method๋Š” DIP ์›์น™์„ ์ž˜ ๊ตฌํ˜„ํ•œ ์‚ฌ๋ก€์ž…๋‹ˆ๋‹ค.

 

 

โœ”๏ธ ์˜์กด์„ฑ

์ƒ์„ฑ ํŒจํ„ด์€ ๊ฐ์ฒด์˜ ์ƒ์„ฑ ๊ณผ์ •์„ ์™ธ๋ถ€์— ๊ณต๊ฐœํ•˜์ง€ ์•Š๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

์ง์ ‘์ ์œผ๋กœ new ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋นˆ๋„๊ฐ€ ์ค„์–ด๋“ค๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

๋Š์Šจํ•œ ๊ฒฐํ•ฉ์œผ๋กœ ์˜์กด์„ฑ์„ ์ค„์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

 

โœ”๏ธ ์บก์Šํ™”์™€ ๊ด€๋ฆฌ

ํŒฉํ† ๋ฆฌ ๋ฉ”์„œ๋“œ ํŒจํ„ด์€ ํด๋ž˜์Šค ๊ฒฐํ•ฉ๋„๊ฐ€ ๋‚ฎ๊ณ  ์œ ์—ฐ์„ฑ์ด ์ข‹์Šต๋‹ˆ๋‹ค. 

 

Factory Method์˜  ์žฅ๋‹จ์ 

์žฅ์ 

 

  •  ํฌ๋ฆฌ์—์ดํ„ฐ์™€ ๊ตฌ์ƒ ์ œํ’ˆ๋“ค์ด ๋‹จ๋‹จํ•˜๊ฒŒ ๊ฒฐํ•ฉ๋˜์ง€ ์•Š๋„๋ก ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋กœ ์ธํ•ด ๊ธฐ๋Šฅ ๊ฐœ์„  ์‹œ ๊ธฐ๋Šฅ์„ ๋ณด์™„ํ•˜๊ธฐ ์œ„ํ•œ ๋ฆฌํŒฉํ† ๋ง ์ž‘์—…์ด ํŽธ๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
  •  ๋‹จ์ผ ์ฑ…์ž„ ์›์น™. ์ œํ’ˆ ์ƒ์„ฑ ์ฝ”๋“œ๋ฅผ ํ”„๋กœ๊ทธ๋žจ์˜ ํ•œ ์œ„์น˜๋กœ ์ด๋™ํ•˜์—ฌ ์ฝ”๋“œ๋ฅผ ๋” ์‰ฝ๊ฒŒ ์œ ์ง€๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  •  ๊ฐœ๋ฐฉ/ํ์‡„ ์›์น™. ๋‹น์‹ ์€ ๊ธฐ์กด ํด๋ผ์ด์–ธํŠธ ์ฝ”๋“œ๋ฅผ ํ›ผ์†ํ•˜์ง€ ์•Š๊ณ  ์ƒˆ๋กœ์šด ์œ ํ˜•์˜ ์ œํ’ˆ๋“ค์„ ํ”„๋กœ๊ทธ๋žจ์— ๋„์ž…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‹จ์ 

  •  ํŒจํ„ด์„ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด ๋งŽ์€ ์ƒˆ๋กœ์šด ์ž์‹ ํด๋ž˜์Šค๋“ค์„ ๋„์ž…ํ•ด์•ผ ํ•˜๋ฏ€๋กœ ์ฝ”๋“œ๊ฐ€ ๋” ๋ณต์žกํ•ด์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 

 

Factory Method๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ด์œ 

ํŒฉํ† ๋ฆฌ ๋ฉ”์†Œ๋“œ ํŒจํ„ด์„ ์‚ฌ์šฉํ•˜๋Š” ์ด์œ ๋Š” ํด๋ž˜์Šค์˜ ์ƒ์„ฑ๊ณผ ์‚ฌ์šฉ์˜ ์ฒ˜๋ฆฌ๋กœ์ง์„ ๋ถ„๋ฆฌํ•˜์—ฌ ์ฝ”๋“œ์˜ ๊ฒฐํ•ฉ๋„๋ฅผ ๋‚ฎ์ถ”๊ธฐ ์œ„ํ•จ์ž…๋‹ˆ๋‹ค.
๊ฒฐํ•ฉ๋„๋Š” ๊ฐ„๋‹จํžˆ ๋งํ•ด์„œ ํด๋ž˜์Šค์˜ ์ฒ˜๋ฆฌ ๋กœ์ง์— ๋Œ€ํ•œ ๋ณ€๊ฒฝ์ ์ด ์ƒ๊ฒผ์„ ๋•Œ ์–ผ๋งˆ๋‚˜ ์‚ฌ์ด๋“œ ์ดํŽ™ํŠธ๋ฅผ ์ฃผ๋Š”๊ฐ€ ์ธ๋ฐ,

 

ํŒฉํ† ๋ฆฌ ๋ฉ”์†Œ๋“œ ํŒจํ„ด์„ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ ์ง์ ‘ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ด ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•˜๊ณ  ์„œ๋ธŒ ํด๋ž˜์Šค์— ์ƒ์„ฑ ๋กœ์ง์„ ์œ„์ž„ํ•จ์œผ๋กœ์จ ๋ณด๋‹ค ํšจ์œจ์ ์ธ ์ฝ”๋“œ ์ œ์–ด๋ฅผ ํ•  ์ˆ˜ ์žˆ๊ณ  ์˜์กด์„ฑ์„ ์ œ๊ฑฐ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋กœ ์ธํ•ด ์ฝ”๋“œ๋ฅผ ๋”์šฑ ์‰ฝ๊ฒŒ ์œ ์ง€๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

Factory Method ๊ตฌ์กฐ

 

Product

Factory method๊ฐ€ ์ƒ์„ฑํ•  ๊ฐ์ฒด์˜ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.

 

ConcreteProduct 

Factory method๊ฐ€ ์ƒ์„ฑํ•  ๊ฐ์ฒด๋กœ, Product๋ฅผ implementsํ•ฉ๋‹ˆ๋‹ค.

 

Creator 
Product(ํ˜น์€ ConcreteProduct) ํƒ€์ž…์„ ๋ฐ˜ํ™˜ํ•˜๋Š” Factory method๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. 

Product ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด factory method๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

ConcreteCreator 

ConcreteProduct์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” factory method๋ฅผ ์˜ค๋ฒ„๋ผ์ด๋”ฉํ•˜์—ฌ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค.

 

 

Sample Code: Java

๋‹ค์Œ์€ ๋‘๊ฐ€์ง€์˜ ์ฟ ํฐ(RewardCoupon, ReceiptCoupon)์„ ๋งŒ๋“œ๋Š” ํŒฉํ† ๋ฆฌ๋ฉ”์„œ๋“œ์ฟ ํฐ ์˜ˆ์ œ์ž…๋‹ˆ๋‹ค.

Product

public interface Coupon {
    void name();
}

 

 

ConcreateProduct

class RewardCoupon implements Coupon {
    public void name() {
        System.out.println("Reward Coupon");
    }
}
class ReceiptCoupon implements Coupon {
    public void name() {
        System.out.println("Receipt Coupon");
    }
}

 

Creator

abstract class Factory {
    public Coupon create(String couponCode) {
        return this.createCoupon(couponCode);
    }

    abstract public Coupon createCoupon(String couponCode);
}

 

ConcreteCreator

class CouponFactory extends Factory {
    public CouponFactory() {
        System.out.println("CouponFactory ์ƒ์„ฑ");
    }

    public Coupon createCoupon(String couponCode) {
        if (model == "RewardCoupon") {
            return new RewardCoupon();
        } else {
            return new ReceiptCoupon();
        }
    }
}

 

Main

public class Main {
    public static void main(String[] args) {
        Factory fac = new CouponFactory();
        Coupon coupon = fac.create("RewardCoupon");
        coupon.name();

        coupon = fac.create("ReceiptCoupon");
        coupon.name();
    }
}

 

 

์ฐธ๊ณ  :
https://refactoring.guru/ko/design-patterns/factory-method

https://gngsn.tistory.com/121

 

Design Pattern, Strategy

Behavioral Object Pattern Strategy Pattern Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from clients that use it. - GoF Design Patterns ์ „๋žต ํŒจํ„ด์€ ๋™์ผ ๊ณ„์—ด์˜

gngsn.tistory.com

https://bamdule.tistory.com/157