태민의 스프링 - 1.2 DAO의 분리(1)

한태민·2021년 10월 21일
1

스프링 씨-리즈

목록 보기
2/2

1.1에서 썼던 코드들은 다시 뒤돌아보면 굉장이 난감한 코드들이였다.

그래서 오늘은 DAO의 관심사 분리에 대해 알아보았다.

객체지향의 세계에서는 모든 것이 변한다. 여기서 변한다는 것은 오브젝트에 대한 설계와 이를 구현한 코드가 변한다는 뜻이다.

소프트웨어 개발에서 끝이란 개념은 없다.

사용자의 비즈니스 프로세스와 그에 따른 요구사항은 끊임없이 바뀌고 발전한다. 시간이 지남에 따라 기술도 바뀌고, 환경도 변화한다. 그래서 우리 개발자들은 객체를 설계할 떄 가장 염두에 둬야 할 사항은 변화를 대비하는 것이다.

요구사항으로 기능 변경 요청이 들어 왔을때 누구는 몇 줄의 코드만 변경해도 되는것에 반해, 나 같은 사람은 몇시간이 걸린다.

그리고 걱정한다.

 


그래서 나 같은 사람이 준비해야 할 일은 한가지 관심이 한군데에 집중되게 하는 것이다.

분리해야 하는 것은 분리하고 모아야하는 것은 모으고!

프로그래밍의 기초 개념 중 관심사의 분리(Separation of Concerns)라는게 있다. 꼭 확인하자

중복 코드의 메소드 추출

이제 관심사 분리를 해보자!

현재 기능 중 가장 겹치는 것은 무엇일까?

import java.sql.*;

public class UserDao {
    public void add(User user) throws ClassNotFoundException, SQLException{
        Class.forName("org.mariadb.jdbc.Driver");
        Connection c = DriverManager.getConnection("jdbc:mariadb://localhost:3306/springbook","root","qwer");

        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("org.mariadb.jdbc.Driver");
        Connection c = DriverManager.getConnection("jdbc:mariadb://localhost/springbook","root","qwer");

        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;

    }
}

1. 중복 코드 찾기

        Class.forName("org.mariadb.jdbc.Driver");
        Connection c = DriverManager.getConnection("jdbc:mariadb://localhost:3306/springbook","root","qwer");

add()에서도 get()에서도 겹치는 Connection과 관련된 코드이다.

이 부분을 제거하고 독립적인 메소드로 만들어보자.

2. 중복 코드의 메소드 추출

    private Connection getConnection() throws ClassNotFoundException, SQLException{
        Class.forName("org.mariadb.jdbc.Driver");
        Connection c = DriverManager.getConnection("jdbc:mariadb://localhost/springbook","root","qwer");

        return c;
    }

이렇게 따로 빼내어 준다면 분리가 끝났다. 그리고 기존 코드도 수정해야한다.

전체 코드는 다음과 같다.

3. 수정 후 전체 코드

import java.sql.*;

public class UserDao {
    public void add(User user) throws ClassNotFoundException, SQLException{

        Connection c = getConnection();

        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{

        Connection c = getConnection();

        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;

    }

    private Connection getConnection() throws ClassNotFoundException, SQLException{
        Class.forName("org.mariadb.jdbc.Driver");
        Connection c = DriverManager.getConnection("jdbc:mariadb://localhost/springbook","root","qwer");

        return c;
    }
}

이로써 나중에 DB비밀번호를 바꾸더라도 메소드 하나만 변경하면 끝이다.

이렇게 기능에는 영향을 주지 않으면서 코드의 구조만 변경하는 이런 작업을 리팩터링(refactoring)이라고 한다.

또한 위에서 사용한 getConnection()이라고 하는 공통의 기능을 담당하는 메소드로 중복된 코드를 뽑아내는것을 리팩터링에서는 메소드 추출 기법(extract method)이라고 한다.

후기

예제만 따라하면 그냥 되는줄 알았다. 근데 다시 보니 너무 멍청했다. 큰 깨달음을 얻은 것 같다.

profile
BackEnd Devloper

0개의 댓글