SSAFY11th-book-study / book-study

SSAFY 11기 6반의 '토비의 스프링 스터디'
0 stars 0 forks source link

[1.3.3] 의존성 주입, 싱글톤 패턴 #3

Closed limjongheok closed 8 months ago

limjongheok commented 9 months ago

앞서 책에서

interface ConnectionMaker2 {
    Connection makeConnection() throws ClassNotFoundException, SQLException;
}

인터페이스를 생성하고

public class DConnectionMaker2 implements ConnectionMaker2{
    @Override
    public Connection makeConnection() throws ClassNotFoundException, SQLException {
        // 독자적 방법으로 Connection 생성
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        Connection c = DriverManager.getConnection("jdbc:mysql://localhost:3306/springbook","root","root");

        return c;
    }
}

관련 구현 클래스를 생성 후

public class UserDao6 {
    private ConnectionMaker2 connectionMaker;

    public UserDao6(ConnectionMaker2 connectionMaker){
        connectionMaker = connectionMaker;
    }

    public void add(User1 user1) throws ClassNotFoundException, SQLException {
        Connection c = connectionMaker.makeConnection();
        // 기존 코드와 동일
    }

    public User1 get(User1 user1) throws ClassNotFoundException, SQLException{
        Connection c = connectionMaker.makeConnection();
        // 기존 코드와 동일
        return  user1;

    }

}
public class UserDao6Test {
    @Test
    public void UserDao6DTest(){
        ConnectionMaker2 connectionMaker2 = new DConnectionMaker2();
        UserDao6 userDao6 = new UserDao6(connectionMaker2);
    }
}

다음과 같이 UserDao6DTest 에서 UserDao6 에 생성자를 통해 ConnectionMaker2의 DConnectinMaker2랑 관계를 주입하는 방식을 사용하고 있습니다. 허나 제 생각에는 UserDao6 와 같은 Dao 클래스는 하나의 인스턴스만 생성하고 다른 객체들이 공유하는 형식인 싱글톤 패턴으로 사용해도 될거 같단 생각이 들었습니다. (어차피 한 기능의 인스턴스를 사용하며, 메모리를 아끼기 위해서) 허나 윗방식인 생성자를 통한 의존성 주입을 할 경우 싱글톤으로 인스턴스를 생성할 방식이 없는것 같아 질문 드립니다. 혹시 생성자 주입과 싱글톤 패턴을 같이 사용할 수 있는지? 만약 없다면 무슨 상황에 생성자 의존성 주입을 사용하고, 싱글톤 패턴을 사용하는지 질문 드립니다.

gmelon commented 9 months ago

말씀하신대로 UserDao는 단일 인스턴스로만 사용해도 문제가 없을 것 같아서 싱글톤 패턴을 적용하는게 좋아보이네요! 그런데 이를 구현하려면 제 생각에는 사용할 ConnectionMaker를 주입해주는 또 다른 객체가 필요할 것 같다고 생각합니다.

가령 팩토리 클래스를 만들고, 프로그램 실행 시 인자로 사용할 전략에 대한 값을 받아 UserDao 에 전달하고 팩토리 클래스를 통해 ConnectionMaker를 생성하는 등의 방식이 가능할 것 같아요! 추가로 이렇게 하면 ConnectionMaker도 싱글턴으로 유지할 수도 있을 것이라고 생각합니다.

그런데 이러한 기능을 개발자가 직접 만들기는 어려우니 스프링과 같은 DI 컨테이너의 도움을 받는 것이라고 이해했습니다.

hj-k66 commented 9 months ago

해당 내용은 이후 1.6.1에서 설명하고 있습니다.

우선 일반적인 자바 싱글톤 방식에서는 private 생성자이기 때문에 생성자 주입을 할 수 없습니다. 그래서 스프링에서는 싱글톤 레지스트리를 통해 오브젝트를 싱글톤 형태로 생성, 관리합니다. 이를 통해 단점이었던 스태틱 메소드와 private 생성자를 사용해야하는 것에 벗어나 일반적인 클래스처럼 public 생성자를 가질 수 있다 합니다!