goal
Refactoring을 이용해 Code smell을 제거한다.
판매할 DB프로그램 만들기 [Refactoring - 1편]
** 학습 목표 **
- Database API를 판매할 목적으로 프로그래밍을 진행한다.
- 독립된 파일로 구성하는 것을 목표로 진행한다.
1 ] 구성된 소스파일
파일명 | 설명 |
User.java | DAO, 즉 Database에 접근할 객체를 만들 파일 |
UserDao.java | Database를 조작할 파일 (Database 검색 / Database 추가 즉, SQL의 insert작업/select작업) |
ConnectionMarker.java | JAVA JDBC를 이용해 DB를 연결할 파일 - 회사마다 사용할 DB가 다를 것이기 떄문에 공통된 작업으로 interface로 정의 |
DConnectionMaker.java | 프로그램이(Database API) 판매될 D회사 |
2 ] 소스파일 세부내용
- tobys.User.java
package tobys;
public class User {
String id;
String name;
String password;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
- tobys.UserDao.java
package tobys;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class UserDao {
private ConnectionMarker connectionMaker;
public UserDao(){
connectionMaker = new DConnectionMaker();
}
public void add(User user) throws ClassNotFoundException, SQLException {
Connection c = connectionMaker.makeConnection();
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());
ps.executeUpdate();
ps.close();
c.close();
}
public User get(String id) throws ClassNotFoundException, SQLException {
Connection c = connectionMaker.makeConnection();
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;
}
}
- tobys.ConnectionMarker.java
package tobys;
import java.sql.Connection;
import java.sql.SQLException;
public interface ConnectionMarker {
public Connection makeConnection() throws ClassNotFoundException, SQLException;
}
- tobys.DConnectionMaker.java
package tobys;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class DConnectionMaker implements ConnectionMarker{
public Connection makeConnection() throws ClassNotFoundException, SQLException {
// D사의 독자적인 방법으로 Connection을 생성하는 코드
Class.forName("com.mysql.jdbc.Driver");
Connection c = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/tobys_spring","kimeuncheol","1234");
return c;
}
}
소스코드 설명
파일 | 설명 |
User.java | DAO를 만들어줄 객체 - 즉, 해당 파일에 있는 class를 가지고 객체를 생성한 후, Database접근을 할 객체를 생성하는 부분 - UserDao의 add()와 get()부분에서 모두 사용한다. |
UserDao.java | 매개변수로 전달 받은 User클래스의 객체를 add()와 get()에서 사용한다. - User의 객체를 매개변수로 전달 받은 후, 기능과 성격에 맞게 메소드 구현 및 User클래스 메소드 사용 |
ConnectionMarker.java | DB연결 부분 - 해당 파일은 interface로 빠져있다. - 왜냐하면 D회사뿐만 아니라, 다른 회사에도 판매가 될 수 있는데, 공통적인 작업이 DB를 연결해는 부분이기 때문에 - 해당 파일에서는 makeConnection()메소드를 생성하고 반환을 Connection으로 해줌으로써 독립성을 지킨다. - 회사가 DB를 연결하기 위해서는 ConnectionMarker 인터페이스를 상속 받음으로써 makeConnection()메소드를 구현해줘야한다. - 구현은 회사의 입맛에 맞게 해주면 된다. |
DConnectionMaker.java | 해당 프로그램을 산 D회사 - 파일 내부에서 ConnectionMaker파일의 인터페이스를 상속받아 D회사의 업무 환경에 맞게 커스텀을 진행한다. |
소스코드의 문제
초기에 한 번 어떤 클래스의 오브젝트를 사용할지를 결정하는 UserDao.java
파일의 `UserDao클래스` 생성자 부분에서 new DConnectionMarke()
부분이 남았다.
- 즉, 현재의 코드에서는 판매할 회사가 2개 이상이 되었을 때 문제가 발생하게 된다.
- D회사의 커스텀된 Database로만 접근... 말이 되냐.. 내 회사는 B회사인데
이러한 문제 때문에 위의 다이어그램에서는 보이지 않지만 사실은 아래와 같은 관계가 형성되어있다.

해결이 필요한 문제
- UsersDao클래스 이름을 넣어서 객체를 생성하는 방법을 수정한다. (2편계속)
소감: 짜증난다
'Portfolio > 자질구레한 실습해보기' 카테고리의 다른 글
window :) 환경변수 설명 및 실습진행 (Java JDK path 설정) (0) | 2022.05.02 |
---|