일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- BOJ2042
- 객체지향 설계 5원칙
- batch udpate
- Greedy
- 리액트의 작동방식
- 리액트 성능 최적화
- 섬 연결하기
- 리액트 상태값 업데이트
- codility
- React 훅 사용규칙
- useContext
- JS Array Functions
- Kruskal Algorithm
- useState
- heap
- react
- State
- DB Navigator
- spread operator
- Modern Javascript
- 프로그래머스#JAVA
- useReducer
- DFS
- java
- MST구현
- Lifting State Up
- 프로그래머스
- state update scheduling
- Segment Tree
- rest operator
- Today
- Total
개발하는SM
[Spring] Spring 의 핵심 컨셉과 좋은 객체지향 설계의 5원칙(SOLID) 본문
개요
Spring 프레임워크의 핵심 컨셉은 무엇인지, 왜 만들었는지에 대해 아래 강의 내용을 바탕으로 정리하였다.
스프링 핵심 원리 - 기본편 - 인프런 | 강의
스프링 입문자가 예제를 만들어가면서 스프링의 핵심 원리를 이해하고, 스프링 기본기를 확실히 다질 수 있습니다., - 강의 소개 | 인프런
www.inflearn.com
Spring 과 좋은 객체 지향 어플리케이션
Spring 은 객체 지향 언어인 JAVA 기반의 프레임워크이다.
Spring 은 좋은 객체 지향 어플리케이션을 개발할 수 있도록 도와주는 프레임워크이다.
그렇다면 좋은 객체 지향 어플리케이션이란 어떤 것일까?
객체 지향 프로그래밍은 프로그램을 유연하고 변경이 용이하게 만들기 때문에 대규모 소프트웨어 개발에 많이 사용된다.
프로그램을 유연하고 변경이 용이하게 만들어주는 객체 지향 언어의 핵심 특징 - 다형성
다형성의 실세계 비유 : 역할과 구현으로 세상을 구분함
자동차의 역할에는 엑셀 / 브레이크 등이 있음.
해당 역할을 구현하는 실제 자동차 모델들이 있음.
이렇게 역할과 구현으로 구분하면 세상이 단순해지고, 유연해지며 변경도 편리해진다.
클라이언트( 위 그림의 운전자 ) 는 대상의 역할( 자동차의 역할 ) 만 알면 된다.
실제 구현 대상 ( 자동차 상세 모델 ) 의 상세한 내부 구조를 몰라도 되고, 내부 구조가 변경되어도 영향을 받지 않는다.
구현 대상이 변경되어도 자동차의 역할 자체는 변하지 않으므로 클라이언트 ( 운전자 )는 영향을 받지 않는다.
자바 언어의 다형성을 활용하면 역할과 구현을 분리할 수 있다.
- 역할 = 인터페이스
- 구현 = 인터페이스를 구현한 클래스, 구현 객체
인터페이스에 있는 메소드를 오버라이딩하여 구현 객체별로 메소드를 다르게 정의할 수 있다.
아래 예시에서, MemberRepository 인터페이스가 save() 라는 메소드를 가지고 있고
MemberRepository 를 구현하는 MemoryMemberRepository 와 JdbcMemberRepository 는 각각 save() 메소드를 오버라이딩하여 서로 다르게 정의할 수 있다.
아래에서 클라이언트 역할을 하는 MemberService 의 경우 MemberRepository 라는 인터페이스에 save() 라는 메소드를 호출해야 한다는 사실만을 알고 있으면 된다. ( 상세 구현 클래스에 대해서는 몰라도 된다 )
따라서 클라이언트를 변경하지 않고, 서버의 구현 기능을 유연하게 변경할 수 있다.
스프링은 이러한 다형성을 극대화해서 이용할 수 있도록 도와준다.
스프링에서 이야기하는 제어의 역전(IoC), 의존관계 주입(DI)은 다형성을 활용하여 역할과 구현을 편리하게 다룰 수 있도록 지원한다.
좋은 객체 지향 설계의 5원칙 ( SOLID )
1. SRP ( Single Responsibility Principle, 단일 책임 원칙 )
- 한 클래스는 하나의 책임만 가져야 한다.
- 중요한 기준은 변경이다. 변경이 있을 때 파급 효과가 적으면 해당 원칙을 잘 따른 것이라고 볼 수 있다.
2. OCP ( Open/closed principle, 개방-폐쇄 원칙 )
- 소프트웨어 요소는 확장에는 열려있으나 변경에는 닫혀있어야 한다.
- 다형성을 사용하여 인터페이스를 구현하는 새로운 클래스를 만들어 새로운 기능을 구현한다.
그런데 아래 예시에서는 다형성을 활용했지만, 구현 객체를 변경하려면 클라이언트( MemberService ) 소스를 변경해야 한다.
분명 다형성을 사용했지만 OCP 원칙을 지킬 수 없다.
이러한 문제점을 Spring 을 사용하여 해결할 수 있다.

3. LSP ( Liskov substitution principle, 리스코프 치환 원칙 )
- 프로그램의 객체는 프로그램의 정확성을 깨뜨리지 않으면서 하위 타입의 인스턴스로 바꿀 수 있어야 한다
- 예를 들어, 자동차의 엑셀 역할인데 속도 + 100 이 아니라 속도 - 100 형태이면 안됨
4. ISP ( Interface segregation principle, 인터페이스 분리 원칙 )
- 특정 클라이언트를 위한 인터페이스 여러 개가 범용 인터페이스 하나보다 낫다
- 자동차 인터페이스 -> 운전 인터페이스, 정비 인터페이스로 분리 // 사용자 클라이언트 -> 운전자 클라이언트, 정비사 클라이언트로 분리
- 인터페이스가 명확해지고, 대체 가능성이 높아진다.
5. DIP ( Dependency inversion principle, 의존관계 역전 원칙 )
- 추상화( 인터페이스 ) 에 의존해야지, 구체화 ( 구현 ) 에 의존해선 안된다.
- 앞에서 이야기 했듯이 역할에 의존해야 한다는 것과 같음.
그런데, 위의 OCP 원칙 위배 사례를 보면 클라이언트 ( MemberService ) 는 인터페이스 뿐만 아니라 구현
( MemoryMemberRepository ) 에도 의존함.
MemberService 가 구현 클래스를 직접 선택하기 때문임. 이는 DIP 원칙 위배.
위의 예시를 통해 살펴보았듯이, 다형성만으로는 OCP, DIP 원칙을 지킬 수 없음.
스프링은 DI ( Dependency Injection, 의존관계 주입 ) 및 DI 컨테이너 제공을 통해 다형성 + OCP, DIP 를 가능하게 지원함.
정리
Spring 은 좋은 객체 지향 어플리케이션을 만들 수 있도록 도움을 주는 프레임워크이다.
좋은 객체 지향 어플리케이션은 역할과 구현이 명확하게 분리되어 유연하고 변경이 용이하다.
좋은 객체지향 어플리케이션 설계의 5원칙 - SOLID
단순 다형성만으로는 5원칙 중 OCP, DIP 원칙을 지킬 수 없음.
스프링에서 제공하는 기술을 통해 다형성 + OCP, DIP 가 가능해짐.