소프트웨어의 설계를 할 때 객체는 단 하나의 책임만 가질 수 있다.
객체가 하나의 책임을 가진다는 것은 새로운 기능이 확장되거나 변경사항이 있는 경우 파급효과가 적다면 하나의 책임을 가지고 있는 것이다.
이 말은 객체 간의 응집도는 높고 결합도가 낮은 프로그램으로 말할 수 있다.
소프트웨어가 기존의 코드를 변경하지 않고(Closed) 확장(Open)할 수 있다.
인터페이스 안에 필요 기능을 작성한다면 인터페이스를 구현하는 구현클래스는 다형성을 통해서 새로운 기능의 확장이 가능하다.
클래스를 상속하는 자식 클래스들은 부모 클래스의 규약을 지켜야한다.
어떤 구현 클래스는 자신이 구현하지 않는 인터페이스는 사용하지 않아야한다.
특정 클라이언트를 위한 인터페이스 여러 개가 범용 인터페이스 하나보다 낫다.
ex)
분리하면 정비 인터페이스 자체가 변해도 운전자 클라이언트에 영향을 주지 않고 인터페이스가 명확해져 대체 가능성이 높아진다.
구현체보다는 인터페이스나 추상 클래스에 의존하는 것이 좋다.
클라이언트가 기능을 이용할 때 인터페이스의 기능만 알고 그 안을 구현하는 구현체에 대해서는 몰라도 되는 것과 비슷한 원리이다.
구현체보다 인터페이스나 추상 클래스에 의존해야 기존 기능의 변경이나 새로운 요구사항을 통한 기능 확장이 되었을 때 유연한 변경이 가능하다.
여기서 OCP는 인터페이스와 구현체 둘다 의존하는 것을 알 수 있는데 이는 DIP를 위반하는 것으로 볼 수 있다.
즉 객체 지향 설계의 핵심은 다형성이지만 다형성만으로는 OCP, DIP를 위배하는 경우가 발생한다.
Spring Framework는 스프링이 지원하는 의존성 주입(Dependency Injection)과 DI 컨테이너를 이용해 자바 객체의 의존성을 연동해준다.
※ 참고 문헌