이번 포스팅에선 객체지향 설계 5원칙인 SOLID에 대해 알아보려고 한다.
객체지향의 4가지 특성인 캡슐화, 추상화, 다향성, 상속과 더불어 설계 원칙을 공부해보자.
SOLID 는 자기 자신 클래스의 응집도는 내부적으로 높이고 , 타 클래스들간 결합도는 낮추는
High Cohesion - Loose Coupling 원칙을 객체 지향의 관점에서 도입한 것 이다.
정보처리자격증을 공부할 때, 응집도가 높고 결합도가 낮을 수록 객체지향의 설계에 적합하고,
이렇게 설계된 SW는 재사용성이 증가하고, 수정이 최소화 되기 때문에 유지보수가 용이해진다고 배웠다.
SRP ( Single Responsibility Principle ) 단일 책임 원칙
" 어떤 클래스를 변경해야 하는 이유는 오직 하나 뿐이어야 한다"
클래스의 역할과 책임을 너무 많이 주지 말라는 뜻이다.
클래스를 설계할 때 어플리케이션의 경계를 정하고 , 추상화를 통해 어플리케이션 경계 안에서
필요한 속성과 메서드를 선택하여 설계해야 한다.
남자 클래스를 SRP을 적용해 역할마다 클래스를 분리하면
이렇게 적용 할 수 있겠다.
OCP ( Open Closed Principle ) 개방 폐쇠 원칙
" 소프트웨어 엔티티( 클래스, 모듈, 함수 )는 확장에 대해서는 열려 있어야 하지만 , 변경에 대해서는 닫혀 있어야 한다 "
자신의 확장에는 열려 있고, 주변의 변화에 대해서는 닫혀 있어야 한다는 뜻이다.
운전자는 클래스의 변화에 따라 행동이 의존적으로 변하게 된다.
때문에, 상위에 자동차라는 클래스를 만들어서, 자동차클래스는 하위에 다른 차종을 상속하여
황장할 수 있고, 운전자는 그 변경 사항에 전혀 영향을 받지 않을 수 있다.
웹개발에서 흔히 사용하는 JDBC로 예를 들어보자.
Spring에서 JDBC를 이용해서 DB에 접속할 때 , JDBC가 아닌 DB드라이버와 직접 컨텍한다면
각각의 DB의 변경사항에 영향을 받고 자바애플리케이션에 영향을 끼쳐 여러 문제점이 발생 할 것이다.
때문에 DB의 확장에는 열려있고, JDBC 인터페이스의 변화에는 닫혀있는 모습이다.
LSP ( Liskov Substitution Principle) 리스코프 치환
" 서브 타입은 언제나 자신의 기반 타입으로 교체할 수 있어야 한다"
객체지향에서 상속은 조직도, 계층도가 아닌 분류도가 되어야한다.
- 하위 분류는 상위 분류의 한 종류여야한다.
- 구현 분류는 인터페이스 할 수 있어야 한다.
ISP ( Interface Segregation Principle ) 인터페이스 분리 원칙
" 클라이언트는 자신이 사용하지 않는 메소드에 의존 관계를 맺으면 안된다. "
SRP의 예제 중 남자를 단일 책임을 갖는 클래스로 나눈 표이다.
이것은 너무 많은 클래스 구현을 불러오기 때문에, 다양한 역할을 인터페이로 나누고
남자라는 클래스는 그 인터페이스를 구현한 클래스 이면 된다.
남자친구 홍길동 = new 남자();
아들 홍길동 = new 남자();
사원 홍길동 = new 남자();
소대원 홍길동 = new 남자();
한마디로 각각 인터페이스를 정의하고 상황에 맞는 메서드만을 정의한다는 것이다.
상위클래스가 풍성할 수록 캐스팅이 적게 일어나서 소스코드가 깔끔해진다.
DIP ( Dependency Inversion Principle ) 의존 역전 원칙
"고차원 모듈은 저차원 모듈에 의존하면 안된다. 이 두 모듈 모두 다른 추상화 된 것에 의존해야 한다. "
DIP를 구현하는 한가지 방법이 스프링에서 많이 강조되는 DI (Dependency Injection ) 이다.
해당 의존 관계를 타이어 인터페이스를 사용하여 역전시킨다.
구체적인 스노우 타이어에 의존하던 것을 추상적인 타이어에 의존하는 것으로 변경하는 것이다.
해당 방법은 위에서 설명한 OCP ( 개방 폐쇄 원칙 ) 에서 나온 방법이다.
설계 원칙 안에 다른 설계 원칙이 녹아있는 경우가 많기 때문에
어떤 느낌으로 객체지향을 설계해야 하는 지 감을 잡는게 중요하다고 생각한다.
스프링은 생산성을 높이고 유지보수를 용이하게 해주는 프레임워크이다.
그 중 스프링의 중요한 기능으로 여겨지는 DI라는 의존성주입이 위에서 설명한 SOLID에 나와있는 것과 다르지 않다.
결국 객체지향에서 생산성을 높이고 유지보수를 용이하게 하기 위해선 SOLID 설계를 따라야 한다는 것이다.
소규모 프로젝트라도 몇 번 해보면 바로 느낄 수 있다.
설계를 잘하는 것이 유지보수는 물론 개발시간과 비용, 성능 등 모든 부분에 큰 영향을 끼친다는 것을.
지금은 제대로 이해가 안되더라도, 계속 숙지해서 자유롭게 쓸 수 있도록 노력해보려고 한다.
'JAVA > 자바' 카테고리의 다른 글
함수형 인터페이스 (0) | 2023.06.10 |
---|---|
[Java] Enum, 열거타입 (0) | 2023.06.07 |
[JAVA] Static과 Final (0) | 2022.02.26 |
[JAVA] 스택과 힙 , 가비지 컬렉터 (1) | 2022.02.25 |
[JAVA] String에서 ==와 equals()의 차이점 (0) | 2022.02.20 |