코드를 개선해온 결과를 객체지향 기술의 여러 가지 이론을 통해 알아봅시다.
개방 폐쇄 원칙 (OCP, Open-Closed Principle)
service
에서 repository
의 기능은 언제든지 확장이 가능한 상태입니다. 동시에 확장을 하더라도, service
자신의 핵심높은 응집도와 낮은 결합도
개방 폐쇄 원칙은 높은 응집도와 낮은 결합도라는 소프트웨어 개발의 고전적인 원리로도 설명 가능합니다.
응집도가 높다는 것은 하나의 모듈, 클래스가 하나의 책임 또는 관심사에만 집중되어 있다는 것을 뜻하고,
불필요하거나 직접 관련이 없는 외부의 관심과 책임이 얽혀 있지 않다는 뜻입니다.
높은 응집도
낮은 결합도
즉, repository
라는 관심사를 하나의 관심사로 분리 하였으며, 인터페이스를 활용하였기 때문에 응집도가 높고, 결합도가 낮다고 할 수 있습니다.
전략 패턴
전략패턴은 자신의 기능에서, 필요에 따라 변경이 필요한 알고리즘을 인터페이스를 통해 통째로 외부로 분리시키고, 이를 구현한 구체적인 알고리즘 클래스를 필요에 따라 바꿔서
사용할 수 있는 디자인 패턴을 말합니다.
즉, 컨텍스트(service
)를 사용하는 클라이언트(AppConfig
)는 컨텍스트가 사용할 전략(repository
)를 컨텍스트의 생성자등을 통해 제공해주는 것을 말합니다.
지금 까지 개선해온 코드가 OCP, 높은 응집도, 낮은 결합도, 전략 패턴을 잘 지켰음을 증명했습니다.
스프링이란 객체지향적 설계 원칙과 디자인 패턴에 나타난 장점을 자연스럽게 개발자들이 활용할 수 있게 해주는 프레임워크입니다.
객체의 생성 방법을 결정하고 그렇게 만들어진 오브젝트를 돌려주는 일을 하는 오브젝트를 뜻합니다.
오브젝트를 생성하는 쪽과 생성된 오브젝트를 사용하는 쪽의 역할과 책임을 깔끔하게 분리하려는 목적으로 사용합니다.
이는, Ver 5. 에서 만들어봤던 AppConfig
와 같은 클래스를 뜻합니다.
@RequiredArgsConstructor
public class AppConfig {
private final EntityManager em;
public UserRepositoryV5 userRepository(){
return new UserRepositoryV5Impl(em);
}
public UserServiceV5 userService(){
return new UserServiceV5(userRepository());
}
}
service
-> repository
와 같은 의존 관계를 형성하고 있을 때, 새로운 repository
구현 클래스로 변경이 필요하면 AppConfig
클래스만 수정해주면 됩니다.
예를 들자면, repositoryImplV1
과 repositoryImplV2
와 같은 repository
구현체가 있을 때,
@RequiredArgsConstructor
public class AppConfig {
private final EntityManager em;
public UserRepositoryV5 userRepository(){
// return new UserRepositoryV5Impl(em);
return new UserRepositoryV5ImplV2(em);
}
public UserServiceV5 userService(){
return new UserServiceV5(userRepository());
}
}
이런 식으로만, 바꿔준다면 되는 것을 의미합니다.
일반적인 프로그램의 흐름은 main() 메소드와 같은 프로그램이 시작되는 지점에서 사용할 오브젝트, 오브젝트의 메소드 호출 등등
모든 종류의 작업을 사용자가 능동적으로, 직접 제어하는 구조입니다.
제어의 역전이란 이런 일반적인 프로그램의 흐름을 거꾸로 뒤집는 것 입니다.
제어의 역전에서는 자신이 사용할 오브젝트를 결정하지 않을 뿐더럴 생성조차 하지 않습니다.
모든 제어 권한을 자신이 아닌 다른 대상에게 위임하는 것을 뜻합니다.
흔히, 스프링과 같은 프레임워크는 제어의 역전 개념이 적용된 대표적인 기술이라고 합니다.
프레임워크와 라이브러리를 혼동할수도 있는데 둘은 엄연히 차이가 있습니다.
지금, 우리가 만든 repository
와 service
사이에서도 제어의 역전이 적용 되어 있습니다.
일반적인 프로그램의 경우, repository
의 구현 클래스를 결정하고 오브젝트를 만드는 결정권한은 service
에 있을 것입니다.
그러나, 지금음 AppConfig
에 있습니다. service
는 능동적인 존재가 아닌, 수동적인 존재가 되었다고고 말할 수 있습니다.
service
는 자기 자신도 수동적으로 만들어 지며, 사용할 오브젝트 또한 수동적으로 공급 받게 됩니다.
현재 지금 만든 것은 가장 단순한 IOC 프레임워크를 만들었다고 보면 될것이고, 이제 애플리케이션 전반에 걸쳐 사용하기 위해서는 대표적인 IOC 프레임워크인
스프링의 도움이 필요하합니다.(컴포넌트의 생성과 관계설정, 사용, 생명주기 관리등을 관장하는 존재)
깔끔한 정리 잘 봤습니다!
혹시 실례가 되지 않는다면 따로 정리를 해도 될까요? 출처 남기겠습니다!