Skip to content

Latest commit

ย 

History

History
474 lines (351 loc) ยท 16.4 KB

2_Factory Method_Java.md

File metadata and controls

474 lines (351 loc) ยท 16.4 KB

ํŒฉํ† ๋ฆฌ ๋ฉ”์„œ๋“œ ํŒจํ„ด

https://cyclic-basket-9b5.notion.site/1c1eeedb4edc4f388897822b04237ee9?pvs=4

Factory Method - ์‹œ์ž‘

๊ฐ์ฒด ์ƒ์„ฑ์„ ๊ณต์žฅ(Factory) ํด๋ž˜์Šค๋กœ ์บก์Šํ™” ์ฒ˜๋ฆฌํ•ด์„œ ๋Œ€์‹  ์ƒ์„ฑํ•˜๊ฒŒ ํ•˜๋Š” ์ƒ์„ฑ ๋””์ž์ธ ํŒจํ„ด์ด๋‹ค.

์ข€ ๋” ์ž์„ธํ•˜๊ฒŒ ์„ค๋ช…ํ•˜์ž๋ฉด, ํด๋ผ์ด์–ธํŠธ์—์„œ ์ง์ ‘ new ์—ฐ์‚ฐ์ž๋ฅผ ํ†ตํ•ด ์ œํ’ˆ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ๋Œ€์‹  ์ œํ’ˆ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•  ๊ณต์žฅ ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค๊ณ , ์ด๋ฅผ ์ƒ์†ํ•˜๋Š” ์„œ๋ธŒ ๊ณต์žฅ ํด๋ž˜์Šค์˜ ๋ฉ”์„œ๋“œ์—์„œ ์—ฌ๋Ÿฌ๊ฐ€์ง€ ์ œํ’ˆ ๊ฐ์ฒด ์ƒ์„ฑ์„ ๊ฐ๊ฐ ์ฑ…์ž„์ง€๋Š” ๊ฒƒ์„ ๋งํ•œ๋‹ค.

์ด ํŒจํ„ด์„ ์ด์šฉํ•˜๋Š” ์ด์œ ๋Š” ๊ฐ์ฒด๊ฐ„์˜ ๊ฒฐํ•ฉ๋„๋ฅผ ๋‚ฎ์ถœ ์ˆ˜ ์žˆ๊ณ , ์œ ์ง€๋ณด์ˆ˜์— ์šฉ์ดํ•ด์ง€๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

๐Ÿ’ก ๊ทธ๋ž˜ ๊ณต์žฅํ•œํ…Œ ์š”์ฒญํ•˜๋ฉด ์„œ๋ธŒ ๊ณต์žฅ ํด๋ž˜์Šค์˜ ๋ฉ”์„œ๋“œ์—์„œ ์ œํ’ˆ์„ ์ƒ์„ฑํ•œ๋‹ค๋Š” ๋ง์„ ํ‘œํ˜„ํ•œ๊ฑด ์•Œ๊ฒ ๋Š”๋ฐ, **๊ทธ๋ƒฅ ํ•œ ๊ณต์žฅ์—์„œ ๋‹ค ๋งŒ๋“ค๋ฉด ์•ˆ๋ผ? ์™œ ์„œ๋ธŒ ๊ณต์žฅ์ด ํ•„์š”ํ•œ๋ฐ?**๋ผ๋Š” ๋ฌผ์Œ์ด ์ƒ๊ธธ ์ˆ˜ ์žˆ๋‹ค.

์ด๋ฅผ ์ดํ•ดํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋จผ์ € Factory Method ํŒจํ„ด๊ณผ Abstract Factory ํŒจํ„ด์˜ ๋ฒ ์ด์Šค์ธ Simple Factory๋ฅผ ์•Œ์•„์•ผํ•œ๋‹ค.

์ฐธ๊ณ ๋กœ Simple Factory๋Š” ๋””์ž์ธ โ€˜ํŒจํ„ดโ€™์ด๋ผ๊ณ ๋Š” ํ•  ์ˆ˜ ์—†๊ณ , OOP์—์„œ ์ž์ฃผ ์“ฐ์ด๋Š” ๊ด€์šฉ๊ตฌ๋ผ๊ณ  ๋ณด๋ฉด ๋œ๋‹ค.

Simple Factory?

Simple Factory๋Š” ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ด๋‚ด๋Š” ๊ณต์žฅ์„ ๋”ฐ๋กœ ๋‘๋Š” ๊ฒƒ์ด๋‹ค.

์ฆ‰, ๊ฐ์ฒด ์ƒ์„ฑ ๋ถ€๋ถ„์„ ์ „๋‹ดํ•˜๋Š” ๊ณต์žฅ ํด๋ž˜์Šค๊ฐ€ ๋”ฐ๋กœ ์žˆ๋Š” ๊ฒƒ์ด๋‹ค.

๊ฐ์ฒด๋Š” ์—ฌ๋Ÿฌ ๊ณณ์—์„œ ์ƒ์„ฑ๋  ์ˆ˜ ์žˆ๋‹ค. ํ•˜์ง€๋งŒ ํ˜ธ์ถœํ•˜๋Š” ์ชฝ์ด ๊ฐ์ฒด์˜ ์ƒ์„ฑ์ž์— ์ง์ ‘ ์˜์กดํ•˜๊ณ  ์žˆ๋‹ค๋ฉด, ๋‚˜์ค‘์— ์ˆ˜์ •๋˜์–ด์•ผ ํ•˜๋Š” ์ฝ”๋“œ๊ฐ€ ๋งŽ์ด ๋ฐœ์ƒํ•œ๋‹ค. (๋ฐ‘์—์„œ ์˜ˆ์‹œ๋ฅผ ํ†ตํ•ด ํ™•์ธํ•ด๋ณด์ž!)

๋”ฐ๋ผ์„œ ์ƒ์„ฑ์ž ํ˜ธ์ถœ(new)์„ ๋ณ„๋„์˜ ํด๋ž˜์Šค(Factory)์—์„œ ๋‹ด๋‹นํ•˜๊ณ  ํด๋ผ์ด์–ธํŠธ ์ฝ”๋“œ์—์„œ๋Š” ์ด Factory๋ฅผ ํ†ตํ•ด ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ด์•ผ ํ•œ๋‹ค.

Example - ๊ตฌํ˜„ ํด๋ž˜์Šค ์˜์กด O

public interface Sopt {
    void printLanguage();
}

public class Server implements Sopt {
	  @Override
    public void printLanguage() {
        System.out.println("Java");
    }
}

public class Ios implements Sopt {
	  @Override
    public void printLanguage() {
        System.out.println("Swift");
    }
}

Sopt๋ฅผ ํ•œ๋ฒˆ ์˜ˆ์‹œ๋กœ ๋“ค์–ด๋ณด์ž.

๊ณตํ†ต ์ธํ„ฐํŽ˜์ด์Šค์ธย Soptย ์„ ์ •์˜ํ•˜๊ณ  ์ด๋ฅผ ๊ตฌํ˜„ํ•˜๋Š”ย Server,ย Iosย ํด๋ž˜์Šค์ด๋‹ค.

์ด์ œ ํด๋ผ์ด์–ธํŠธ ์ฝ”๋“œ์—์„œย Server,ย Iosย ์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.

public class Client {
    public static void main(String[] args) {
	    Sopt server = new Server();
	    Sopt ios = new Ios();
	    
	    server.printlanguage();
	    ios.printlanguage();
    }
}

์ผ๋ฐ˜์ ์ธ ์‚ฌ์šฉ๋ฒ•์€ new๋ฅผ ์‚ฌ์šฉํ•ด ๊ตฌํ˜„ ํด๋ž˜์Šค๋ฅผ ์ƒ์„ฑํ•œ ํ›„ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ํ•˜์ง€๋งŒ ์ด๋ ‡๊ฒŒ ๋˜๋ฉด ํด๋ผ์ด์–ธํŠธ์™€ ํด๋ž˜์Šค๋“ค ์‚ฌ์ด์— ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์˜์กด๊ด€๊ณ„๊ฐ€ ์ƒ๊ธด๋‹ค.

simple_factory

์ด๋ ‡๊ฒŒ ๊ตฌํ˜„ ํด๋ž˜์Šค(Server, Ios)๋ฅผ ์˜์กดํ•˜๊ณ  ์žˆ์œผ๋ฉด, ํ•ด๋‹น ํด๋ž˜์Šค์˜ ์ƒ์„ฑ์ž or ์ „์ฒ˜๋ฆฌ ์ฝ”๋“œ๊ฐ€ ๋ณ€๊ฒฝ๋˜์—ˆ์„ ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ๋ชจ๋“  ํด๋ผ์ด์–ธํŠธ ์ฝ”๋“œ๋ฅผ ๋ณ€๊ฒฝํ•ด์•ผ ํ•œ๋‹ค.

๊ทธ๋Ÿฌ๋ฉด ์ด์ œ ๊ฐ์ฒด์˜ ์ƒ์„ฑ๋งŒ์„ ๋‹ด๋‹นํ•˜๋Š” ๋ณ„๋„์˜ Factory ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค์–ด๋ณด์ž!


Example - ๊ตฌํ˜„ ํด๋ž˜์Šค ์˜์กด X

public interface Sopt {
    enum Part { // ์ถ”๊ฐ€
        SERVER, IOS    
    }
    
    void printLanguage();
}

public class Server implements Sopt {
	  @Override
    public void printLanguage() {
        System.out.println("Java");
    }
}

public class Ios implements Sopt {
	  @Override
    public void printLanguage() {
        System.out.println("Swift");
    }
}

์šฐ์„  Sopt ์ธํ„ฐํŽ˜์ด์Šค์— enum ํƒ€์ž…์œผ๋กœ ์„ ์–ธ์„ ํ•ด์ค€๋‹ค.

public class SoptFactory {

    public Sopt createSopt(Sopt.Part soptPart) {
        switch (soptPart) {
            case SERVER:
                return new Server();
            case IOS:
                return new Ios();
            default:
                throw new IllegalArgumentException("Sopt์— ์—†๋Š” ํŒŒํŠธ์ž…๋‹ˆ๋‹ค");
        }
    }
}

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

public class Client {
    public static void main(String[] args) {
        SoptFactory soptFactory = new SoptFactory();
        Sopt server = soptFactory.createSopt(Sopt.Part.SERVER);
        Sopt ios = soptFactory.createSopt(Sopt.Part.IOS);

        server.printLanguage();
        ios.printLanguage();
    }
}

soptFactory๋ฅผ ์„ ์–ธํ•˜๊ณ  ์ƒ์„ฑ ๋ฉ”์„œ๋“œ์ธ create๋งŒ ํ˜ธ์ถœํ•˜๋ฉด ์‹ค์ œ ๊ตฌํ˜„ ํด๋ž˜์Šค์ธ Server, Ios์— ์˜์กดํ•˜์ง€ ์•Š์€ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.

factory_2

์ด์ œ ์˜์กด๊ด€๊ณ„๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ฐ”๋€Œ๊ฒŒ ๋œ๋‹ค.

ํด๋ผ์ด์–ธํŠธ์—์„œ ๊ตฌํ˜„ํด๋ž˜์Šค(Server, Ios)์— ์ง์ ‘ ์˜์กดํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์—, ํด๋ž˜์Šค ์ด๋ฆ„์ด ๋ณ€๊ฒฝ๋˜๊ฑฐ๋‚˜, ์ƒ์„ฑ์ž๊ฐ€ ๋ณ€๊ฒฝ๋˜์–ด๋„ SoptFactory ๋‚ด๋ถ€๋งŒ ์ˆ˜์ •ํ•˜๋ฉด ๋œ๋‹ค!!

Simple Factory์˜ ํ•œ๊ณ„

์šฐ์™€ ์™„๋ฒฝํ•œ๋ฐ ์•ž์œผ๋กœ Simple Factory๋กœ ๊ตฌํ˜„ํ•ด์•ผ์ง•~

๋†‰! ๐Ÿ™…โ€โ™‚๏ธ

์•„์‰ฝ์ง€๋งŒ, Simple Factory๋Š” ๊ฐ์ฒด ์ƒ์„ฑ์˜ ์—ญํ• ์„ ํŒฉํ† ๋ฆฌ์— ๋‹ด๋‹น์‹œ์ผœ ํ™•์žฅ์ด ์šฉ์ดํ•˜๋‹ค๋Š” ์žฅ์ ์ด ์žˆ์ง€๋งŒ, ๋ณ€๊ฒฝ์— ๋‹ซํ˜€ ์žˆ์–ด์•ผ ํ•œ๋‹ค๋Š” OCP ์›์น™์— ์œ„๋ฐฐ๋œ๋‹ค.

๋งŒ์•ฝ ์ƒˆ๋กœ์šด Sopt ์ธํ„ฐํŽ˜์ด์Šค์˜ ๊ตฌํ˜„ ํด๋ž˜์Šค๋กœ Android๊ฐ€ ์ถ”๊ฐ€๋˜์—ˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ณด์ž.

public class Client {
    public static void main(String[] args) {
        SoptFactory soptFactory = new SoptFactory();
        Sopt server = soptFactory.createSopt(Sopt.Part.SERVER);
        Sopt ios = soptFactory.createSopt(Sopt.Part.IOS);
        Sopt android = soptFactory.createSopt(Sopt.Part.ANDROID); // ์ถ”๊ฐ€

        server.printLanguage();
        ios.printLanguage();         
        android.printLanguage(); // ์ถ”๊ฐ€
    }
}

๋ฌธ์ œ ์—†์–ด๋ณด์ด๋Š”๋ฐ ์–ด๋””์„œ OCP๋ฅผ ์œ„๋ฐ˜ํ•œ๋‹ค๋Š”๊ฑฐ์ง€?

public interface Sopt {
    enum Part {
        SERVER, IOS, ANDROID   // ์ถ”๊ธฐ
    }
    
    void printLanguage();
}

public class Server implements Sopt {
	  @Override
    public void printLanguage() {
        System.out.println("Java");
    }
}

public class Ios implements Sopt {
	  @Override
    public void printLanguage() {
        System.out.println("Swift");
    }
}

public class Android implements Sopt { // ์ถ”๊ฐ€
    @Override
    public void printLanguage() {
        System.out.println("Kotlin");
    }
}

Android ํด๋ž˜์Šค๋ฅผ ์ƒˆ๋กญ๊ฒŒ ์ถ”๊ฐ€ํ–ˆ์ง€๋งŒ,

๊ธฐ์กด Sopt.Part ์—ด๊ฑฐํ˜•์— ์ƒˆ๋กœ์šด ํƒ€์ž…์„ ์ถ”๊ฐ€ํ•ด์•ผ ํ•˜๋„ค ๐Ÿ˜ญ

public class SoptFactory {
    public Sopt createSopt(Sopt.Part soptPart) {
        switch (soptPart) {
            case SERVER:
                return new Server();
            case IOS:
                return new Ios();
            case ANDROID:
                return new Android(); 
            default:
                throw new IllegalArgumentException("Sopt์— ์—†๋Š” ํŒŒํŠธ์ž…๋‹ˆ๋‹ค");
        }
    }
} 

**SoptFactory**์˜ create ๋ฉ”์„œ๋“œ์— ์ƒˆ๋กœ์šด **case**๋ฅผ ์ถ”๊ฐ€ํ•ด์•ผ ํ•˜๋„ค ๐Ÿ˜ญ

์ด๋ ‡๋“ฏ OCP๋ฅผ ์œ„๋ฐ˜ํ•˜๊ฒŒ ๋œ๋‹ค.

๊ทธ๋Ÿฌ๋ฉด OCP๋ฅผ ์œ„๋ฐ˜ํ•˜์ง€ ์•Š๊ณ  ํŒฉํ† ๋ฆฌ ํŒจํ„ด์„ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์—†์„๊นŒ?

ํŒฉํ† ๋ฆฌ ๋ฉ”์„œ๋“œ ํŒจํ„ด์ด๋‚˜ ์ถ”์ƒ ํŒฉํ† ๋ฆฌ ํŒจํ„ด์„ ํ™œ์šฉํ•œ๋‹ค๋ฉด ๊ธฐ์กด ํด๋ž˜์Šค์— ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š๊ณ  ํ™•์žฅ์ด ๊ฐ€๋Šฅํ•˜๋‹ค ๐Ÿ‘ ๋ณธ๋ก ์œผ๋กœ ๋“ค์–ด๊ฐ€๋ณด์ž ๐Ÿ‘จ๐Ÿปโ€๐Ÿ’ป

Factory Method - ๋ณธ๋ก 

๋‹ค์‹œ ํ•œ ๋ฒˆ ๋ฆฌ๋งˆ์ธ๋“œ ํ•˜์ž๋ฉด, Factory Method ํŒจํ„ด์ด๋ž€ ํด๋ผ์ด์–ธํŠธ์—์„œ ์ง์ ‘ new ์—ฐ์‚ฐ์ž๋ฅผ ํ†ตํ•ด ์ œํ’ˆ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ๋Œ€์‹  ์ œํ’ˆ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•  ๊ณต์žฅ ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค๊ณ (์—ฌ๊ธฐ๊นŒ์ง„ Simple Factory ์™€ ๋™์ผ), ์ด๋ฅผ ์ƒ์†ํ•˜๋Š” ์„œ๋ธŒ ๊ณต์žฅ ํด๋ž˜์Šค์˜ ๋ฉ”์„œ๋“œ์—์„œ ์—ฌ๋Ÿฌ๊ฐ€์ง€ ์ œํ’ˆ ๊ฐ์ฒด ์ƒ์„ฑ์„ ๊ฐ๊ฐ ์ฑ…์ž„์ง€๋Š” ๊ฒƒ์„ ๋งํ•œ๋‹ค.(์ด ๋ถ€๋ถ„์ด ์ฐจ์ด์ !)

Factory Method ๊ตฌ์กฐ

123
  • Creator : ์ตœ์ƒ์œ„ ๊ณต์žฅ ํด๋ž˜์Šค๋กœ์„œ, ํŒฉํ† ๋ฆฌ ๋ฉ”์„œ๋“œ๋ฅผ ์ถ”์ƒํ™”ํ•˜์—ฌ ์„œ๋ธŒ ํด๋ž˜์Šค๋กœ ํ•˜์—ฌ๊ธˆ ๊ตฌํ˜„ํ•˜๋„๋ก ํ•จ.
    • ๊ฐ์ฒด ์ƒ์„ฑ ์ฒ˜๋ฆฌ ๋ฉ”์„œ๋“œ(someOperation) : ๊ฐ์ฒด ์ƒ์„ฑ์— ๊ด€ํ•œ ์ „์ฒ˜๋ฆฌ, ํ›„ ์ฒ˜๋ฆฌ๋ฅผ ํ…œํ”Œ๋ฆฟํ™”ํ•œ ๋ฉ”์„œ๋“œ
    • ํŒฉํ† ๋ฆฌ ๋ฉ”์„œ๋“œ(createProduct) : ์„œ๋ธŒ ๊ณต์žฅ ํด๋ž˜์Šค์—์„œ ์žฌ์ •์˜ํ•  ๊ฐ์ฒด ์ƒ์„ฑ ์ถ”์ƒ ๋ฉ”์„œ๋“œ
  • ConcreteCreator : ๊ฐ ์„œ๋ธŒ ๊ณต์žฅ ํด๋ž˜์Šค๋“ค์€ ์ด์— ๋งž๋Š” ์ œํ’ˆ ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋„๋ก ์ƒ์„ฑ ์ถ”์ƒ ๋ฉ”์„œ๋“œ๋ฅผ ์žฌ์ •์˜ํ•œ๋‹ค. ์ฆ‰, ์ œํ’ˆ ๊ฐ์ฒด ํ•˜๋‚˜๋‹น ๊ทธ์— ๊ฑธ๋งž๋Š” ์ƒ์‚ฐ ๊ณต์žฅ ๊ฐ์ฒด๊ฐ€ ์œ„์น˜๋œ๋‹ค.
  • Product : ์ œํ’ˆ ๊ตฌํ˜„์ฒด๋ฅผ ์ถ”์ƒํ™”ํ•œ ๊ฒƒ
  • ConcreateProduct : ์ œํ’ˆ ๊ตฌํ˜„์ฒด

์•„๊นŒ ๋ณด์•˜๋˜ Simple Factory์˜ ์˜ˆ์‹œ์— ๋Œ€์ž…ํ•ด ๋ณด์ž๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

  • Product๋Š” Sopt
  • ConcreateProduct๋Š” Server, Ios
  • Creator๋Š” SoptFactory(์„œ๋ธŒ ํด๋ž˜์Šค๋กœ ํ•˜์—ฌ๊ธˆ ๊ตฌํ˜„ํ•˜๋„๋ก ํ•˜์ง€ ์•Š์•˜์„ ๋•Œ)

์ด์ œ ํ•  ์ผ์€ ํŒฉํ† ๋ฆฌ ๋ฉ”์„œ๋“œ๋ฅผ ์ถ”์ƒํ™”ํ•˜์—ฌ ์„œ๋ธŒ ํด๋ž˜์Šค๋กœ ํ•˜์—ฌ๊ธˆ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

Example - ํŒฉํ† ๋ฆฌ ํŒจํ„ด

public interface Sopt {
    void printLanguage();
}

public class Server implements Sopt {
    @Override
    public void printLanguage() {
        System.out.println("Java");
    }
}

public class Ios implements Sopt {
    @Override
    public void printLanguage() {
        System.out.println("Swift");
    }
}

์ธํ„ฐํŽ˜์ด์Šค Product(Sopt)์™€ ๊ตฌํ˜„ ํด๋ž˜์Šค ConcreateProduct(Server, Ios)์ด๋‹ค. Simple Factory์™€ ๋™์ผํ•˜๋‹ค.

// ๊ณต์žฅ ๊ฐ์ฒด ์ถ”์ƒํ™” (์ถ”์ƒ ํด๋ž˜์Šค)
public abstract class SoptFactory {

    // ๊ฐ์ฒด ์ƒ์„ฑ ์ฒ˜๋ฆฌ ๋ฉ”์„œ๋“œ(final๋กœ ์˜ค๋ฒ„๋ผ์ด๋”ฉ ๋ฐฉ์ง€)
    public final Sopt createOperation() {
        Sopt sopt = createSopt(); // ์„œ๋ธŒ ํด๋ž˜์Šค์—์„œ ๊ตฌ์ฒดํ™”ํ•œ ํŒฉํ† ๋ฆฌ ๋ฉ”์„œ๋“œ ์‹คํ–‰
        sopt.setup();  // .. ์ด๋ฐ–์˜ ๊ฐ์ฒด ์ƒ์„ฑ์— ๊ฐ€๋ฏธํ•  ๋กœ์ง ์‹คํ–‰
        return sopt;  // ์™„์„ฑ๋œ ๊ฐ์ฒด ๋ฐ˜ํ™˜
    }

    // ํŒฉํ† ๋ฆฌ ๋ฉ”์†Œ๋“œ : ๊ตฌ์ฒด์ ์ธ ๊ฐ์ฒด ์ƒ์„ฑ ์ข…๋ฅ˜๋Š” ๊ฐ ์„œ๋ธŒ ํด๋ž˜์Šค์— ์œ„์ž„
    // protected ์ด๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ™์€ ํŒจํ‚ค์ง€ ๋‚ด์˜ ํด๋ž˜์Šค๊ฑฐ๋‚˜, ํ•ด๋‹น ํด๋ž˜์Šค๋ฅผ ์ƒ์†๋ฐ›์€ ์ž์‹ํด๋ž˜์Šค์—์„œ๋งŒ ์ ‘๊ทผ ๊ฐ€๋Šฅ
    protected abstract Sopt createSopt();
}

// ์„œ๋ฒ„๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ตฌ์ฒด ํŒฉํ† ๋ฆฌ
public class ServerFactory extends SoptFactory {
    @Override
    public Sopt createSopt() {
        return new Server();
    }
}

// iOS๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ตฌ์ฒด ํŒฉํ† ๋ฆฌ
public class IosFactory extends SoptFactory {
    @Override
    public Sopt createSopt() {
        return new Ios();
    }
}

์šฐ์™€ ๋„ˆ๋ฌด ์–ด๋ ค์šด๊ฑธโ€ฆ?

์ฐจ๊ทผ์ฐจ๊ทผ ์–ด๋–ค ์ ์ด ๋ณ€ํ–ˆ๋Š”์ง€ ์‚ดํŽด๋ณด์ž!

  1. SoptFactory๊ฐ€ ์ถ”์ƒ ํด๋ž˜์Šค๋กœ ๋ณ€ํ™˜๋˜์—ˆ๋‹ค.
  2. ๊ฐ์ฒด ์ƒ์„ฑ ์ฒ˜๋ฆฌ ๋ฉ”์„œ๋“œ(createOperation**)**๊ฐ€ ์ƒ๊ฒผ๋‹ค.
  3. ํŒฉํ† ๋ฆฌ ๋ฉ”์„œ๋“œ์ธ createSopt๊ฐ€ ์ถ”์ƒ ๋ฉ”์„œ๋“œ๋กœ ๊ทธ๋ฆฌ๊ณ  protected๋กœ ์ ‘๊ทผ์ œ์–ด์ž๊ฐ€ ๋ฐ”๋€Œ์—ˆ๋‹ค.

์ฒซ๋ฒˆ์งธ, SoptFactory๊ฐ€ ์ถ”์ƒ ํด๋ž˜์Šค๋กœ ๋ณ€ํ™˜๋œ ์ด์œ ๋Š”

๊ตฌ์ฒด์ ์ธ ๊ฐ์ฒด ์ƒ์„ฑ ๋กœ์ง์„ ์ฑ…์ž„์„ ์„œ๋ธŒ ํด๋ž˜์Šค๋กœ ๋„˜๊ธฐ๊ธฐ ์œ„ํ•ด์„œ ์ž…๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์ ‘๊ทผ ๋ฐฉ์‹์€ ๊ฐ์ฒด ์ƒ์„ฑ์˜ ๊ตฌ์ฒด์ ์ธ ์„ธ๋ถ€์‚ฌํ•ญ์„ ์ˆจ๊ธฐ๋ฉด์„œ๋„ ํ•„์š”์— ๋”ฐ๋ผ ํ™•์žฅํ•  ์ˆ˜ ์žˆ๋Š” ์œ ์—ฐ์„ฑ์„ ์ œ๊ณตํ•œ๋‹ค.

๋‘๋ฒˆ์งธ, ๊ฐ์ฒด ์ƒ์„ฑ ์ฒ˜๋ฆฌ ๋ฉ”์„œ๋“œ(createOperation)๊ฐ€ ์ƒ๊ธด ์ด์œ ๋Š”

๊ฐ์ฒด ์ƒ์„ฑ ๊ณผ์ •์—์„œ ๊ณตํ†ต๋œ ์‚ฌํ•ญ(ex. ๊ฐ์ฒด ์ƒ์„ฑ ํ›„ ์„ค์ •, ์œ„์˜ sopt.setup())์„ ์ฒ˜๋ฆฌํ•˜๊ณ , ์‹ค์ œ ๊ฐ์ฒด ์ƒ์„ฑ์€ createSopt ์ถ”์ƒ ๋ฉ”์„œ๋“œ(ํŒฉํ† ๋ฆฌ ๋ฉ”์„œ๋“œ)์— ์œ„์ž„ํ•˜๊ธฐ ์œ„ํ•ด์„œ์ด๋‹ค.

์„ธ๋ฒˆ์งธ, ํŒฉํ† ๋ฆฌ ๋ฉ”์„œ๋“œ์ธ createSopt๊ฐ€ ์ถ”์ƒ ๋ฉ”์„œ๋“œ์ด์ž protected๋กœ ์ ‘๊ทผ์ œ์–ด์ž๊ฐ€ ์„ค์ •๋œ ์ด์œ ๋Š”

์ถ”์ƒ ๋ฉ”์„œ๋“œ๋กœ ์„ ์–ธํ•จ์œผ๋กœ์จ ๋ชจ๋“  ์„œ๋ธŒ ํด๋ž˜์Šค๊ฐ€ ์ด ํŒฉํ† ๋ฆฌ ๋ฉ”์„œ๋“œ๋ฅผ ๊ตฌํ˜„ํ•˜๋„๋ก ์š”๊ตฌํ•  ์ˆ˜ ์žˆ๊ณ ,

protected๋กœ ์„ค์ •ํ•จ์œผ๋กœ์„œ ์„œ๋ธŒ ํด๋ž˜์Šค์™€ ๊ฐ™์€ ํŒจํ‚ค์ง€์˜ ํด๋ž˜์Šค์— ์˜ํ•ด์„œ๋งŒ ์ ‘๊ทผ๋  ์ˆ˜ ์žˆ์œผ๋ฉฐ, API ์‚ฌ์šฉ์ž๋Š” createSopt์˜ ์กด์žฌ ์ž์ฒด๋ฅผ ์•Œ๋ ค์ฃผ์ง€ ์•Š๊ณ  createOperation ๊ณต๊ฐœ ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ๊ฐ์ฒด๋ฅผ ์š”์ฒญํ•˜๊ฒŒ ๋œ๋‹ค๋Š” ์žฅ์ ์ด ์žˆ๋‹ค.

public class Client {
    public static void main(String[] args) {
        // ๊ฐ ํƒ€์ž…์˜ ํŒฉํ† ๋ฆฌ ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ
        SoptFactory serverFactory = new ServerFactory();
        SoptFactory iosFactory = new IosFactory();

        // ์„œ๋ฒ„ ๊ฐ์ฒด ์ƒ์„ฑ ๋ฐ ์‚ฌ์šฉ
        Sopt server = serverFactory.createOperation();
        server.printLanguage();

        // iOS ๊ฐ์ฒด ์ƒ์„ฑ ๋ฐ ์‚ฌ์šฉ
        Sopt ios = iosFactory.createOperation();
        ios.printLanguage();
    }
}

ํด๋ผ์ด์–ธํŠธ ์ฝ”๋“œ์ด๋‹ค.

ํด๋ผ์ด์–ธํŠธ ์ฝ”๋“œ์—์„œ Server์™€ Ios ํด๋ž˜์Šค์— ๋Œ€ํ•œ ์˜์กด์„ฑ ์—†์ด ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

์˜์กด์„ฑ ์ฃผ์ž…์„ ์‚ฌ์šฉํ•ด์„œ ์™ธ๋ถ€์—์„œ Factory ํด๋ž˜์Šค๋ฅผ ๋ฐ›์•„์˜จ๋‹ค๋ฉด ServerFactory(), IosFactory() ์— ๋Œ€ํ•œ ์˜์กด์„ฑ๋„ ์ œ๊ฑฐ๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค.

Simple Factory ํ•œ๊ณ„ ๊ทน๋ณต

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

์ด๋ฒˆ์—๋„ Android ํŒŒํŠธ๊ฐ€ ์ถ”๊ฐ€๋œ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜์ž

Simple Factory์—์„œ๋Š” SoptFactory์˜ create ๋ฉ”์„œ๋“œ๋ฅผ ์ˆ˜์ •ํ•ด์•ผ ํ–ˆ๋‹ค.

๊นœ๋นกํ•˜๊ณ  switch-case๋ฅผ ๋„ฃ์ง€ ์•Š์•˜๋‹ค๋ฉด, ์ฝ”๋“œ์— ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๊ณ  Enum์— ์„ค์ •ํ•ด ๋†“์•˜๋˜ IllegalArgumentException๋กœ ์–ด๋Š์ •๋„ ๋ฐฉ์–ดํ•  ์ˆ˜๋Š” ์žˆ์ง€๋งŒ, ์ˆ˜์ •์—๋„ ์—ด๋ ค์žˆ๋‹ค๋Š” ๋‹จ์ ์€ ๋ณ€ํ•˜์ง€ ์•Š๋Š”๋‹ค.

ํ•˜์ง€๋งŒ ์šฐ๋ฆฌ๋Š” Factory Method ํŒจํ„ด์„ ์ ์šฉํ–ˆ๊ธฐ ๋•Œ๋ฌธ์—, ๊ธฐ์กด SoptFactory์˜ ์ˆ˜์ • ์—†์ด ์ƒˆ๋กœ์šด ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€๋งŒ ํ•˜๋ฉด ๋œ๋‹ค!!

public interface Sopt {
    void printLanguage();
}

public class Server implements Sopt {
    @Override
    public void printLanguage() {
        System.out.println("Java");
    }
}

public class Ios implements Sopt {
    @Override
    public void printLanguage() {
        System.out.println("Swift");
    }
}

public class Android implements Sopt { // ์ถ”๊ฐ€
    @Override
    public void printLanguage() {
        System.out.println("Kotlin");
    }
}

Sopt ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” Android ํด๋ž˜์Šค ์ถ”๊ฐ€

public abstract class SoptFactory {

    public final Sopt createOperation() {
        Sopt sopt = createSopt(); // ์„œ๋ธŒ ํด๋ž˜์Šค์—์„œ ๊ตฌ์ฒดํ™”ํ•œ ํŒฉํ† ๋ฆฌ ๋ฉ”์„œ๋“œ ์‹คํ–‰
        sopt.setup();  // .. ์ด๋ฐ–์˜ ๊ฐ์ฒด ์ƒ์„ฑ์— ๊ฐ€๋ฏธํ•  ๋กœ์ง ์‹คํ–‰
        return sopt;  // ์™„์„ฑ๋œ ๊ฐ์ฒด ๋ฐ˜ํ™˜
    }

    protected abstract Sopt createSopt();
}

public class ServerFactory extends SoptFactory {
    @Override
    public Sopt createSopt() {
        return new Server();
    }
}

public class IosFactory extends SoptFactory {
    @Override
    public Sopt createSopt() {
        return new Ios();
    }
}

public class AndroidFactory extends SoptFactory { // ์ถ”๊ฐ€
    @Override
    protected Sopt createSopt() {
        return new Android();
    }
}

Android ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋Š” AndroidFactory ์ •์˜

public class Client {
    public static void main(String[] args) {
        // ๊ฐ ํƒ€์ž…์˜ ํŒฉํ† ๋ฆฌ ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ
        SoptFactory serverFactory = new ServerFactory();
        SoptFactory iosFactory = new IosFactory();
        SoptFactory androidFactory = new AndroidFactory();

        // ์„œ๋ฒ„ ๊ฐ์ฒด ์ƒ์„ฑ ๋ฐ ์‚ฌ์šฉ
        Sopt server = serverFactory.createOperation();
        server.printLanguage();

        // iOS ๊ฐ์ฒด ์ƒ์„ฑ ๋ฐ ์‚ฌ์šฉ
        Sopt ios = iosFactory.createOperation();
        ios.printLanguage();
        
        // Andorid ๊ฐ์ฒด ์ƒ์„ฑ ๋ฐ ์‚ฌ์šฉ
        Sopt android = androidFactory.createOperation();
        android.printLanguage();
    }
}

์ด๋ ‡๊ฒŒ ์ตœ์ƒ์œ„ ๊ณต์žฅ ํด๋ž˜์Šค์˜ ์ฝ”๋“œ ์ˆ˜์ • ์—†์ด ์ƒˆ๋กœ์šด ๊ฐ์ฒด ํƒ€์ž…์„ ์ถ”๊ฐ€ํ•˜๊ธฐ ์œ„ํ•ด ์ƒˆ๋กœ์šด ํŒฉํ† ๋ฆฌ ํด๋ž˜์Šค๋งŒ ์ถ”๊ฐ€ํ•˜๋ฉด ๋˜๊ณ  ๊ธฐ์กด ์ฝ”๋“œ๋ฅผ ๋ณ€๊ฒฝํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค. ์ด๋Š” OCP๋ฅผ ์ž˜ ์ค€์ˆ˜ํ•œ๋‹ค๊ณ  ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

factory_3

์ด๋ ‡๊ฒŒ ์˜์กด๊ด€๊ณ„๋ฅผ ๊ฐ–๊ฒŒ ๋œ๋‹ค.

Factory Method - ์žฅ๋‹จ์ 

  • ์žฅ์ : Factory Method ํŒจํ„ด์˜ ๊ฐ€์žฅ ํฐ ์žฅ์ ์€ ์ง€๊ธˆ๊นŒ์ง€ ๋ณธ ๊ฒƒ์ฒ˜๋Ÿผย ์ˆ˜์ •์— ๋‹ซํ˜€์žˆ๊ณ  ํ™•์žฅ์—๋Š” ์—ด๋ ค์žˆ๋Š” OCP ์›์น™์„ ์ง€ํ‚ฌ ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์ด๋‹ค.
  • ๋‹จ์ : ๊ฐ„๋‹จํ•œ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ๋•Œ๋ณด๋‹ค ๋งŽ์€ ํด๋ž˜์Šค๋ฅผ ์ •์˜ํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ฝ”๋“œ๋Ÿ‰์ด ์ฆ๊ฐ€ํ•œ๋‹ค.