토비의 스프링 (4)
- SPRING
- 2019. 1. 2. 22:21
추상화란 어떤 것들의 공통적인
성격을 뽑아내어 이를 따로 분리해내는 작업이다.
자바가 추상화를 위해 제공하는 가장
유용한 도구는 인터페이스이다.
인터페이스는 자신을 구현한 클래스에 대한
구체적인 정보는 모두 감춰버린다.
인터페이스는 어떤 일을 하겠다는 기능만 정의해놓은 것이다.
이말은 인터페이스는 "어떤 기능을 하겠다." 하는 구현체가 없다
구현은 인터페이스를 구현할 클래스들 안에서 해야한다.
아래처럼 인터페이스를 정의하자.
DB커넥션을 가져오는 메소드 이름을 makeConnection()
이라고 정했다.
위 인터페이스를 사용하는
UserDao 는 ConnectionMaker 인터페이스 타입의
오브젝트라면 어떤 클래스로 만들어졌든지
makeConnection() 메소드를 호출하면 Connection타입의
오브젝트를 만들어서 돌려줄 것이다.
위 인터페이스를 사용할 때에는
아래와 같이 ConnectionMaker를 implements(구현)하고
Connection makeConnection()을 자기만의 방법으로
만들어 주면 된다. 예를 들어 위에서 makeConnection()은
DB커넥션을 가져오는 메소드라 정했으니
아래의 makeConnection()은 자기가 사용할
DB에 맞게 커넥션을 가져올 수 있도록 하면된다.
아래는 특정 클래스 대신 인터페이스를 사용해서 DB커넥션을
가져와 사용하도록 수정한 UserDao이다.
UserDao의 add, get 메소드와 필드에는 ConnectionMaker 라는
인터페이스와 인터페이스의 메소드인 makeConnection만 사용하도록 되있다.
그러니 이제는 위 클래스를 옆에 있는 친구에게 주고 사용하라고 하고
이 친구가 DB접속용 클래스를 다시 만든다고 해도
UserDao의 코드를 뜯어 고칠 일은 없다.
하지만 위에서 connectionMaker = new AConnectionMaker()를 보면
AConnection 클래스의 생성자를 호출해서 오브젝트를 생성하는
부분이 아직 남아있다.
UserDao의 다른 모든 곳에서는 인터페이스를 이용하게
만들어서 DB커넥션을 제공하는 클래스에 대한 구체적 정보가 모두 제거됬지만
초기에 한 번 어떤 클래스의 오브젝트를 사용할지를 결정하는
생성자의 코드는 제거되지 않고 남아 있다.
결국 아직도 UserDao의 변경없이는 DB커넥션 기능의 확장이 자유롭지 못하다.
완벽하게 분리를 하여 독립적으로 사용하려면
UserDao의 클라이언트에서 UserDao를 사용하기 전에
먼저 UserDao가 어떤 ConnectionMaker의 구현 클래스를 사용할지를
결정하도록 만들어야한다.
즉, UserDao 오브젝트와 특정 클래스로부터 만들어진
ConnectionMaker 오브젝트 사이에 관계를 설정해주는 것이다.
클래스 사이에 관계가 만들어진다는 것은 한 클래스가 인터페이스 없이 다른
클래스를 직접 사용한다는 것이다.
따라서 클래스가 아니라 오브젝트와 오브젝트 사이의 관계를 설정해줘야 한다.
오브젝트 사이의 관계는 런타임 시에 한쪽이 다른 오브젝트의 레퍼런스를 갖고 있는
방식으로 만들어진다. 따라서 위에서 말한
connectionMaker = new AConnectionMaker() 는
AConnectionMaker의 오브젝트의 레퍼런스를 UserDao의
connectionMaker 변수에 넣어서 사용하게 함으로써
이 두 개의 오브젝트가 사용 이라는 관계를 맺게 해주는 것이다.
이제 위소스를 완벽히 독립시켜보자.
현재는 UserDao 클래스의 main()메소드가 UserDao클라이언트라고 볼 수 있다.
좀 더 깔끔하게 구분하기 위해 UserDaoTest라는 이름의
클래스를 하나 만들고 UserDao에 있던 main()메소드를 UserDaoTest로 옮겨보자.
그리고 UserDao의 생성자를 수정해서 클라이언트가 미리
만들어 둔 ConnectionMaker의 오브젝트를 전달 받을 수 있도록 파라미터를 하나 추가한다.
UserDao의 생성자는 이제 아래와 같이 바뀌었다.
클라이언트와 같은 제3의 오브젝트가 UserDao 오브젝트가
사용할 ConnectionMaker 오브젝트를 전달해주도록 만든 것이다.
이렇게 하고 나니 UserDao에는 ConnectionMaker의 구체적인
구현 클래스 이름인 AConnectionMaker가 사라졌다.
AConnectionMaker를 생성하는 코드는 UserDao와 특정 ConnectionMaker 구현
클래스의 오브젝트 간 관계를 맺는 책임을 담당하는 코드였는데
그것을 UserDao의 클라이언트에게 넘겨벼렸기 때문이다.
이제 UserDaoTest는 아래와 같이 바뀐다.
UserDaoTest 는 UserDao와 COnnectionMaker 구현 클래스와의
런타임 오브젝트 의존 관계를 설정하는 책임을 담당해야 한다.
그래서 특정 ConnectionMaker 구현 클래스의
오브젝트를 만들고, UserDao생성자 파라미터에 넣어 두 개의 오브젝트를 연결해준다.
그리고 원래 자기 책임이던 UserDao에 대한 테스트 작업을 수행한다.
클라이언트인 UserDaoTest가 이렇게 해줌으로써 UserDao의 변경없이도
자유롭게 DB커넥션의 기능을 확장할 수 있다.
이제 BConnectionMaker라는 이름으로 새로운
커넥션을 사용하고 싶다면
ConnectionMaker connectionMaker = new BConnectionMaker(); 를
사용하면 된다.
'SPRING' 카테고리의 다른 글
토비의 스프링 (6) (0) | 2019.01.08 |
---|---|
토비의 스프링 (5) (0) | 2019.01.02 |
토비의 스프링 (3) (0) | 2018.12.24 |
토비의 스프링 (2) (0) | 2018.12.19 |
토비의 스프링 (1) (0) | 2018.12.18 |