๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

๐Ÿ“š์ฝ์€ ์ฑ… ์ •๋ฆฌ/์ž๋ฐ” ๋งˆ์Šคํ„ฐ๋ถ

[์ž๋ฐ” ๋งˆ์Šคํ„ฐ๋ถ] 12์žฅ ๋””์ž์ธํŒจํ„ด ์ฆ๊ธฐ๊ธฐ - ์ƒ์„ฑ

12.1 ๋””์ž์ธ ํŒจํ„ด์˜ ๊ธฐ๋ณธ

12.1.1 ๋””์ž์ธ ํŒจํ„ด์ด๋ž€?

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

 

์˜ˆ๋ฅผ ๋“ค์–ด, '์–ด๋–ค ์ƒํƒœ๊ฐ€ ๋ฐ”๋€Œ์—ˆ์„ ๋•Œ ๋ฐ˜์‘ํ•˜๋Š” ํด๋ž˜์Šค๊ตฐ ๋งŒ๋“ค๊ธฐ'

'๋‹ค๋ฅธ ํŒ€์ด ๋งŒ๋“  ๋ถ€ํ’ˆ๊ณผ์˜ ์ค‘๊ฐœ๋ฅผ ํ•˜๋Š” ํด๋ž˜์Šค ๋งŒ๋“ค๊ธฐ',

'์žฌ๊ท€์ ์ธ ๊ตฌ์กฐ๋ฅผ ํด๋ž˜์Šค๋กœ ํ‘œํ˜„ํ•˜๊ธฐ'์™€ ๊ฐ™์€ ๊ฒƒ๋“ค์ด ์žˆ๋‹ค.

 

์ด๋Ÿฐ ๋น„์Šทํ•œ ๋ชฉ์ ์— ๋Œ€ํ•ด ํด๋ž˜์Šค ๊ตฌ์กฐ์˜ ๋ชจ๋ฒ”์‚ฌ๋ก€๋ฅผ ํŒจํ„ด์œผ๋กœ ์ •๋ฆฌํ•œ ๊ฒƒ์ด ๋””์ž์ธ ํŒจํ„ด์ด๋‹ค. 

์ด ์ค‘ ๊ฐ€์žฅ ์œ ๋ช…ํ•œ ๊ฒƒ์ด 'GoF ๋””์ž์ธ ํŒจํ„ด'์ด๋ฉฐ ๊ฐ์ฒด์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์— ๋„์›€์ด๋˜๋Š” ๋””์ž์ธ ํŒจํ„ด 23๊ฐ€์ง€๋ฅผ ์†Œ๊ฐœํ•œ๋‹ค.

23์ข…๋ฅ˜์˜ ํŒจํ„ด์€ ํฌ๊ฒŒ 3๊ฐ€์ง€๋กœ ๋ถ„๋ฅ˜๋˜์–ด ์žˆ๋‹ค.

  1. ๊ฐ์ฒด์˜ '์ƒ์„ฑ'์— ๊ด€ํ•œ ํŒจํ„ด
  2. ํ”„๋กœ๊ทธ๋žจ์˜ '๊ตฌ์กฐ'์— ๊ด€ํ•œ ํŒจํ„ด
  3. ๊ฐ์ฒด์˜ 'ํ–‰๋™'์— ๊ด€ํ•œ ํŒจํ„ด

๋””์ž์ธ ํŒจํ„ด์„ ์‚ฌ์šฉํ•˜๋ฉด ์ข‹์€์ 

1. ์žฌ์‚ฌ์šฉ์„ฑ์ด ๋†’๊ณ  ์œ ์—ฐ์„ฑ ์žˆ๋Š” ์„ค๊ณ„๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค.

๊ณ ์ˆ˜๋“ค์ด ์ž˜ ์„ค๊ณ„ํ•ด๋‘” ํŒจํ„ด์„ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋งค์šฐ ์œ ์šฉํ•˜๋‹ค.

 

2. ์˜์‚ฌ ์†Œํ†ต์ด ์‰ฌ์›Œ์ง„๋‹ค.

์ž์ฃผ ์‚ฌ์šฉํ•˜๋Š” ํŠน์ • ์„ค๊ณ„๋ฅผ ์„ค๋ช…ํ•  ๋•Œ ๋‹ค๋ฅธ ๊ธฐ์ˆ ์ž์—๊ฒŒ ์ด๋ฅผ ์„ค๋ช…ํ•˜๊ธฐ ์œ„ํ•ด ๋งŽ์€ ๋ถ€๊ฐ€์„ค๋ช…์„ ํ•ด์•ผํ•˜์ง€๋งŒ 'ํŒจํ„ด'์„ ์•Œ๊ณ  ์žˆ๋‹ค๋ฉด ์ด๋ฅผ ํ†ตํ•ด ์†Œํ†ต์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

 

12.2 ์ƒ์„ฑ์— ๊ด€ํ•œ ํŒจํ„ด

  • ์ƒ์„ฑ์— ๊ด€ํ•œ ๋””์ž์ธ ํŒจํ„ด

AbstractFactory - ๊ด€๋ จ๋œ ์ผ๋ จ์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒํ™ฉ์— ๋”ฐ๋ผ ์ ์ ˆํ•˜๊ฒŒ ์ƒ์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ• ์ œ๊ณต.

Builder - ๋ณตํ•ฉํ™”๋œ ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ ๊ณผ์ •์„ ์€ํํ•œ๋‹ค.

Singleton - ํŠน์ • ํด๋ž˜์Šค์— ๋Œ€ํ•ด ์ธ์Šคํ„ด์Šค๊ฐ€ ํ•˜๋‚˜์ž„์„ ๋ณด์žฅ.

 

12.2.1 AbstractFactory ํŒจํ„ด - ์ผ๋ จ์˜ ์ธ์Šคํ„ด์Šค๊ตฐ ๋ชจ์•„์„œ ์ƒ์„ฑํ•˜๊ธฐ

์„ค์ •ํŒŒ์ผ์— ๊ธฐ์žฌ๋œ ์ •๋ณด์— ๋”ฐ๋ผ DBMS๋ฅผ ์ˆ˜์‹œ๋กœ ๋ฐ”๊ฟ”์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ํ”„๋กœ๊ทธ๋žจ์„ ์ƒ๊ฐํ•ด๋ณด์ž. DBMS์— ์ ‘๊ทผํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ํ”„๋กœ๊ทธ๋žจ์—์„œ ์ปค๋„ฅ์…˜ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ๋ฐ์ดํ„ฐ์— ์•ก์„ธ์Šคํ•˜๊ฒŒ ๋œ๋‹ค. ์ด ๊ณผ์ •์€ DBMS ๋งˆ๋‹ค ๋‹ค๋ฅด๊ธฐ ๋•Œ๋ฌธ์— DBMS๋งˆ๋‹ค ์—ฐ๊ด€๋œ ์ธ์Šคํ„ด์Šค๋ฅผ ํ•œ๊บผ๋ฒˆ์— ์ƒ์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค๋ฉด ๋งค์šฐ ํŽธํ•  ๊ฒƒ์ด๋‹ค.

 

AbstractFactory ํŒจํ„ด์€ ์ธ์Šคํ„ด์Šค์˜ ์ƒ์„ฑ์„ ์ „๋ฌธ์œผ๋กœ ์‹ค์‹œํ•˜๋Š” ํด๋ž˜์Šค(Factory)๋ฅผ ์ค€๋น„ํ•˜์—ฌ ์ผ๊ด€์„ฑ์„ ์œ ์ง€ํ•ด์•ผํ•˜๋Š” ์ธ์Šคํ„ด์Šค๋“ค์„ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•œ ํŒจํ„ด์ด๋‹ค.

 

  • Factory.java
public interface Factory {
    Connection getConnection();

    Configuration getConfiguration();
}

DBMS๊ฐ€  ์ƒ์„ฑํ•ด์•ผํ•˜๋Š” ํด๋ž˜์Šค๋ฅผ ๋ฉ”์„œ๋“œ๋กœ ์ •์˜ํ•ด๋‘์—ˆ๋‹ค.

 

  • createProduct() ์— ๋Œ€ํ•œ ์ •์˜ (์ปค๋„ฅ์…˜, ์„ค์ • ๋“ฑ)
public abstract class Configuration {
    // ์ž„์˜์˜ ์ฒ˜๋ฆฌ
}

public abstract class Connection {
    // ์ž„์˜์˜ ์ฒ˜๋ฆฌ
}

 

 

  • ConcreteFactory (๊ตฌ์ฒด์ ์ธ ํŒฉํ† ๋ฆฌ์— ๋Œ€ํ•œ ๊ตฌํ˜„)
// PostgreSQL์„ ์ƒ์„ฑํ•˜๋Š” ํด๋ž˜์Šค
public class PostgreSQLFactory implements Factory{

    @Override
    public Connection getConnection() {
        return new PostgreSQLConnection();
    }

    @Override
    public Configuration getConfiguration() {
        return new POstgreSQLConfiguration();
    }
}

// MySQL์„ ์ƒ์„ฑํ•˜๋Š” ํด๋ž˜์Šค
public class MySQLFactory implements Factory {

    @Override
    public Connection getConnection() {
        return new MySQLConnection();
    }

    @Override
    public Configuration getConfiguration() {
        return new MySQLConfiguration();
    }
}

 

  • ์ƒ์„ฑํ•ด์•ผํ•˜๋Š” ๊ฐ์ฒด๋ฅผ ๊ตฌํ˜„ํ•œ ๊ตฌํ˜„์ฒด๋“ค
public class MySQLConfiguration extends Configuration {
    //MySQL ์„ค์ • ์ •๋ณด์™€ ๋กœ๋”ฉ ์ฒ˜๋ฆฌ
}

public class MySQLConnection extends Connection {
    // MySQL์˜ ์ปค๋„ฅ์…˜ ์ฒ˜๋ฆฌ
}

public class POstgreSQLConfiguration extends Configuration {
    // PostgreSQL์˜ ์„ค์ • ์ •๋ณด์˜ ๋กœ๋”ฉ ์ฒ˜๋ฆฌ
}

public class PostgreSQLConnection extends Connection {
    // PostgreSQL ์ปค๋„ฅ์…˜ ์ฒ˜๋ฆฌ
}

 

  • SampleMain.java
public class SampleMain {
    public static void main(String[] args) {
        String env = "PostgreSQL";
        Factory factory = createFactory(env);

        Connection connection = factory.getConnection();
        Configuration configuration = factory.getConfiguration();
    }

    private static Factory createFactory(String env) {
        switch (env) {
            case "PostgreSQL":
                return new PostgreSQLFactory();
            case "MySQL":
                return new MySQLFactory();
            default:
                throw new IllegalArgumentException();
        }
    }
}

๋ฉ”์ธ ๋ฉ”์„œ๋“œ์—์„œ๋Š” "์„ค์ •๊ฐ’"์— ๋”ฐ๋ผ ๊ฐ๊ฐ์˜ DBMS์— ๋Œ€์‘๋˜๋Š” ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•œ๋‹ค. ๋ฐ˜ํ™˜๊ฐ’์„ ๊ณตํ†ต์˜ ์ถ”์ƒ์ ์ธ ํด๋ž˜์Šค๋กœ ๊ตฌํ˜„ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ตฌํ˜„ ๋‚ด์šฉ์„ ์‹ ๊ฒฝ์“ฐ์ง€ ์•Š๊ณ  ์ปค๋„ฅ์…˜ ์ •๋ณด์™€ ์„ค์ • ์ •๋ณด๋ฅผ ์ทจ๋“ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

https://sup2is.github.io/2020/06/22/abstract-factory-pattern.html

 

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

 

12.2.2 Builder ํŒจํ„ด - ๋ณตํ•ฉํ™”๋œ ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ ๊ณผ์ •์„ ์€ํํ•œ๋‹ค.

์ƒ์„ฑ์˜ ํ๋ฆ„์„ ๊ณตํ†ตํ™”ํ•˜๊ธฐ ์œ„ํ•œ ์ˆ˜๋‹จ์ด 'Builder ํŒจํ„ด'์ด๋‹ค. ๋ณต์žกํ•œ ์ƒ์‚ฐ ๊ณผ์ •์ด ํ•„์š”ํ•œ ์ธ์Šคํ„ด์Šค์— ๋Œ€ํ•ด ๊ทธ ์ƒ์„ฑ๊ณผ์ •์„ ์€ํํ•จ์œผ๋กœ์จ ๋™์ผ๊ณผ์ •์œผ๋กœ ์„œ๋กœ ๋‹ค๋ฅธ ๋‚ด๋ถ€ ํ˜•์‹์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ์–ป๊ธฐ ์œ„ํ•œ ํŒจํ„ด์ด๋‹ค.

 

  • Builder ์ธํ„ฐํŽ˜์ด์Šค
public interface Builder {
    void createHeader();

    void createContents();

    void createFooter();

    Page getResult();
}

 

  • Builder ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” Director ํด๋ž˜์Šค - ์ฒ˜๋ฆฌ์˜ ๊ณผ์ •์„ ๊ตฌํ˜„ํ•ด๋‘ .
public class Director {
    private Builder builder;

    public Director(Builder builder) {
        this.builder = builder;
    }

    public Page construct() {
        builder.createHeader();
        builder.createContents();
        builder.createFooter();

        return builder.getResult();
    }
}

 

  • Page
public class TopPage extends Page{
    // ๋งจ ์œ„ ํŽ˜์ด์ง€
}

public class Page {
    private String header;
    private String contents;
    private String footer;

    // getter, setter ์ƒ๋žต.
}

 

  • ๋นŒ๋”๋ฅผ ์–ด๋–ป๊ฒŒ ๊ตฌํ˜„ํ• ์ง€์— ๋Œ€ํ•œ ์‹ค์ œ ์ฒ˜๋ฆฌ -> TopPageBuilder
public class TopPageBuilder implements Builder{
    private TopPage page;

    public TopPageBuilder() {
        this.page = new TopPage();
    }


    @Override
    public void createHeader() {
        this.page.setHeader("TOP Header");
    }

    @Override
    public void createContents() {
        this.page.setContents("TOP Contents");
    }

    @Override
    public void createFooter() {
        this.page.setFooter("TOP Footer");
    }

    @Override
    public Page getResult() {
        return this.page;
    }
}

 

  • SampleMain.java
public class SampleMain {
    public static void main(String[] args) {
        Builder builder = new TopPageBuilder();
        Director director = new Director(builder);

        Page page = director.construct();
    }
}

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

์–ด๋–ป๊ฒŒ ๊ตฌํ˜„๋œ Builder๋ฅผ ๋„˜๊ฒจ์ฃผ๋Š”๋ƒ์— ๋”ฐ๋ผ Page์˜ ๋‚ด์šฉ์ด ๋‹ฌ๋ผ์งˆ ์ˆ˜ ์žˆ๋‹ค.

 

๋นŒ๋” ํŒจํ„ด์„ ์ด์šฉํ•˜๋ฉด ์ด์šฉ์ž๊ฐ€ ์ƒ์„ฑ ์ฒ˜๋ฆฌ์˜ ํ๋ฆ„์„ ์˜์‹ํ•˜์ง€ ์•Š๊ณ (Director์ฒ˜๋ฆฌ) ๊ฐœ๋ณ„ ์ฒ˜๋ฆฌ(Builder ๊ตฌํ˜„)์—๋งŒ ์ฃผ๋ชฉํ•˜์—ฌ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ด ์žฅ์ ์ด๋‹ค.

 

12.2.3 Singleton ํŒจํ„ด - ํŠน์ • ํด๋ž˜์Šค์— ๋Œ€ํ•ด ์ธ์Šคํ„ด์Šค๊ฐ€ ํ•˜๋‚˜์ž„์„ ๋ณด์žฅํ•œ๋‹ค.

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

 

์ด๋ฅผ ์‹คํ˜„ํ•˜๊ธฐ ์œ„ํ•œ ์ˆ˜๋‹จ์ด ๋ฐ”๋กœ SingletonํŒจํ„ด์ด๋‹ค. (ํŠน์ • ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค๊ฐ€ ์œ ์ผํ•œ ์กด์žฌ์ž„์„ ๋ณด์žฅํ•˜๋Š” ๊ฒƒ)

 

public class Configure {
    private static Configure instance = new Configure();
    
    private Configure() {
        // ์„ค์ • ์ •๋ณด๋ฅผ ์ฝ์–ด๋“ค์ด๋Š” ์ฒ˜๋ฆฌ 
    }
    
    public static Configure getInstance() {
        return instance;
    }
}

 

public class SampleMain {
    public static void main(String[] args) {
        Configure configure = Configure.getInstance();
    }
}

 

getInstnace() ์Šคํƒœํ‹ฑ ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด Configure๊ฐ์ฒด๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋‹ค. ์ด ๊ฐ์ฒด๋Š” ์‹œ์Šคํ…œ์—์„œ ์‚ฌ์šฉํ•˜๋Š” ์œ ์ผํ•œ Configure ๊ฐ์ฒด์ด๋‹ค.

 

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