HomeAboutMeBlogGuest
© 2025 Sejin Cha. All rights reserved.
Built with Next.js, deployed on Vercel
📝
남득윤 학습 저장소
/
토비의 스프링 3.1 Vol.1 스프링의 이해와 원리
토비의 스프링 3.1 Vol.1 스프링의 이해와 원리
/
1️⃣
1장 - 오브젝트와 의존관계, 초난감 DAO
1️⃣

1장 - 오브젝트와 의존관계, 초난감 DAO

 

초난감 DAO v1

public class UserDao { public void add(User user) throws ClassNotFoundException, SQLException { Class.forName("com.mysql.cj.jdbc.Driver"); Connection c = DriverManager.getConnection("jdbc:mysql://localhost/springbook?characterEncoding=UTF-8", "spring", "book"); PreparedStatement ps = c.prepareStatement( "insert into users(id, name, password) values(?,?,?)"); ps.setString(1, user.getId()); ps.setString(2, user.getName()); ps.setString(3, user.getPassword()); ps.executeUpdate(); ps.close(); c.close(); } public User get(String id) throws ClassNotFoundException, SQLException { Class.forName("com.mysql.cj.jdbc.Driver"); Connection c = DriverManager.getConnection("jdbc:mysql://localhost/springbook?characterEncoding=UTF-8", "spring", "book"); PreparedStatement ps = c .prepareStatement("select * from users where id = ?"); ps.setString(1, id); ResultSet rs = ps.executeQuery(); rs.next(); User user = new User(); user.setId(rs.getString("id")); user.setName(rs.getString("name")); user.setPassword(rs.getString("password")); rs.close(); ps.close(); c.close(); return user; } }
UserDao - code@tobyilee/tobyspringin5
 
위 코드가 끔찍한 이유
  • add 메서드의 관심사를 살펴보면 크게 세 가지나 된다.
      1. DB conncetion 얻기
      1. sql 을 생성/실행하기
      1. 자원을 release 하고 connection 을 close 하기
  • 예외 처리가 없다.
    • 무책임하게 예외를 던져버린다. 그것도 기술의존적인 checked exception 을…
 
초난감 DAO 와 그를 사용하는 Client 의 클래스 다이어그램을 그리면 아래와 같다.
notion image

위 코드를 여러가지 객체지향의 무기를 사용해 개선해보자!
위의 여러 문제점 중 첫째 DB connection 을 얻는 방식을 분리해보자

1. private method 로 분리

notion image
  • 좋은 변경이지만 만족 스럽지 않다.
  1. UserDao 가 아닌 ProductDao 가 등장한다면 같은 Connection 을 사용하더라도 private getConnection 메서드가 중복되게 등장해야 한다.
  1. 결국 UserDao 의 커넥션을 결정할 책임은 아직 UserDao 가 가진다.
      • 이래서는 Naver 와 Daum 에 우리의 UserDao 를 팔아먹을 수 없다!
 

2. 상속을 통한 확장

notion image
  • 여전히 만족스럽지 않다.
  1. 역시 ProductDao 가 등장한다면?
      • 각 Dao 마다 재정의를 위한 getConnection 메서드가 abstract 로 제공 되어야 하고 모든 자식 Dao 에서는 이를 재정의 해야한다.
      • 엄청난 코드 중복이 발생한다.
 
  1. 상속을 사용했기 때문에 자식클래스와 부모클래스가 너무 관계가 깊다.
      • 그에 반에 두 클래스의 책임이 너무 다르다.
      • 자식 클래스는 커넥션의 생성만을, 부모 클래스는 이를 사용한 DB 처리를 책임진다.
 

3. 클래스의 분리

notion image
  • 여전히 만족 스럽지 않다.
  1. 클래스만 분리 되었지 결국 UserDao 의 커넥션을 결정할 책임은 아직 UserDao 가 가진다.
      • 이래서는 Naver 와 Daum 에 우리의 UserDao 를 팔아먹을 수 없다!
 

4. 인터페이스의 도입으로 의존도를 낮추기

notion image
  • 훨씬 유연하다.
  • 아주 훌륭하다.
 
여기서 얼렁 뚱땅 넘어가버린 것이 있다.
 
4 이전의 UserTest 는 원래 UserDao 를 사용해서 기능을 검증하는 역할만을 가졌었다.
인터페이스를 도입하며 구체적인 Connection, ConnectionMaker 를 설정하는 책임이 UserDao 의 바깥으로 분리되면서 자연스럽게 UserTest 가 이 책임까지 떠앉아 버렸다.
 
이를 개선해보자