Portfolio/자질구레한 실습해보기

자질구레한 실습 :) Refactoring관련, 판매할 Database API 만들기 [1편]

euncheol kim 2022. 5. 1. 21:49

 

goal

Refactoring을 이용해 Code smell을 제거한다.

 

판매할 DB프로그램 만들기 [Refactoring - 1편]


** 학습 목표 **

  • Database API를 판매할 목적으로 프로그래밍을 진행한다.
    • 독립된 파일로 구성하는 것을 목표로 진행한다.

1 ] 구성된 소스파일

image

파일명 설명
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편계속)




소감: 짜증난다