스프링

4. [SOLID] 객체 지향 설계 5가지 원칙

juhoyang 2024. 9. 13. 10:52

클린코드로 유명한 로버트 마틴의 좋은 객체지향 설계의 5가지 원칙

 

1. SRP(Single Responsibility principle) 단일 책임 원칙

한가지 클래스는 하나의 책임만 가져야 한다.

-> 수정이 있을때 변경 

 

하나의 책임? 

  - 규모는 다를수 있음

  - 문맥과 상황에 따라 다름

 

기준

 변경이 있을 때 파급 효과가 적으면 해당 원칙을 잘 따른것

 

예) 한 파일 소스에 DB접근, View, 중요 로직이 한꺼번에 있다면 한가지 수정이 있을때 모든 로직이 있는 파일을 수정해야 한다.

따라서 각각 목적에 맞게 파일을 분리해서 변경이 있을때 영향 범위에 맞는 파일만 수정 하도록 하는게 수정에 있어 파급효과가 적다.

 

2. [중요] OCP(Open/closed Princile) 개발-폐쇄 원칙

소프트웨어 요소는 확장에는 열려 있으나 변경에는 닫혀 있어야 한다.

다형성을 활용해 구현

 

인터페이스를 구현한 새로운 클래스를 만들어서 설정하려먼 소스 수정을 해야하는데 Sping은 소스가아닌 설정 파일 수정으로 설정가능하다.

 

3. LSP(Liskov substitution principle) 리스코프 치환 원칙

객체는 프로그램의 정확성을 깨뜨리지 않고 하위 타입의 인스턴스로바꿀 수 있어야 한다.

인터페이스의 목적의 규약을 다 지켜야 한다. 

다양성을 지원 하기 위해 인터페이스를 구현한 구현체를 믿고 사용하려면 해당 원칙이 지켜줘야 한다.

 

예) 인터페이스의 메소드의 목적이 합계를 구하는 거라면 해당 목적에 맞게 구현해야 한다. (합계를 구하는 목적이 아닌 다른 것으로 구현하면 안됨)

 

4. ISP(Interface Segregation Principle) 인터페이스 분리 원칙

특정 클라이언트를 위한 인터페이스 여러개가 범용 인터페이스 하나 보다 낫다.

인터페이스를 분리해서 사용하면 변경이 있을 때 영향범위가 작음 -> 인터페이스가 명확해지고 대체 가능성이 높아짐

 

예)

휴대폰 인터페이스를 만든다고 하면 한개보다는 전화, 통화,, 등으로 쪼개서 인터페이스를 만드는게 특정부분에서 변경이 있을때 영향범위가 적다.

 

5. DIP(Dependency Inversion Principle) 의존관계 역전 원칙

프로그래머는 추상화에 의존해야지, 구체화에 의존하면 안된다. 

구현 클래스에 의존하지 말고, 인터페이스에 의존 하라는 뜻 (클래스에 의존하게 되면 나중에 변경하기 힘듬)

 

 

스프링에서 SOLID 구현

SRP

- 한 클래스는 하나의 책임만 가져야 한다.

- 클라이언트 객체는 실행하는 책임만 담당하고 구현 객체를 생성하고 연결하는 책임은 AppConfig가 담당한다.

 

DIP

- 추상화에 의존해야지, 구체화에 의존하면 안된다.

- DI 는 해당 원칙을 따르는 방법중 하나

- 클라이언트 코드가 추상화 인터페이스에만 의존하도록 객체 인스턴스생성과 주입은AppConfig가 해줌

 

OCP

- 소프트웨어 요소는 확장에 열려있고 변경에는 닫혀있어야 한다.

- 애플리케이션을 사용영역과 구성영역으로 나누어 클라이언트 코드는 추상화에만 의존하고 구성영역인 AppConfig에서는 구현객체를

생성 주입을 담당하여 구성 영역에서 객체를 변경해도 클라이언트 코드는 수정은 닫혀있다.

 

순수한 java로 OCP, DIP원칙을 지키기는 힘들다.

 

이유

위 내용과 같이 서비스(OrderServiceImpl)에서 역할인 인터페이스(DiscountPolicy)의 구현체를 바꿀때 마다

아래처럼 service소스를 수정해야 하기 때문이다. -> DIP위반

 

해당 문제를 해소하기 위해 스프링에서 DI컨테이너를 이용해 객체를 주입해줄수 있다.

 

수정내용

OrderServiceImpl

- 인터페이스만(추상화) 의존하여 넣음

 

AppConfig

- 실질적인 구현체 설정은 해당 설정파일에서 진행

 

DI(Dependency Injection) + DI 컨테이너  -> OCP, DIP를 가능하게 지원한다.

클라이언트 코드 변경없이 기능을 확장할 수 있다. 

 

정리

 

참고

https://inpa.tistory.com/entry/OOP-%F0%9F%92%A0-%EA%B0%9D%EC%B2%B4-%EC%A7%80%ED%96%A5-%EC%84%A4%EA%B3%84%EC%9D%98-5%EA%B0%80%EC%A7%80-%EC%9B%90%EC%B9%99-SOLID

 

💠 객체 지향 설계의 5가지 원칙 - S.O.L.I.D

객체 지향 설계의 5원칙 S.O.L.I.D 모든 코드에서 LSP를 지키기에는 어려움. 리스코프 치환 원칙에 따르면 자식 클래스의 인스턴스가 부모 클래스의 인스턴스를 대신하더라도 의도에 맞게 작동되어

inpa.tistory.com

 

자료출처

스프링 핵심 원리 - 기본편

https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%ED%95%B5%EC%8B%AC-%EC%9B%90%EB%A6%AC-%EA%B8%B0%EB%B3%B8%ED%8E%B8/dashboard

 

스프링 핵심 원리 - 기본편 강의 | 김영한 - 인프런

김영한 | 스프링 입문자가 예제를 만들어가면서 스프링의 핵심 원리를 이해하고, 스프링 기본기를 확실히 다질 수 있습니다., 스프링 핵심 원리를 이해하고, 성장하는 백엔드 개발자가 되어보

www.inflearn.com

 

'스프링' 카테고리의 다른 글

7. 스프링 컨테이너, 빈  (0) 2024.09.22
5. IoC, DI, 컨테이너  (0) 2024.09.22
3. 객체지향 프로그래밍이란? (java)  (1) 2024.09.12
2. 스프링 프레임 워크의 구성  (0) 2024.09.11
1. 스프링이란?  (0) 2024.09.11