내일배움캠프 Kotlin & Spring 챌린지반 세션 - 변경에 유연한 프로그래밍 강의를 정리했습니다.
객체지향 프로그래밍에서 변경에 유연한 프로그램을 만들기 위해서는 캡슐화가 중요하고, 이를 위해서 DI가 필요한 이유를 흐름에 따라 서술했습니다.
1. 객체지향 프로그래밍은 여러 객체들이 협력해나가는 방식으로 프로그래밍합니다.
2. A객체가 B객체에게 협력을 요청하는 것은 의존한다는 것입니다.
A객체 내부에서 B객체의 메소드를 호출하거나, B객체를 생성하는 등 A객체를 만들기 위해 B객체가 필요한 경우를 말합니다.
이때 A객체는 요청을 보내는 객체, 클라이언트 객체입니다.
객체지향 프로그래밍은 협력을 기반으로 하므로 의존성이 반드시 필요합니다.
3. 의존성은 변경을 전파합니다.
예를 들어 B객체의 메소드 이름이 변경되면 A객체 내부에서 호출했던 메소드 이름도 변경해야 합니다.
4. 소프트웨어의 중요한 가치 중 하나는 변경에 유연해야 한다는 것입니다.
하지만 의존성은 변경을 전파하므로, 이를 최소화해야 합니다.
5. 따라서 변경될 가능성이 낮은 것에 클라이언트 객체가 의존하도록 해 결합도를 낮춰야 합니다.
변경될 가능성이 낮은 것을 추상적인 것이라고 합니다.
클라이언트 객체가 구체적인 것을 의존하지 않고 추상적인 것에 의존하도록 하는 것을 캡슐화라고 합니다.
6. 객체의 구체적인 것을 외부로부터 숨겨 특정 객체를 캡슐화합니다.
나아가 객체 자체를 구체적인 것으로 보고 클라이언트 객체가 추상화된 상위 타입에 의존하도록 해 캡슐화합니다.
추상화 타입은 추상 클래스, 인터페이스가 대표적이지만, 일반 클래스도 가능합니다.
7. 추상화 타입은 하위 타입에게 책임을 물려줍니다.
하위 타입은 추상화 타입의 역할을 할 수 있는 객체임이 보장됩니다.
8. 추상화 타입을 이용해 다형성을 구현합니다.
클라이언트 객체는 코드로 존재하는 컴파일 시점에는 추상화 타입에 의존합니다.
정확히는 추상화 타입의 역할을 할 수 있는 객체에 의존합니다.
따라서 실제 어플리케이션이 실행되는 런타임 시점에는 추상화 타입의 역할을 대체할 수 있는 구현 객체가 그 자리를 차지할 수 있습니다.
9. 이렇게 구현된 다형성이 변경에 유연한 구조를 만듭니다.
클라이언트 객체는 의존하는 객체가 구체적으로 어떻게 동작하는지 모릅니다.
그래서 언제든지 구체적인 것을 변경할 수 있는 자율적인 객체가 됩니다.
10. 클라이언트 객체는 의존하는 객체를 직접 생성하거나 외부로부터 주입받을 수 있습니다.
직접 객체를 생성하는 방식은 추상화 타입에 의존할 수 없고, 객체를 생성하는 방식이 변경되면 클라이언트 객체로 변경이 전파될 수 있습니다.
그러므로 외부로부터 주입받아야 합니다.
즉 추상화 타입을 의존함으로써 다형성을 구현하려면 DI(Dependency Injection. 의존성 주입)가 필요합니다.