[Java] 객체지향 설계 5원칙 - SOLID
- 4 minsOOP를 실 세계에서 설명하려면?
- OOP 4대 특성 : 주방도구
- 추상화/ 상속/ 캡슐화/ 다형성
- OOD (객체 지향 설계) 5원칙 : 주방 도구 설명서
- SOLID
- DP (디자인 패턴) : 레시피
1. SRP (Single Responsibility Principle) 단일 책임 원칙
: 클래스
와 메소드
는 하나의 역할만 하도록 한다.
"어떤 클래스를 변경해야 하는 이유는 오직 하나뿐이어야 한다." - 로버트 C. 마틴
- 변화의 시기와 이유가 다르면 클래스는 분리하여야 한다.
남자
클래스를 SRP을 적용해 역할 마다 클래스를 분리함.
2. OCP (Open Closed Principle) 개방 폐쇄 원칙
: 자신의 확장에는 개방돼 있고, 주변의 변화에 대해서는 폐쇄돼 있어야 한다.
"소프트웨어 엔티티(패키지, 클래스, 모듈, 함수 등)는 확장에 대해서는 개방되어야 하지만,
변경에 대해서는 폐쇄되어야 한다." - 로버트 C. 마틴
운전자
는 마티즈
와 쏘나타
의 변화에 따라 행동이 의존적으로 변화게 된다.
때문에 마티즈
, 쏘나타
의 상위에 자동차
라는 상위클래스를 둔다.
이렇게 되면 자동차
클래스는 하위에 다른 차종을 상속하여 확장할 수 있고, 운전자
는 그 변경 사항에 전혀 영향을 받지 않을 수 있다.
DB 의 확장에는 열려있고, JDBC 인터페이스의 변화는 닫혀있다.
3. LSP (Liskov Substitution Principle) 리스코프 치환 원칙
: 서브타입은 언제나 자신의 상위 타입으로 교체할 수 있어야 한다.
"서브 타입은 언제나 자신의 기반 타입으로 교체할 수 있어야 한다."
- 로버트 C 마틴
객체지향에서 상속은 조직도, 계층도가 아니라 분류도가 되어야 한다.
- 하위 클래스
is a kind of
상위 클래스 : 하위 분류는 상위 분류의 한 종류이다. - 구현 클래스
is able to
인터페이스 : 구현 분류는 인터페이스 할 수 있어야한다.
상속을 잘 활용하고 있다면, 이미 LSP는 잘 구현하고 있는 것이다.
- LSP 위반 사례 : 딸은 아버지의 역할을 할 수 없다.
- LSP를 잘 구현한 사례 : 박쥐는 포유류의 역할을 할 수 있다.
4. ISP (Interface Segregation Principle) 인터페이스 분리 원칙
"클라이언트는 자신이 사용하지 않는 메소드에 의존 관계를 맺으면 안 된다."
- 로버트 C 마틴
SRP의 예제 중 남자
를 단일 책임을 갖는 클래스로 나누었다. 이것은 너무 많은 클래스 구현을 불러 온다. 그래서 다양한 역할을 인터페이스로 만들고 남자
라는 클래스는 그 인터페이스를 구현한 클래스이면 된다.
때문에 이런식으로 고칠 수 있다.
남자친구 홍길동 = new 남자();
아들 홍길동 = new 남자();
사원 홍길동 = new 남자();
소대원 홍길동 = new 남자();
빈약한 상위 클래스 vs 풍성한 상위 클래스
상위클래스가 풍성할 수록 캐스팅(Casting)이 적게 일어나서 소스코드가 깔끔해진다. 때문에 상위클래스가 풍성할 수 록 좋다.
5. DIP (Dependency Inversion Principle) 의존 역전 원칙
: 자신보다 변하기 쉬운 것에 의존하지 마라.
"고차원 모듈은 저차원 모듈에 의존하면 안 된다. 이 두 모듈 모두 다른 추상화된 것에 의존해야 한다."
"추상화된 것은 구체적인 것에 의존하면 안된다. 구체적인 것이 추상화된 것에 의존해야 한다.
"자주 변경되는 구체(Concrete) 클래스에 의존하면 안된다."
- 로버트 C 마틴"
DIP를 구현하는 한가지 방법이 DI(Dependency Injection)이다.
- 자동차는 스노우 타이어에 의존하고 있다.
- 해당 의존 관계를
타이어
인터페이스를 사용하여 역전시킴 : 구체적인스노우 타이어
에 의존하던 것을 추상적인타이어
에 의존하는 것으로 변경함
// 기존 코드
class Car {
SnowTire tire = new SnowTire();
}
// DIP 적용
class Car {
Tire tire;
void setTire(Tire tire) {
this.tire = tire;
}
}
자신보다 변하기 쉬운 것에 의존하지 마라.
상위클래스
일 수록, 인터페이스
일 수록, 추상 클래스
일 수록 변하지 않을 가능성이 크다.
하위클래스
나 구체클래스
가 아닌 더 추상적인 것에 의존하라는 것이 의존 역전 원칙이다.
관심사의 분리(SOC)
이 것을 추구하면 자연스럽게 SOLID
는 자연스럽게 구현된다.
SOLID 원칙을 적용하면 소스파일의 갯수는 오히려 늘어 나지만, 그만큼 유지보수와 코드에 대한 이해가 쉬워진다.