SSAFY11th-book-study / book-study

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

[3.5.1] JdbcContext에 적용된 템플릿/콜백 #29

Closed a-young-kim closed 5 months ago

a-young-kim commented 6 months ago

p.245 image

 public void add(final User user) throws  SQLException {
        this.jdbcContext.workWithStatementStrategy(new StatementStrategy(){
            @Override
            public PreparedStatement makePreparedStatement(Connection c) throws SQLException {
                PreparedStatement ps = c.prepareStatement("insert into user(id, name, password) values(?, ?, ?)");

                ps.setString(1, user.getId());
                ps.setString(2, user.getName());
                ps.setString(3, user.getPassword());
                return ps;
            }
        });
    }

add() 메소드 안의 this.jdbcContext~~ 부터 모든 내용을 콜백 오브젝트라고 생각하였는데 StatementStrategy만 <> 이라고 적혀 있어서 혹시 제가 잘못 생각했는지 궁금합니다.

limjongheok commented 6 months ago

우선 JdbcContext 클래스는 쿼리를 db로 보내고 반환(자원을 닫는) 역할을 하고 있음을 알 수 있습니다. 이때 쿼리는 INSERT , DELETE , UPDATE , SELECT 등 여러 쿼리가 올 수 있음을 알 수 있습니다.

public interface StatemenStrategy{
    public PreparedStatement makePreparedStatement(Connection c) throws SQLException;
}

그래서 다음과 같이 변화할 수 있는 부분이 쿼리 만드는 부분을 따로 인터페이스로 추출하여

class Insert implements StatemenStrategy{ ...}
class Delete implements StatemenStrategy{ ...}

class UserDao{
        StatemenStrategy s = new Insert(); 
       JdbcContext jdbcContext = new JdbcContext(); // ioc
       jdbcContext.setStatemenStrategy(s); // di 다음과 같이 사용
}

다음과 같이 알맞는 구현체를 만드는 전략패턴을 사용할 수 있습니다.

헌데 책에서는 탬플릿 콜백으로 익명 클래스 혹은 내부 클래스로 di를 주입 했습니다. 우선 질문에 올려주신 코드는 익명 클래스로 익명클래스를 변수를 지정해주어 변경하면

 private JdbcContext jdbcContext;
 public void add(final User user) throws  SQLException {
             StatementStrategy st = new StatementStrategy(){
            @Override
            public PreparedStatement makePreparedStatement(Connection c) throws SQLException {
                PreparedStatement ps = c.prepareStatement("insert into user(id, name, password) values(?, ?, ?)");

                ps.setString(1, user.getId());
                ps.setString(2, user.getName());
                ps.setString(3, user.getPassword());
                return ps;
            }
        });
        this.jdbcContext.workWithStatementStrategy(st);
    }

다음과 같으며 콜백은

  StatementStrategy st = new StatementStrategy(){
            @Override
            public PreparedStatement makePreparedStatement(Connection c) throws SQLException {
                PreparedStatement ps = c.prepareStatement("insert into user(id, name, password) values(?, ?, ?)");

                ps.setString(1, user.getId());
                ps.setString(2, user.getName());
                ps.setString(3, user.getPassword());
                return ps;
            }
        });

다음 부분이며

    this.jdbcContext.workWithStatementStrategy(st);

해당 부분은 di 부분인거 같습니다. 헌데 저도 이 부분에서 궁금한게 이와 같이 익명 내부 클래스를 사용한 다는 것은 특정 기능을 위해 한번 호출될때 이득을 볼거 같은데 userDao 뿐만아니라 앞으로 생성될 Dao 에서 또한 StatementStrategy 를 사용을 할텐데 이럴 경우 내부, 익명 클래스로 사용하는 거 보다 class를 구현하여 생성하여 사용하는 것이 더 좋지 않을까 궁금합니다.

a-young-kim commented 5 months ago

콜백

  StatementStrategy st = new StatementStrategy(){
            @Override
            public PreparedStatement makePreparedStatement(Connection c) throws SQLException {
                PreparedStatement ps = c.prepareStatement("insert into user(id, name, password) values(?, ?, ?)");

                ps.setString(1, user.getId());
                ps.setString(2, user.getName());
                ps.setString(3, user.getPassword());
                return ps;
            }
        });

DI

    this.jdbcContext.workWithStatementStrategy(st);