새로운 내용을 공부할 때
새로운 내용의 공부를 시작할 때 용어의 정의를 이해하지 못하거나 정확하게 알지 못한다면 그 용어가 포함된 문장을 이해하지 못합니다.
작은 단어 하나가 내용을 이해하지 못하게 하기 때문에 용어를 정확하게 이해하는 것이 중요합니다.

3 분 소요

커넥션 만들기 추출

사용자 정보 저장


public void add(final User user) throws ClassNotFoundException, SQLException {
  System.out.println("User added: " + user.getId());
  Class.forName("com.mysql.cj.jdbc.Driver");

  final Connection con = DriverManager.getConnection("jdbc:mysql://localhost/spring", "root", "1234");
  final PreparedStatement ps = con.prepareStatement("insert into users(id, name, password) values (?,?,?);");
  ps.setString(1, user.getId());
  ps.setString(2, user.getName());
  ps.setString(3, user.getPassword());

  ps.executeUpdate();

  ps.close();
  con.close();
}

해당 코드를 보면 사용할 데이터베이스, 어떤 드라이버를 사용할 것인지, 어떤 로그인 정보를 사용할 것인지, 커넥션을 생성해서 관리하는 방법등 다양하게 관심사가 추가되었습니다.

관심사를 분리하는 방법에서 먼저 하는 일은 중복된 코드를 제거하는 방법입니다.

중복된 코드 추출

토비님 강의를 봐도 먼저 하는 것은 스코프를 나누는 방법입니다.

같은 기능을 최소하여 묶은 다음 하나의 메서드로 추출하여 관심사를 메서드로 나누는 방법입니다.

관심사를 묶어서 처리를 할 때, 어디까지 추상화를 할지 선택하는 것이 중요하다고 생각됩니다.

현재 데이터베이스에 연결을 하려면

  • 데이터베이스 선택
  • 어떤 드라이버를 사용할 것인지
  • 로그인 정보는 어떤 것을 사용할 것인지
  • 커넥션을 생성하는 방법을 커넥션 풀을 사용할 것인지
  • 커넥션 풀을 사용한다면 어떤 커넥션 풀 기술을 사용할 것인지

이런 관심사도 나눌 수 있습니다.

너무 관심사를 세분화해서 나누기보다 현재는 데이터베이스 연결후 통신할 수 있는 기능을 하나의 클래스 책임이라 생각하도 묶어서 관리합니다.

public void add(final User user) throws ClassNotFoundException, SQLException {
  System.out.println("User added: " + user.getId());
  Connection con = getGetConnection();
  final PreparedStatement ps = con.prepareStatement("insert into users(id, name, password) values (?,?,?);");
  ps.setString(1, user.getId());
  ps.setString(2, user.getName());
  ps.setString(3, user.getPassword());

  ps.executeUpdate();

  ps.close();
  con.close();
}

private Connection getGetConnection() throws ClassNotFoundException, SQLException {
  Class.forName("com.mysql.cj.jdbc.Driver");
  return DriverManager.getConnection("jdbc:mysql://localhost/spring", "root", "1234");
}

중복된 코드를 추출하여 공용 로직으로 사용하면 다음과 같은 장점이 생깁니다.

코드 변경시 해당 메서드를 사용하는 모든 클래스를 수정해야하는 것을 하나의 변경지점에 처리할 수 있습니다.

관심이 다른 코드가 있는 메소드에서는 영향을 주지 않게 됩니다.

관심의 내용이 독립적으로 동작하니 수정도 가능하다

수정한 코드 검증 테스트

이미 커넥션을 가져오는 코드를 테스트 했습니다.

코드를 수정(리팩토링)을 했다면 수정한 후에는 기능에 문제가 없다는 게 보장되지 않기 때문에 테스트가 필요합니다.

수정된 코드는 리팩토링 전 코드와 후 코드의 기능은 동일하기 때문에

검증을 통해서 수정전 코드와 결과가 동일하면 됩니다.

메세드 분리의 의미

메소드를 분리하는 것은 기능이 변경되지 않고 구조를 변경하게 되었습니다.

특정 관심사를 메서드로 분리하니

  1. 재사용 가능하다
  2. 특정 관심사를 수정하는 요구사항이 들어오면 이 부분만 수정하고 테스트를 하면된다

이것을 메소드 추출이라고 합니다

메소드 추출의 의미

메소드 추출은 기존 로직의 기능을 변경하지 않고 특정 관심사를 메소드로 분리하는 것을 말합니다.

관심사를 분리하게 되면 특정 관심사를 수정하는 요구사항이 생겨 수정이 발생해도 메소드 내에 있는 코드만 테스트를 하면 됩니다.

변경 사항이 생기는 부분만 테스트를 하기 때문입니다.

기능은 동일하지만 미래 변화에 조금 유연한 코드로 변경할 수 있도록 만들어주는 리팩토링 방법입니다.

독립

메서드 추출은 관심사를 같은 클래스 내의 메서드로 분리하는 방법을 말합니다.

데이터베이스 커넥션을 가져오는 기술을 사용하는 환경에 따라 다르게 하고 싶은 경우가 있습니다.

그렇다면 메서드 추출은 코드를 매번 수정해서 배포해야합니다.

이유는 관심사에 대한 코드가 구체화되어있기 때문에 변경하기가 어렵습니다.

이럴때 사용하는 방법이 상속을 사용할 수 있습니다.

상속

커넥션을 가져오는 방법을 추상 메소드로 만들어서 해당 클래스를 사용할 때 직접 사용하도록 만드는 방법입니다.

커넥션을 획득하는 것 뿐만 아니라 데이터를 추가하고 조회하는 방법도 커넥션마다 다른 쿼리를 작성해야하기 때문에 코드내에 구체화되어있으면 안됩니다.

이런 경우에 추상 클래스를 만들어서 사용하면 됩니다.

상속의 한계

상속을 통해서 확장하면 코드 구현은 간단하게 하여 확장이 가능합니다.

다만 기능을 확장하기 위해서

  1. 기능을 구현하기 위해서는 새 클래스를 생성해야 합니다.
  2. 다중 상속이 어려워서 다른 기능을 오버라이딩을 하려고 한다면 이미 부모가 있어서 어렵습니다.
  3. 상하위 클래스가 밀접하여 강결합으로 인해 슈퍼 클래스의 내부 변경이 있다면 하위 클래스에 모두 영향을 미치게 되므로 관심사의 분리로 인해 얻는 이점이 사라질 수 있습니다. 그래서 슈퍼클래스는 더 이상 영향력이 퍼지는 것을 막기 위해 final 키워드를 통해 상속하지 못하도록 합니다.
  4. 확장 기능인 커넥션을 가져오는 부분은 다른 테이블 정보를 조회하는 클래스에도 적용하려면 해당 dao에도 중복된 클
  5. 래스를 생성해야합니다s

변화의 성격

모든 오브젝트는 변한다고 합니다.

오브젝트가 모두 동일한 요구사항으로 변경되는 건 아닙니다,

이유, 시기, 주기 등 다양한 환경 요소로 관심사가 변경될때 서로 영향을 주지 않도록 독립적으로 살아는것이 중요하다

기존 로직은 동일하지만 특정 관심사는 변경 시기나 이유, 주기등이 다른 것을 분리하여 서로 영향을 주지 않은 채로 필요한 시점에 각각 수정하고 테스트할 수 있기 때문입니다

태그:

카테고리:

업데이트:

댓글남기기