public void add(User user) throws ClassNotFoundException, SQLException {
//DB 드라이버 로드 및 DB 연결
Class.forName("com.mysql.cj.jdbc.Driver");
Connection c = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/스키마 이름", "user ID", "user password");
...
위의 코드처럼 DB 드라이버를 로딩하고 연결하는 동작을 하는 메서드가 수백, 수천개라고 생각해보자. 만약 유저를 변경하거나 패스워드를 재설정할 때마다 수백, 수천개의 메서드를 수정해야만 한다.
그럼 이러한 공통된 코드들을 한 군데 묶어놓는 게 낫지 않을까?
위의 코드가 여러번 중복해서 존재한다면 그것들을 묶어 메서드 하나로 표현할 수 있다. 즉 새로운 메서드 하나를 만들어줌으로써 수백, 수천번의 중복된 코드를 한번에 수정할 수 있다.
public void add(User user) throws ClassNotFoundException, SQLException {
//DB 드라이버 로드 및 DB 연결
Class.forName("com.mysql.cj.jdbc.Driver");
Connection c = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/스키마 이름", "user ID", "user password");
...
public User get(String id) throws ClassNotFoundException, SQLException {
//DB 드라이버 로드 및 DB 연결
Class.forName("com.mysql.cj.jdbc.Driver");
Connection c = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/스키마 이름", "user ID", "user password");
...
여기서 커넥션 부분만 추출하여 따로 메서드를 하나 더 만들어준다는 말이다.
private Connection getConnection() throws ClassNotFoundException, SQLException {
Class.forName("com.mysql.cj.jdbc.Driver");
Connection c = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/스키마 이름", "user ID", "user password");
return c;
}
그럼 수백, 수천개의 메서드들의 커넥션은 위의 getConnection()메서드로 호출되고 수정된다.
public User get(String id) throws ClassNotFoundException, SQLException {
//DB 드라이버 로드 및 DB 연결
Connection c = getConnection();
...
그러면 우리는 드라이버의 URL이 바뀌든, DB 종류가 바뀌는 등 여러 변경 상황에 메서드 하나로 수백, 수천개의 메서드 수정에 대처할 수 있는 것이다. 이 작업은 기능에는 영향을 주지 않으면서 코드의 구조만 변경한다. 이런 작업을 리팩토링이라고 한다.
리팩토링은 기존의 코드를 외부의 동작방식에는 변화 없이 내부 구조를 변경해서 재구성하는 작업 또는 기술을 말한다.리팩토링을 하면 코드 내부의 설계가 개선되어 코드를 이해하기가 더 편해지고, 변화에 효율적으로 대응할 수 있다. 결국 생산성은 올라가고, 코드의 품질은 높아지며, 유지보수하기 용이해지고, 견고하면서도 유연한 제품을 개발할 수 있다.
UserDao를 구매하겠다는 N사와 D사가 있다고 치자. 이 두 회사가 각기 다른 DB를 사용하고 있고 구매 후에도 DB 커넥션을 변경할 가능성이 있다면 판매 전에 그에 맞는 DB 커넥션 설정을 해서 팔면 되겠지만, 구매 이후에도 DB 커넥션을 변경할 가능성이 있으므로 구매 이후에 getConnection() 메서드의 수정이 필요하다. 어떻게 해야될까?
UserDao 소스를 두 회사에 제공하고 변경이 필요하면
getConnection()메서드를 수정해서 사용하라고 할 수 있다.
하지만, UserDao에 비밀 기술이 적용되어 소스코드를 공개할 수 없다면?
상속을 통한 확장을 하는 것이다. UserDao에서
getConnection()메서드를 추상 메서드 처리하여 추상 클래스인 UserDao를 N사와 D사에 판매한다. 이 회사들은 UserDao 클래스를 상속해서 각각 NUserDao와 DUserDao라는 서브 클래스를 만들어 원하는 방식대로getConnection()메서드를 구현한다.
//UserDao 추상 클래스
public abstract class UserDao {
...
//getConnection() 추상 메서드
public abstract Connection getConnection() throws ClassNotFoundException, SQLException;
public class NUserDao extends UserDao {
public Connection getConnection() throws ClassNotFoundException, SQLException { //상속을 통해 확장된 getConnection() 메서드
//N사 DB 커넥션 생성코드
}
}
public class DUserDao extends UserDao {
public Connection getConnection() throws ClassNotFoundException, SQLException {
//D사 DB 커넥션 생성코드
}
}
}