[스프링] 관심사의 분리 ( 메소드 분리 )
스프링 프레임워크를 사용하기 위한
기본 개념을 하나씩 정리해볼까 한다.
▷ 분리와 확장
분리와 확장을 고려한 설계는 미래를 대비한다.
프로그램을 만들 때는 '분리'와 '확장'을 고려해야한다. 변화는 대체로 한 가지 관심에서 발생하지만 작업은 한 곳에 발생하지 않는다. 그러므로 분리와 확장이 고려되지 않은 코드는 '유지보수'가 어렵다.
그럼 이제부터 '분리' 와 '확장'을 고려하여 '변화에 대응하는 코드'를 작성해보자.
▷ 관심사의 분리 ( Separation of Concern )
관심사의 분리란, 관심이 같은 거는 모으고 다른 거는 분리시키는 개념이다. 그럼 이를 DAO 객체를 통해 알아보자.
DAO(Data Access Object) : DB에 접근하여 SQL문 실행을 전담하는 객체
UserDao 클래스에는 두 가지 메소드를 만들었다.
1. add 메소드 : INSERT 명령어로 레코드를 삽입하는 메소드
2. get 메소드 : SELECT 명령어로 레코드를 추출하는 메소드
1. add 메소드 코드
public int add(User user) {
try {
// 1. DB 접근
Class.forName("com.mysql.cj.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/SpringProject";
String id = "root";
String pw = "111111";
Connection c = DriverManager.getConnection(url, id, pw);
////////////////////////////////////////////////////////////////////
// 2. SQL문 실행
String sql = "INSERT INTO USER(UserId,Name,Password) VALUES(?,?,?)";
PreparedStatement ps = c.prepareStatement(sql);
ps.setString(1, user.getId());
ps.setString(2, user.getName());
ps.setString(3, user.getPassword());
int result = ps.executeUpdate();
ps.close();
c.close();
return result;
} catch (ClassNotFoundException e) {
System.out.println("클래스 발견 못함");
} catch (SQLException e) {
System.out.println("DB 접속 실패");
}
return -1;
}
add 메소드를 두 가지로 구분할 수 있다.
1. DB 접근 ( 커넥션 객체 생성 )
2. SQL문 실행 ( INSERT문 )
2. get 메소드 코드
public User get(String UserId) {
try {
// 1. DB 접근
Class.forName("com.mysql.cj.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/SpringProject";
String id = "root";
String pw = "111111";
Connection c = DriverManager.getConnection(url, id, pw);
/////////////////////////////////////////////////////////
// 2. SQL문 실행
String sql = "SELECT * FROM USER WHERE UserId = ?";
PreparedStatement ps = c.prepareStatement(sql);
ps.setString(1,UserId);
ResultSet rs = ps.executeQuery();
User user = new User();
while(rs.next()) {
user.setId(rs.getString("UserId"));
user.setName(rs.getString("Name"));
user.setPassword(rs.getString("Password"));
}
rs.close();
ps.close();
c.close();
return user;
} catch (ClassNotFoundException e) {
System.out.println("클래스 발견 못함");
} catch (SQLException e) {
System.out.println("DB 접속 실패");
}
return null;
}
get 메소드를 두 가지로 구분할 수 있다.
1. DB 접근 ( 커넥션 객체 생성 )
2. SQL문 실행 ( SELECT 문 )
add 메소드와 get 메소드는 DB 접근이라는 관심사가 같고 SQL문 실행에서는 서로 관심사가 다른다. add 메소드는 삽입이고 get 메소드는 추출이다. 그러므로 관심사가 같은 DB접근 코드는 하나로 묶어 분리 시킬 수 있다.
3. 관심사 코드 분리
public class UserDao {
// DB 접근 전용 메소드 생성
public Connection getConnection() {
try {
Class.forName("com.mysql.cj.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/SpringProject";
String id = "root";
String pw = "111111";
Connection c = DriverManager.getConnection(url, id, pw);
return c;
} catch (ClassNotFoundException e) {
System.out.println("클래스 발견 못함");
} catch (SQLException e) {
System.out.println("DB 접속 실패");
}
return null;
}
public int add(User user) throws SQLException {
Connection c = getConnection(); // connection 메소드 호출
String sql = "INSERT INTO USER(UserId,Name,Password) VALUES(?,?,?)";
PreparedStatement ps = c.prepareStatement(sql);
ps.setString(1, user.getId());
ps.setString(2, user.getName());
ps.setString(3, user.getPassword());
int result = ps.executeUpdate();
ps.close();
c.close();
return result;
}
public User get(String UserId) throws SQLException {
Connection c = getConnection(); // Connection 메소드 호출
String sql = "SELECT * FROM USER WHERE UserId = ?";
PreparedStatement ps = c.prepareStatement(sql);
ps.setString(1,UserId);
ResultSet rs = ps.executeQuery();
User user = new User();
while(rs.next()) {
user.setId(rs.getString("UserId"));
user.setName(rs.getString("Name"));
user.setPassword(rs.getString("Password"));
}
rs.close();
ps.close();
c.close();
return user;
}
}
이와 같이, 관심사를 따로 분리하면, add메소드나 get 메소드 외에 커넥션 객체를 필요로하는 메소드가 추가되어도 코드를 중복하여 작성할 필요가 없다.