Coding Planet

[μ΄νŽ™ν‹°λΈŒ μžλ°”]chapter2 : [μ•„μ΄ν…œ5] μžμ›μ„ λͺ…μ‹œν•˜μ§€ 말고 의쑴 객체 μ£Όμž…μ„ μ‚¬μš©ν•˜λΌ λ³Έλ¬Έ

πŸ’» Java Study/Java 이둠 정리

[μ΄νŽ™ν‹°λΈŒ μžλ°”]chapter2 : [μ•„μ΄ν…œ5] μžμ›μ„ λͺ…μ‹œν•˜μ§€ 말고 의쑴 객체 μ£Όμž…μ„ μ‚¬μš©ν•˜λΌ

jhj.sharon 2023. 8. 11. 01:11
λ°˜μ‘ν˜•

μ•„μ΄ν…œ5: μžμ›μ„ λͺ…μ‹œν•˜μ§€ 말고 의쑴 객체 μ£Όμž…μ„ μ‚¬μš©ν•˜λΌ

이전에 μ‚΄νŽ΄λ³Έ 정적 μœ ν‹Έλ¦¬ν‹° ν΄λž˜μŠ€λ‚˜ μ‹±κΈ€ν„΄ 방식은 μ‚¬μš©ν•˜λŠ” μžμ›μ— 따라 λ™μž‘μ΄ λ‹¬λΌμ§€λŠ” ν΄λž˜μŠ€μ—λŠ” μ ν•©ν•˜μ§€ μ•Šλ‹€. 정적 μœ ν‹Έλ¦¬ν‹° ν΄λž˜μŠ€λŠ” μƒνƒœλ₯Ό κ°€μ§ˆ 수 μ—†λ‹€. 즉 μžμ›μ— 따라 λ™μž‘μ„ λ³€κ²½ν•˜λŠ” 것이 μ–΄λ ΅λ‹€. 싱글턴은 μ „μ—­ μƒνƒœλ₯Ό κ°€μ§€κ²Œ λ˜λ―€λ‘œ μ—¬λŸ¬ μžμ›μ„ κ΄€λ¦¬ν•˜κ±°λ‚˜ λ™μž‘μ„ λ™μ μœΌλ‘œ λ³€κ²½ν•˜κΈ° μ–΄λ ΅κ²Œ λ§Œλ“ λ‹€. λ˜ν•œ 정적 μœ ν‹Έλ¦¬ν‹° ν΄λž˜μŠ€λ‚˜ 싱글턴은 상속을 ν†΅ν•œ ν™•μž₯이 μ–΄λ ΅κ³  ν…ŒμŠ€νŠΈλ„ μ–΄λ ΅λ‹€λŠ” 단점이 μžˆλ‹€. λ”°λΌμ„œ β‘ ν΄λž˜μŠ€κ°€ μ—¬λŸ¬ μžμ› μΈμŠ€ν„΄μŠ€λ₯Ό μ§€μ›ν•΄μ•Όν•˜κ³ , β‘‘ ν΄λΌμ΄μ–ΈνŠΈκ°€ μ›ν•˜λŠ” μžμ›μ„ μ‚¬μš©ν•΄μ•Όν•˜λŠ” 쑰건을 λ§Œμ‘±ν•˜λ €λ©΄ μΈμŠ€ν„΄μŠ€λ₯Ό 생성할 λ•Œ μƒμ„±μžμ— ν•„μš”ν•œ μžμ›μ„ λ„˜κ²¨μ£ΌλŠ” 방식인 의쑴 객체 μ£Όμž…μ΄ μ ν•©ν•˜λ‹€.

 

1. 의쑴 객체 μ£Όμž…(Dependency Injection, DI)μ΄λž€?

  • 의쑴 객체 μ£Όμž…μ΄λž€ 객체의 μ˜μ‘΄μ„±μ„ μ™ΈλΆ€μ—μ„œ μ£Όμž…ν•΄μ£ΌλŠ” 것이닀. 이둜 인해 κ°μ²΄λŠ” μžμ‹ μ˜ μ˜μ‘΄μ„±μ„ 직접 μƒμ„±ν•˜κ±°λ‚˜ 관리할 ν•„μš”κ°€ μ—†κ²Œ 되며, ν…ŒμŠ€νŠΈμ™€ μž¬μ‚¬μš©μ„±μ΄ ν–₯μƒλœλ‹€.
  • μ΄λŸ¬ν•œ 방식은 μžμ›μ΄ λͺ‡ κ°œλ“  의쑴 관계가 μ–΄λ–»λ“  상관없이 잘 μž‘λ™ν•œλ‹€. λ˜ν•œ λΆˆλ³€μ„ 보μž₯ν•˜μ—¬ 같은 μžμ›μœΌλ‘œ μ‚¬μš©ν•˜λ €λŠ” μ—¬λŸ¬ ν΄λΌμ΄μ–ΈνŠΈκ°€ 의쑴 객체듀을 μ•ˆμ‹¬ν•˜κ³  κ³΅μœ ν•  수 μžˆκΈ°λ„ ν•˜λ‹€.
  • 의쑴 객체 μ£Όμž…μ€ μƒμ„±μž, 정적 νŒ©ν„°λ¦¬, λΉŒλ” λͺ¨λ‘μ— λ˜‘κ°™μ΄ μ‘μš©ν•  수 μžˆλ‹€.

 

2. 의쑴 객체 μ£Όμž…(Dependency Injection, DI) μ˜ˆμ‹œ

1) λͺ¨λ“  λ°μ΄ν„°λ² μ΄μŠ€ 연결을 μœ„ν•œ 곡톡 μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ •μ˜ν•œλ‹€.

public interface DatabaseConnector {
    void connect();
    void save(String data);
}

2) λ‹€μ–‘ν•œ μΈν„°νŽ˜μ΄μŠ€ 연결을 μœ„ν•œ κ΅¬ν˜„ 클래슀

public class MySQLConnector implements DatabaseConnector {
    @Override
    public void connect() {
        // MySQL에 μ—°κ²°ν•˜λŠ” μ½”λ“œ
    }

    @Override
    public void save(String data) {
        // 데이터λ₯Ό MySQL에 μ €μž₯ν•˜λŠ” μ½”λ“œ
    }
}

public class PostgreSQLConnector implements DatabaseConnector {
    @Override
    public void connect() {
        // PostgreSQL에 μ—°κ²°ν•˜λŠ” μ½”λ“œ
    }

    @Override
    public void save(String data) {
        // 데이터λ₯Ό PostgreSQL에 μ €μž₯ν•˜λŠ” μ½”λ“œ
    }
}

3) 데이터λ₯Ό μ €μž₯ν•˜λŠ” ν΄λΌμ΄μ–ΈνŠΈ 클래슀 μ •μ˜

  • 이 ν΄λΌμ΄μ–ΈνŠΈ ν΄λž˜μŠ€λŠ” μƒμ„±μžλ₯Ό 톡해 DatabaseConnector κ΅¬ν˜„μ²΄λ₯Ό μ£Όμž…λ°›λŠ”λ‹€.
public class DataSaver {
    private DatabaseConnector db;

    public DataSaver(DatabaseConnector dbConnector) {
        this.db = dbConnector;
    }

    public void saveData(String data) {
        db.connect();
        db.save(data);
    }
}

4) ν•„μš”ν•œ λ°μ΄ν„°λ² μ΄μŠ€ 연결을 μ„ νƒν•΄μ„œ 객체λ₯Ό μƒμ„±ν•˜κ³  μ‚¬μš©

public class Main {
    public static void main(String[] args) {
        DataSaver mysqlSaver = new DataSaver(new MySQLConnector());
        DataSaver postgresSaver = new DataSaver(new PostgreSQLConnector());

        mysqlSaver.saveData("someDataForMySQL");
        postgresSaver.saveData("someDataForPostgreSQL");
    }
}

 

3. νŒ©ν„°λ¦¬ λ©”μ„œλ“œ νŒ¨ν„΄(Factory Method pattern)κ³Ό Supplier<T>

 

1) νŒ©ν„°λ¦¬ λ©”μ„œλ“œ νŒ¨ν„΄

  • νŒ©ν„°λ¦¬ λ©”μ„œλ“œ νŒ¨ν„΄μ€ 의쑴 객체 μ£Όμž… νŒ¨ν„΄μ˜ λ³€ν˜•μœΌλ‘œ 객체 생성에 κ΄€ν•œ μ±…μž„μ„ μ„œλΈŒν΄λž˜μŠ€λ‘œ μœ„μž„ν•˜λŠ” λ””μžμΈ νŒ¨ν„΄μ΄λ‹€. 이 νŒ¨ν„΄μ€ μΈν„°νŽ˜μ΄μŠ€λ₯Ό 톡해 객체λ₯Ό μƒμ„±ν•˜μ§€λ§Œ, 객체 μƒμ„±μ˜ μ‹€μ œ κ΅¬ν˜„μ€ μ„œλΈŒν΄λž˜μŠ€μ— μœ„μž„λ˜μ–΄ μžˆλ‹€. 즉, μƒμ„±μžμ— μžμ›νŒ©ν„°λ¦¬λ₯Ό λ„˜κ²¨μ£ΌλŠ” 것이닀.
  • νŒ©ν„°λ¦¬λž€ ν˜ΈμΆœν•  λ•Œλ§ˆλ‹€ νŠΉμ •νƒ€μž…μ˜ μΈμŠ€ν„΄μŠ€λ₯Ό λ°˜λ³΅ν•΄μ„œ λ§Œλ“€μ–΄μ£ΌλŠ” 객체이닀. 
*μž₯점 **
- ν΄λΌμ΄μ–ΈνŠΈ μ½”λ“œλŠ” μƒμ„±λ˜λŠ” 객체의 ꡬ체적인 클래슀λ₯Ό μ•Œ ν•„μš”κ°€ μ—†λ‹€.
- 객체 생성 λ‘œμ§μ„ μ€‘μ•™ν™”ν•˜μ—¬ μ½”λ“œ 쀑볡을 쀄일 수 μžˆλ‹€.
- ν™•μž₯성이 쒋아진닀. μƒˆλ‘œμš΄ 객체 μœ ν˜•μ„ μΆ”κ°€ν•˜λ €λ©΄ κΈ°μ‘΄ μ½”λ“œλ₯Ό λ³€κ²½ν•˜μ§€ μ•Šκ³  μƒˆλ‘œμš΄ 클래슀λ₯Ό μΆ”κ°€ν•˜κΈ°λ§Œ ν•˜λ©΄ λœλ‹€.

 

2) Java8 Supplier<T>

  • SupplierλŠ” Java8μ—μ„œ λ„μž…λœ ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€ 쀑 ν•˜λ‚˜λ‘œ, 주둜 객체 μƒμ„±μ΄λ‚˜ μ—°μ‚° κ²°κ³Όλ₯Ό μ œκ³΅ν•˜λŠ” 데 μ‚¬μš©λœλ‹€.
  • SupplierλŠ” λ§€κ°œλ³€μˆ˜λ₯Ό 받지 μ•Šκ³  λ‹¨μˆœνžˆ 무엇인가λ₯Ό λ°˜ν™˜ν•˜λŠ” μΆ”μƒλ©”μ„œλ“œκ°€ μ‘΄μž¬ν•œλ‹€, μΈν„°νŽ˜μ΄μŠ€μ˜ μ •μ˜λŠ” λ‹€μŒκ³Ό κ°™λ‹€.
  • @FunctionalInterfaceλŠ” ν•΄λ‹Ή μΈν„°νŽ˜μ΄μŠ€κ°€ μ •ν™•νžˆ ν•˜λ‚˜μ˜ 좔상 λ©”μ„œλ“œλ§Œμ„ 가지고 μžˆμŒμ„ λ‚˜νƒ€λ‚Έλ‹€. 이둜 인해 λžŒλ‹€ ν‘œν˜„μ‹κ³Ό ν•¨κ»˜ μ‚¬μš©ν•  수 있게 λœλ‹€.
@FunctionalInterface
public interface Supplier<T> {
    T get();// λ§€κ°œλ³€μˆ˜κ°€ μ—†κ³ , λ‹¨μˆœνžˆ 무엇인가λ₯Ό λ°˜ν™˜ν•  λ•Œ
}

2) νŒ©ν„°λ¦¬ λ©”μ„œλ“œ νŒ¨ν„΄κ³Ό Java8 Supplier<T>

  • Java 8의 Supplier μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ‚¬μš©ν•˜λ©΄ νŒ©ν„°λ¦¬ λ©”μ„œλ“œ νŒ¨ν„΄μ„ 더 μœ μ—°ν•˜κ³  κ°„κ²°ν•˜κ²Œ κ΅¬ν˜„ν•  수 μžˆλ‹€.
  • 예λ₯Ό λ“€μ–΄, μ—¬λŸ¬ μœ ν˜•μ˜ 동물을 μƒμ„±ν•˜λŠ” νŒ©ν„°λ¦¬λ₯Ό μƒκ°ν•΄λ³΄μž.
  • μ•„λž˜ μ½”λ“œμ—μ„œ, createAnimal λ©”μ„œλ“œλŠ” Supplier을 λ§€κ°œλ³€μˆ˜λ‘œ λ°›μ•„ ν•΄λ‹Ή κ³΅κΈ‰μžλ₯Ό 톡해 동물 μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•œλ‹€. Dog::new 및 Cat::newλŠ” λ©”μ„œλ“œ μ°Έμ‘°λ₯Ό μ‚¬μš©ν•˜μ—¬ ν•΄λ‹Ή 클래슀의 μƒμ„±μžλ₯Ό μ°Έμ‘°ν•œλ‹€.
public interface Animal {
    void speak();
}

public class Dog implements Animal {
    @Override
    public void speak() {
        System.out.println("Woof!");
    }
}

public class Cat implements Animal {
    @Override
    public void speak() {
        System.out.println("Meow!");
    }
}

public class AnimalFactory {

    public static Animal createAnimal(Supplier<Animal> supplier) {
        return supplier.get();
    }

    public static void main(String[] args) {
        Animal dog = createAnimal(Dog::new);
        dog.speak();

        Animal cat = createAnimal(Cat::new);
        cat.speak();
    }
}
  • ν•œμ •μ  μ™€μΌλ“œμΉ΄λ“œ νƒ€μž…μ€ Java의 μ œλ„€λ¦­μ„ μ‚¬μš©ν•  λ•Œ νŠΉμ • νƒ€μž…μ˜ μ„œλΈŒνƒ€μž…λ§Œμ„ ν—ˆμš©ν•˜λ„λ‘ μ œν•œν•˜λŠ” κΈ°λŠ₯이닀. 이λ₯Ό 톡해 μ œλ„€λ¦­ νƒ€μž…μ˜ μœ μ—°μ„±μ„ 높일 수 μžˆλ‹€.
  • Supplierλ₯Ό μž…λ ₯으둜 λ°›λŠ” λ©”μ„œλ“œμ—μ„œ ν•œμ •μ  μ™€μΌλ“œμΉ΄λ“œ νƒ€μž…μ„ μ‚¬μš©ν•˜λ©΄, νŠΉμ • νƒ€μž…μ˜ μ„œλΈŒνƒ€μž…λ§Œμ„ μƒμ„±ν•˜λŠ” Supplierλ₯Ό 받아듀일 수 있게 λœλ‹€.
  • λͺ¨λ“  동물을 생성할 수 μžˆλŠ” νŒ©ν„°λ¦¬κ°€ μ•„λ‹ˆλΌ, 였직 Dogλ§Œμ„ 생성할 수 μžˆλŠ” νŒ©ν„°λ¦¬λ₯Ό μ›ν•œλ‹€λ©΄ λ‹€μŒκ³Ό 같이 ν•œμ •μ  μ™€μΌλ“œμΉ΄λ“œ νƒ€μž…μ„ μ‚¬μš©ν•  수 μžˆλ‹€.
public Animal createDogSupplier(Supplier<? extends Dog> dogSupplier) {
    return dogSupplier.get();
}

 

 

단

λ°˜μ‘ν˜•
Comments