오브젝트(조영호 저)를 읽고 작성한 글입니다.
개방 폐쇄 원칙은 "확장에는 열려 있어야 하고, 변경에는 닫혀 있어야 한다."를 의미한다. 조금 더 쉽게 풀어 쓰자면, "객체의 기능을 확장할 수 있으면서 기존의 코드(클라이언트 코드)는 수정하지 않는다." 를 뜻한다.
런타임 의존성과 컴파일타임 의존성
OCP는 런타임 의존성과 컴파일타임 의존성에 관한 이야기다.
Movie는 인터페이스인 DiscountPolicy에 의존하기 때문에, 자식 클래스로 OverlappedDiscountPolicy 클래스를 추가하더라도 기존의 코드(Movie, DiscountPolicy, AmountDiscountPolicy, PercentDiscountPolicy)는 변하지 않는다.
새로운 컨텍스트에 사용되도록 확장할 수 있는 것.
새로운 할인 정책을 추가해서 기능을 확장하도록 열려있다.
그리고 기존 코드를 수정할 필요가 없다.
추상화
OCP의 핵심은 추상화에 의존하는 것이다.
OCP에서 '변경에 닫혀 있다'는 것은 구체적으로 말하면 '추상화 부분은 변경에 대해 닫혀 있다'라는 뜻이 된다.
'폐쇄'를 가능하게 하는 것은 (추상화에 대한) 의존성의 방향이다.
생성 책임 분리
public class Movie {
//...
private DiscountPolicy discountPolicy;
public Movie(String title, Duration runningTime, Money fee) {
// ...
this.discountPolicy = new AmountDiscountPolicy();
}
// ...
}
위 코드에서는 할인 정책 종류를 추가(기능을 확장)하기 위해 기존의 코드를 수정해야 하기 때문에 OCP를 위반한다.
또한 하위 클래스를 알고 있기 때문에 결합도가 높아진다.
유연하고 재사용 가능한 설계를 원한다면 객체에 대한 생성과 사용의 책임을 분리하자.
가장 보편적인 방법은 객체 생성의 책임을 클라이언트로 옮기는 것이다.
FACTORY
FACTORY : 객체에 대한 생성과 사용을 분리하기 위해 객체 생성에 특화된 객체.
DI
생성과 사용의 책임을 분리한 후에 사용되는 방법이 DI이다.
DIP
자주 변하는 구체적인 클래스보다는 변하기 어려운 인터페이스나 상위(추상) 클래스와 의존 관계를 맺으라는 원칙
의존 관계를 맺을 때 변화하기 쉬운 것에 의존하기보다는, 변화하지 않는 것에 의존하도록 함으로써 애플리케이션을 변경에 용이하게 할 수 있습니다.
- 상위 모듈은 하위 모듈에 의존해서는 안된다. 추상화에 의존해야 한다.
- 객체는 세부 사항에 의존해서는 안된다. 구체적인 사항은 추상화에 의존해야 한다.
유연한 설계는 곧 복잡한 설계
유연한 설계는 코드를 복잡하게 만들고 가독성을 해친다.
유연성이 필요할 때에만 유연한 설계를 하자.
'CS > OOP' 카테고리의 다른 글
[오브젝트] 11장 - 합성과 유연한 설계 (0) | 2024.02.15 |
---|---|
[오브젝트] 10장 : 상속의 문제점과 추상화 (1) | 2024.02.05 |
[오브젝트] 8장 - 좋은 의존성과 나쁜 의존성 (0) | 2024.01.29 |
[오브젝트] 7장 : 기능 분해의 측면에서 본 OOP (1) | 2024.01.23 |
[오브젝트] 6장 - 메시지와 인터페이스 (0) | 2024.01.22 |