[JDBC] 회원관리 Program STEP3, STEP4, STEP5

jy9922·2022년 7월 22일
0

Java

목록 보기
12/13
post-thumbnail

✔ 회원관리 Program STEP3

  • class를 분리해서 만들어 보아요!
/* UserDao.java */
package lecture0722.step3;

public class UserDAO {
	
	private SimpleConnectionMaker simpleConnectionMaker;
	
	public UserDAO(){
		simpleConnectionMaker = new SimpleConnectionMaker();
     // ...생략...
     public void insert(User user) throws ClassNotFoundException, SQLException {
		// try - catch를 사용하지 않아요! (다른 곳에서 에러 처리)
		Connection con = simpleConnectionMaker.makeConnection();
        ...
	}
/* SimpleConnectionMaker.java */
public class SimpleConnectionMaker {
	
	public Connection makeNewConnection() throws ClassNotFoundException, SQLException{
		Class.forName("com.mysql.cj.jdbc.Driver");
		String jdbc_url = "jdbc:mysql://localhost:3306/sqldb?charEncoding=UTF-8&serverTimezone=UTC&userSSL=false";
		Connection con = DriverManager.getConnection(jdbc_url,"root","test1234");
		return con;
	}
	
}
  • 위의 코드는 코드는 잘 분리하였지만, 소스코드를 공개하지 않은 이상 재사용이 힘들다..
  • UserDAO 안에 simpleConnectionMaker가 private으로 정의되어 있어, 클래스가 tightly coupled되는 현상이 발생한다. (더 안좋아짐)
    UserDAO는 simpleConnectioMaker가 없으면 작동하지 않는다..
    • 한 클래스 안에 다른 클래스 이름이 명확하게 박히면 좋지 않다. (Java 기본 API 제외)

어떻게 하면 해결이 될까요? → Interface

✔ 회원관리 Program STEP 4

interface를 구현해서 tightly coupled되는 현상을 줄여준다.

interface

public interface ConnectionMaker {
	
	public Connection makeConnection() throws ClassNotFoundException, SQLException;
	
}

interface를 구현하는 class

public class NUserDAO implements ConnectionMaker {

	@Override
	public Connection makeConnection() throws ClassNotFoundException, SQLException {
		Class.forName("com.mysql.cj.jdbc.Driver");
		String jdbc_url = "jdbc:mysql://localhost:3306/sqldb?charEncoding=UTF-8&serverTimezone=UTC&userSSL=false";
		Connection con = DriverManager.getConnection(jdbc_url,"root","test1234");
		return con;
	}
	
}
private ConnectionMaker connectionMaker;
	
	public UserDAO(){
		// UserDAO 안에 아직 만들지 않은 클래스를 넣어야 한다. (이 부분이 문제)
		// 오브젝트 간의 의존관계를 밀어버리는 것 - 코드 내에서 해결이 안된다.
		connectionMaker = new NUserDAO();
	}
	

위 코드는 한 클래스 (UserDAO)에 인터페이스 구현 클래스 (NUserDAO)가 들어가 있는 형태로, 두 클래스 간의 의존성이 강하다.

객체지향에서 클래스 간의 의존성을 떨어트리는 것이 좋다.

✔ 회원관리 Program STEP 5 - DI

private ConnectionMaker connectionMaker;
	
	// 객체를 주입받아요(DI)
	public UserDAO(ConnectionMaker connectionMaker){
		// 위 인터페이스를 구현한 객체를 파라미터로 받아서
		// 직접 DAO 안에서 객체를 만들지 않고, 받아와서 사용한다
		// 클래스 내에서 다른 클래스 이름이 나오지 않는다
		// Main으로 이동 -> 객체를 인자로 넣어주어야 한다
		this.connectionMaker = connectionMaker;
	}
	
	public void insert(User user) throws ClassNotFoundException, SQLException {
		// try - catch를 사용하지 않아요! (다른 곳에서 에러 처리)
		Connection con = connectionMaker.makeConnection();
        ...
public class NUserDAO implements ConnectionMaker {

	@Override
	public Connection makeConnection() throws ClassNotFoundException, SQLException {
		Class.forName("com.mysql.cj.jdbc.Driver");
		String jdbc_url = "jdbc:mysql://localhost:3306/sqldb?charEncoding=UTF-8&serverTimezone=UTC&userSSL=false";
		Connection con = DriverManager.getConnection(jdbc_url,"root","test1234");
		return con;
	}
	
}
public class Main {
	public static void main(String[] args) throws ClassNotFoundException, SQLException{
		// Service없이 main에서 직접 로직처리를 해보아요!
		
		// 인터페이스를 구현한 객체를 만들어 준다.
		ConnectionMaker connectionMaker = new NUserDAO();
		UserDAO dao = new UserDAO(connectionMaker);
        ...

DI(Dependency Injection) 🐾

  • 위 코드는 인터페이스 구현 객체를 생성자 함수에 주입시킴으로써 클래스 간 결합도를 낮춰준다.
  • 즉, 두 개의 클래스 간의 의존성은 없다.
    • 여기서 클래스 간의 의존성은 클래스에 새로운 클래스가 박혀있는 상태로 되어 있다.

  • UserDAO 객체와 NUerDAO 객체가 서로 사용될 때, 객체 의존성이 존재하게 된다.
  • 즉, runtime 의존성을 가지게 된다.
  • 클래스 간 의존성은 약해지고, 한 객체에 다른 객체를 인자로 받게 되면서 객체 의존성이 생기게 된다.

결론 - UserDAO는 다른 class에 종속되지 않아요!

0개의 댓글