1.3 DAO의 확장

조창훈·2023년 9월 25일

1. 클래스의 분리

  • 처음에는 메서드로 기능을 분리했음
  • 그 뒤에는 상하위클래스로 기능을 분리했음
  • 이번에는 기능을 아예 연관없는 클래스로 분리할 생각임

분리 방법

  • simpleConnectionMaker라는 클래스를 만들어서 연결관련 설정
    • simpleConnectionMaker에 메서드 makeNewConnection을 구현
  • 그 뒤, UserDAO에서 simpleConnectionMaker의 인스턴스를 생성하고,
    makeNewConnection 메서드를 통해 새로운 연결을 생성함

생기는 문제

  • 이전에 구현한 NUserDAO나 DUserDAO같이 UserDAO 코드 수정없이 상속받은 클래스에서 필요한 기능만 구현해서 사용하는 게 불가능해짐
  • 상속이라는 문제에서는 벗어났지만, 다시 UserDAO의 코드수정이 불가피

1차 해결방법

  • 인터페이스의 도입
    • ConnectionMaker라는 인터페이스를 생성
    • makeConnection이라는 메서드 선언
    • 인터페이스를 구현한 NConnectionMaker,DConnectionMaker생성
  • 인터페이스에 선언된 기능을 사용하는 것으로, UserDAO의 코드를 크게 변경하지 않고, 생성자에서 변수에 인스턴스를 할당하는 것으로 사용가능

문제점 - 여전히 커넥션의 구체적인 이름이 포함됨

private ConnectionMaker connectionMaker();
public UserDAO(){
//여기서 구체적인 NConnectionMaker와 같이 클래스의 이름이 나오게 된다.
connectionMaker = new NConnectionMaker();
}
  • 구체적인 클래스의 이름(NConnectionMaker)가 나오게 되면서, 코드수정은 여전히 필요하게 된다.
  • 물론 add,get과 같이 메서드에서는 구체적인 클래스 명이 나오지 않음
  • 생성자만 변경하면 되는 정도로 변경점이 적어짐

2차 해결방법

  • 파라미터(생성자의 매개변수)를 통한 오브젝트 주입
    • 위에서는 생성자의 파라미터에 아무것도 없음
    • 매개변수를 통해 생성자의 변수에 오브젝트를 전달하는 방법
public UserDAO(ConnectionMaker connectionMaker){
// 아래와 같이 이 클래스의 변수에, 매개변수의 오브젝트를 전달할 수 있다.
this.connectionMaker = connectionMaker;
}
  • 이렇게 되면 클래스에서 NConnectionMaker와 같이 구체적인 클래스의 이름이 사라진다.
  • 이제 UserDAO를 사용할 때(Main함수) 새로운 NConnectionMaker 인스턴스를 만든 뒤, 그 인스턴스를 UserDAO의 생성자로 넘겨주면 된다.


메인에서 생성자 파라미터를 통한 오브젝트 주입


위와 같이 이제 파라미터가 없으면 오류를 띄우는 것을 볼 수 있다.
파라미터에 값을 넣어서 해결한다.

리팩토링 결과


위와같이 잘 작동하는 것을 볼 수 있다.

1.3.4 원칙과 패턴

SOLID원칙과 디자인패턴

  • 이제까지 개선해온 코드를 SOLID 원칙과 디자인패턴을 통해 설명한다.

개방 폐쇄 원칙

  • 클래스나 모듈은 확장에는 열려있어야하고, 변경에는 닫혀있어야 한다.
    • DB연결 방법이라는 기능 확장에는 열려있음
      • NConnectionMaker와 같이 새로운 클래스를 만들어서 적용시킬 수 있음
    • 동시에 UserDAO의 코드는 건드릴 필요가 없음
    • 즉, DB연결방법이 변해도, UserDAO의 코드는 변경하지 않아도 되는 것이 개방 폐쇄원칙을 잘 지킨 결과라고 할 수 있음.

높은 응집도와 낮은 결합도

높은 응집도
  • 하나의 클래스에 하나의 관심사에만 집중되어있다는 뜻
  • 기능 하나에 집중되어있기 때문에, 이 관심사에 변화가 있다면 새로운 클래스를 생성해야함
    • 만약 기능이 여러개 들어가 있다면, 관심사에 변화가 있는 경우, 클래스의 어느 부분을 수정해야 하는지 찾아야 함
    • 응집도가 높으면, 찾을 필요없이 그냥 첨부터 새로 만들면 됨
낮은 결합도
  • 책임과 관심사가 다른 오브젝트 또는 모듈과는 낮은 결합도가 바람직함
  • 낮은 결합도란, 코드의 변경이 일어날 때, 관계를 맺고있는 다른 오브젝트한테 변화를 요구하는 정도

전략 패턴

  • 필요에 따라서 변경이 필요한 알고리즘을 인터페이스를 통해 외부로 분리
    • connectionMaker를 인터페이스로 분리해서 DB연결방법을 분리했다.
  • 인터페이스를 구현한 구체적인 클래스를 필요에 따라 바꿔서 사용
    • NConnectionMaker를 사용했다가, DConnectionMaker를 사용했다가 할 수있음
  • 클라이언트에서 컨텍스트가 사용할 전략을 생성자 등을 통해서 제공해주는게 일반적
    • 클라이언트 : UserDaoTest(main함수있는곳)
    • 컨텍스트 : UserDao(인터페이스의 메서드를 사용하는 곳)
    • 전략 : ConnectionMaker를 구현한 클래스
      (실제 DB와 연결하는 로직이 있는 곳)
profile
초전도-개발자의 길

0개의 댓글