<User / UserDao>
<관심사의 분리>
변화에 유연해야 하고 확장성이 있어야 하는데,
이를 위해서는 관심이 한 가지에 집중되어 있어야 함 (중복 X, 여러 기능이 하나의 메서드에 복합적으로 들어가 있으면 안됨)
이제부터 위의 초난감 DAO를 리팩토링 할 것임
*리팩토링이란?
외부의 동작방식에는 변화 x, 내부 구조를 변경해서 재구성하는 작업, 기술
<메서드 추출>
예를 들어 위의 UserDao에서 DB와 연결하는 부분은 하나의 메서드로 추출해 낼 수 있음 -> getConnection
메서드 추출을 통해 중복을 제거할 수 있음
<템플릿 메서드 패턴(팩토리 메서드 패턴)>
여러 DB와 연동해서 사용할 수 있도록 확장성을 늘리기 위해 getConnection()을 추상 메서드로 만들고 이를 상속해서 쓰게 할 수 있음
이렇게 슈퍼클래스의 메서드를 상속해서 구현하게 하는 방식이 템플릿 메서드 패턴(팩토리 메서드 패턴)
*팩토리 메서드와 템플릿 메서드
팩토리 메서드는 상위 클래스를 상속해서 쓰는 방식
템플릿 메서드는 공통된 역할을 수행하는 메서드인 템플릿 메서드(Template Method), 반드시 구현해야 하는 추상 메서드(Primitive Method), 그대로 사용해도 되고 오버라이딩해서 사용해도 되는 훅 메서드(Hook Method)로 나뉘어짐
여전히 다중 상속 불가능, 슈퍼클래스-서브클래스의 관심사의 긴밀한 결합 허용, DAO 생성 시 DB 커넥션 코드 중복의 문제가 있음
<클래스의 분리>
DB 커넥션을 담당하는 부분을 SimpleConnectionMaker 클래스로 분리
-> UserDao에서 DB커넥션 클래스를 알고 있어야 함, 메서드도 바꿀 수 없음
<인터페이스 도입>
ConnectionMaker 인터페이스를 만들어서 추상화된 makeConnection 메서드를 구현해놓음
하위클래스에서는 인터페이스로 DB 커넥션 가능
그러나 여전히 커넥션 생성자를 호출해서 객체를 생성해야 함
(UserDao 클래스에서 커넥션 오브젝트에 대한 구체적인 정보를 알고 있어야 함)
<관계설정 책임의 분리>
커넥션 생성자를 호출하는 부분을 또 하나의 관심사로 생각해서 밖으로 빼 버림
클래스 사이의 관계(클래스 안에 다른 클래스 이름이 나타나는 것)이 아닌 오브젝트 사이의 관계가 되도록(다이내믹한 관계)
제 3의 오브젝트를 사용해서 생성자 파라미터로 오브젝트 전달
(책의 경우에는 UserDaoTest()으로 빼버림)
<개방 폐쇄 원칙>
클래스나 모듈은 확장에는 열려 있어야 하고 변경에는 닫혀 있어야 한다
UserDao는 DB 커넥션 방식을 다양하게 확장할 수 있으며, DB 커넥션 방식이 변해도 코드를 바꿀 필요가 없다.
<높은 응집도와 낮은 결합도>
하나의 모듈(클래스)가 하나의 관심사에 집중되어 있음 -> 높은 응집도
서로 다른 모듈(클래스)와는 느슨하게 연결된 상태를 유지 -> 낮은 결합도
<전략 패턴>
자신의 기능 맥락에서, 필요에 따라 변경이 필요한 알고리즘을 인터페이스를 통해 통째로 외부로 분리시키고, 이를 구현한 구체적인 알고리즘 클래스를 필요에 따라 바꿔서 사용할 수 있게 하는 디자인 패턴
<오브젝트 팩토리>
팩토리: 객체의 생성 방식을 결정하고 만들어진 객체를 돌려줌
DaoFactory를 만들어 UserDao, ConnectionMaker 생성 작업을 담당하게 함
UserDaoTest에서는 만들어진 객체를 가져와 테스트만을 담당
<컴포턴트와 설계도>
실질적 로직: 컴포넌트
컴포넌트(오브젝트) 간의 관계: 설계도
팩토리를 사용하면 컴포넌트와 설계도를 분리할 수 있음
<팩토리의 활용>
accountDao, messageDao
ConnectionMaker 구현 클래스 선정/생성하는 코드 중복
-> connectionMaker 메서드로 분리
<제어의 역전>
-> 제어를 자신이 가지지 않음! 다른 오브젝트로 다 넘겨버림