πŸ“šμ½μ€ μ±… 정리/μžλ°” λ§ˆμŠ€ν„°λΆ

[μžλ°” λ§ˆμŠ€ν„°λΆ] 12μž₯ λ””μžμΈνŒ¨ν„΄ 즐기기 - 생성

yunanP 2021. 9. 22. 22:05

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 νŒ¨ν„΄μ„ μ΄μš©ν•˜λ©΄ μ—¬λŸ¬ μž‘μ—…μ΄ λ™μ‹œμ— μΈμŠ€ν„΄μŠ€λ₯Ό μ‘°μž‘ν•΄λ„ 무결성을 μ†μƒν•˜μ§€ μ•Šλ„λ‘ μΈμŠ€ν„΄μŠ€μ— 닀쀑 접속을 μ˜ˆμƒν•œ 배타적인 처리λ₯Ό μ‹€μ‹œν•΄μ•Ό ν•œλ‹€λŠ” 점을 κΈ°μ–΅ν•΄λ‘μž.