5장 객체 지향 설계 5원칙
카테고리: Oop-for-spring
스프링 입문을 위한 자바 객체 지향의 원리와 이해 5장의 내용을 정리한 글입니다.
객체 지향 설계 5원칙
객체 지향 프로그래밍을 하기 위해서 알아야할 5가지 원칙 SOLID
가 있습니다.
- SRP(Single Responseibility Priciple): 단일 책임 원칙
- OCP(Open Closed Priciple): 개방 폐쇠 원칙
- LSP(Liskov Substitution Principle): 리스코프 치환 원칙
- ISP(Interface Segregation Principle): 인터페이스 분리 원칙
- DIP(Dependency Inversin Priciple): 의존 역전 원칙
위의 원칙은 응집도
는 높이고, 결합도
는 낮추라는 고전 원칙을 객체 지향의 관점에서 재정립한 것이라고 할 수 있습니다.
결합도와 응집도
좋은 소프트웨어 설계를 위해서는 결합도
는 낮추고, 응집도
는 높이는 것이 바람직 합니다.
결합도
는 모듈(클래스) 간의 상호 의존 정도로서 결합도가 낮으면 모듈 간의 상호 의존성이 줄어들어 객체의 재사용이나 수정, 유지보수가 용이해집니다.
응집도
는 하나의 모듈 내부에 존재하는 구성 요소들의 기능적 관련성으로, 응집도가 높은 모듈은 하나의 책임에 집중하고 독립성이 높아져 재사용이나 기능의 수정, 보수가 용이해집니다.
결합도 수준
데이터 결합도, 스탬프 결합도, 컨트롤 결합도, 외부 결합도, 공유 결합도, 내용 결합도
응집도 수준
기능 응집도, 순차 응집도, 통신 응집도, 절차 응집도, 시간 응집도, 논리 응딥도, 우연 응집도
SRP - 단일 책임 원칙
어떤 클래스를 변경해야 하는 이유는 오직 하나뿐이어야 한다 - 로버트 C.마틴
단일 책임 원칙을 지키지 못한 코드
class Dog {
final static Boolean mail = true;
final static Boolean femail = false;
Boolean gender;
void saySomething() {
if (this.gender == mail) {
// some code
} else {
// another code
}
}
}
위의 코드는 강아지의 성별에 따라 메서드에서 분기 처리가 진행됩니다. Dog 클래스에서 saySomething() 메서드를 수컷 강아지의 행위와 암컷 강아지의 행위를 모두 구현하려고 하였기에 단일 책임(행위) 원칙을 위배하고 있습니다. 메서드가 단일 책임 원칙을 지키지 않을 경우 나타나는 대표적인 사례가 분기 처리를 위한 if문입니다.
단일 책임 원칙을 지킨 코드
class abstract Dog {
abstract void saySomething();
}
class MailDog extends Dog {
void saySomething() {
// some code
}
}
class FemailDog extends Dog {
void saySomething() {
// another code
}
}
하나의 모듈(클래스)는 하나의 책임(행위)를 가지는 것을 알 수 있습니다.
단일 책임 원칙과 객체 지향 4대 특성의 관계
단일 책임 원칙
과 가장 관계가 깊은 것은 모델링 과정을 담당하는 추상화
입니다. 애플리케이션의 경계를 정하고 추상화를 통해 클래스들을 선별하고 속성과 메서드를 설계할 때도 단일 책임 원칙을 적용해야합니다.
OCP - 개방 폐쇄 원칙
소프트웨어 엔티티(클래스, 모듈, 함수 등)는 확장에 대해서는 열려 있어야 하지만 변경에 대해서는 닫혀 있어야 한다 - 로버트 C. 마틴
위의 문장은 새로운 기능은 손쉽게 추가하고, 객체를 직접 수정하는 것은 제한해야 한다는 의미로 해석이 가능합니다.
JDBC로 예를 들자면, JDBC를 사용하는 클라이어느는 데이터베이스가 MySQL에서 오라클로 변경되더라도
, JDBC 인터페이스라고 하는 완충 장치가 있기 때문에 기존 자바 애플리케이션 코드는 수정할 필요성이 없습니다.
OCP를 지키지 않는다고 해서 객체 지향 프로그램을 구현하는 것이 불가능한 것은 아닙니다. 하지만 OCP를 지키지 않는다면, 객체 지향 프로그래밍의 가장 큰 장점인 유연성
, 재사용성
, 유지보수성
등의 이점을 얻을 수 없습니다.
LSP - 리스코프 치환 원칙
서브 타입은 언제나 자신의 기반 타입(base type)으로 교체할 수 있어야 한다. - 로버트 C. 마틴
LSP는 상속과 관련된 원칙입니다. 상속에 대해서 다시 설명하자면, 객체 지향에서의 상속은 조직도나 게층도가 아닌 분류도가 되어야 합니다. 로버트 C. 마틴의 말을 다시 의역하면 하위 클래스의 인스턴스는 상위형 객체 참조 변수에 대입해 대입해 상위 클래스의 인스턴스 역할을 하는 데 문제가 없어야한다 입니다.
ISP - 인터페이스 분리 법칙
클라이언트는 자신이 사용하지 않는 메서드에 의존 관계를 맺으면 안된다. - 로버트 C. 마틴
ISP 원칙이란 범용적인 인터페이스 보다는 사용자가 실제로 사용하는 인터페이스를 만들어야 한다는 의미로, 인터페이스를 사용에 맞게 끔 각기 분리해야한다는 설계 원칙입니다. 만약 인터페이스의 추상 메서드들을 범용적으로 이것저것 구현한다면, 그 인터페이스를 상속받은 클래스는 자신이 사용하지 않는 인터페이스 마저 *억지로 구현 해야하는 상황이 올 수 있습니다.
인터페이스 분리 법칙이란 인터페이스를 잘게 분리하므로써, 클라이언트의 목적과 용도에 적합한 인터페이스 만을 제공해야한다는 것을 의미합니다.
인터페이스 분리 원칙은 단일 책임 원칙과 비슷하게 보이는데, SRP은 클래스의 단일 책임을 강조한다면, ISP는 인터페이스의 단일 책임을 강조한다고 볼 수 있습니다.
DIP - 의존 역전 원칙
고차원 모듈은 저차원 모듈에 의존하면 안된다. 이 두 모듈 모두 다른 추상화된 것에 의존해야 한다.
추상화된 것은 구체적인 것에 의존하면 안 된다.
자주 변경되는 구체 클래스에 의존하지 마라
DIP 원칙이란 객체에서 어떤 클래스를 참조해서 사용해야 하는 상황이 생긴다면, 그 클래스를 직접 참조하는 것이 아니라 그 대상의 상위 요쇼(상위 클래스, 추상 클래스, 인터페이스)를 참조하라는 원칙입니다.
DIP 원칙을 지키면 변하지 않을 가능성이 높은 상위 요소를 의존하기 때문에, 변하기 쉬운 것의 변화에 영향을 받지 않게 할 수 있습니다.
객체 지향 세계와 SOLID
SOLID는 객체 지향을 올바르게 프로그램에 녹여내기 위한 원칙입니다. 따라서 객체 지향 4대 특성을 제대로 이해해야 SOLID를 제대로 이해하고 활용할 수 있습니다.
댓글 남기기