HAZEL

[ CHAPTER 01. 객체 지향 설계와 스프링 ] 스프링, 좋은 객체 지향 프로그래밍, 객체 지향 특징, 다형성, SOLID 본문

PROGRAMMING/Spring

[ CHAPTER 01. 객체 지향 설계와 스프링 ] 스프링, 좋은 객체 지향 프로그래밍, 객체 지향 특징, 다형성, SOLID

Rmsid01 2021. 3. 30. 12:34

- 인프런 '스프링 핵심 원리 - 기본편' 을 듣고 정리한 내용입니다.

 

01. 스프링이란 ? 


1. 스프링 생태계

: 스프링이란, 여러 개의 모음이라고 생각!

 - 필수 :  스프링 프레임워크, 스프링 부트

 - 선택 : 스프링 데이터 (jp) , 스프링 세션 ( 세션기능을 편하게 쓰기 위한 것 ) , 스프링 rest Docs( api 문서를 편하게 쓸수있게 한것 ) ,

              스프링 배치, 스프링 클라우드  

 

외에도 굉장히 많은 기술이 존재함! 

spring.io/projects

 

Spring | Projects

Spring Framework Provides core support for dependency injection, transaction management, web apps, data access, messaging, and more.

spring.io

 

2. 스프링 프레임워크

- 핵심기술

- 웹기술

- 데이터 접근 기술

- 기술 통합

- 테스트

- 언어

 

3. 스프링 부트

: 스프링을 편리하게 사용할 수 있도록 지원, 최근에는 기본으로 사용됨.  

 

4. 스프링 이란 ? ( 문맥에 따라 다르게 해석 )

a. 스프링 DI컨테이너 기술

b. 스프링 프레임 워크

c. 스프링 부터, 스프링 프레임워크 등을 모두 포함한 스프링 생태계

 

5. 스프링이 중요한 이유

a. 스프링은 자바 언어 기반의 프레임워크 

b. 자바가 가진 객체 지향 언어의 가장 큰 장점을 잃어버리지 않게 하는 프레임워크

   즉, 스프링은 좋은 객체 지향 애플리케이션을 개발 할 수 있게 도와주는 프레임워크

 

 

02. 좋은 객체 지향 프로그래밍이란 ?


1. 객체 지향 특징

: 추상화, 캡술화, 상속, 다형성

 

2. 객체 지향 프로그래밍이란,

객체 지향 프로그래밍은 컴퓨터 프로그램을 명령어의 목록으로 보는 시각에서 벗어나 여러 개의 독립된 단위, "객체"들의 모임으로 파악하고자 하는 것이다. 각각의 객체메시지 를 주고받고, 데이터를 처리할 수 있다. (협력)

: 객체 지향 프로그래밍은 프로그램을 유연하고 변경이 용이하게 만들기 때문에 대규모 소프 트웨어 개발에 많이 사용된다.

 즉, 컴포넌트를 쉽고 유연하게 변경하면서 개발할 수 있는 방법이라는 것이다. 즉, 다형성을 의미한다. 

 

3. 다형성이란, 

하나의 객체가 여러 가지 타입을 가질 수 있는 것. 즉 역할과 구현을 분리함을 의미한다. 

 -> 역할과 구현으로 구분하면 세상이 단순해지고, 유연해지며, 변경도 편리해진다. 

 

- 장점 < 핵심은 '클라이언트' >

   a. 클라이언트는 대상의역할(인터페이스)만 알면 됨

   b. 클라이언트는 구현 대상의 내부 구조를 몰라도 됨.

   c. 클라이언트는 구현 대상의 내부 구조가 변경되어도 영향을 받지 않음.

   d. 클라이언트는 구현 대상 자체를 변경해도 영향을 받지 않음 ex, 테슬라 -> 아반떼

 

- 자바언어에서의 역할과 구현을 분리

: 역할 = 인터페이스 

: 구현 = 인터페이스를 구현한 클래스, 구현 객체

 => 객체를 설계할 때 역할과 구현을 명확히 분리, 확장 가능한 설계이며 클라이언트에 영향을 주지 않고 변경 가능함.

 => 객체 설계시 역할(인터페이스)를 먼저 부여하고, 그 역할을 수행하는 구현 객체 만듦 

 * 핵심 : 역할(인터페이스)이 중요하다! - 인터페이스를 안정적으로 잘 설계하는 것이 중요함  

 

- 역할과 구현을 분리 ; 한계

: 역할(인터페이스) 자체가 변하면, 클라이언트 / 서버 모두에 큰 변경이 발생함 

  따라서, 인터페이스를 안정적으로 잘 설계하는 것이 무엇보다도 중요하다! 

 

- 객체의 협력

: 혼자의 객체는 없다.

: 클라이언트  : 요청, 서버 : 응답

: 수 많은 객체 클라이언트와 객체 서버는 서로 협력 관계를 가짐

 

- 서버는 또 다른 클라이언트일수있다.

 

4. 자바 언어의 다형성

: 오버라이딩 으로 동작함  

: 다형성으로 인터페이스를 구현한 객체를 실행 시점에 유연하게 변경할 수 있다.

 

5. 다형성의 본질

인터페이스를 구현한 객체 인스턴스를 실행 시점유연하게 변경할 수 있다.

: 다형성의 본질을 이해하려면 협력이라는 객체사이의 관계에서 시작해야함

 : 클라이언트를 변경하지 않고, 서버의 구현 기능을 유연하게 변경할 수 있다.

 

6. 스프링과 객체 지향

: 스프링은 다형성을 극대화해서 이용할 수 있게 해줌.

: 스프링에 나오는 제어의 역전, 의존관리 주입은 다형성을 활용해서 역할과 구현을 편리하게 다룰 수 있도록 지원함.

 

 

03. 좋은 객체 지향 설계의 5가지 원칙 ( SOLID )


1. SOLID 란,

: 클린코드로 유명한 로버트 마틴이 좋은 객체 지향 설계의 5가지 원칙을 정리한 것.

 

a.  SRP: 단일 책임 원칙(single responsibility principle)
b.  OCP:
개방-폐쇄 원칙 (Open/closed principle)
c . LSP:
리스코프 치환 원칙 (Liskov substitution principle)

d . ISP: 인터페이스 분리 원칙 (Interface segregation principle)

e. DIP: 의존관계 역전 원칙 (Dependency inversion principle)

 

2. SRP: 단일 책임 원칙(single responsibility principle)

: 하나의 클래스는 하나의 책임만 가짐. - 하지만 하나의 책임은 모호함 

: 이 책임의 범위를 너무 작게도 너무 크게도 하지않고, 적절하게 설정하는 것이 중요하다.

: 따라서, 중요한 기준은 '변경'이다. 변경을 하고나서 파급효과가 적으면 단일 책임 원칙을 잘따른것이라고 말할 수 있다.

 

3. OCP: 개방-폐쇄 원칙 (Open/closed principle) - 가장 중요함

: 소프트웨어 요소는 확장에는 열려있으나, 변경에는 닫혀 있어야 한다. -> 다형성! 

 즉, 인터페이스를 구현한 새로운 클래스를 만들어서 새로운 기능을 구현 

  

  - OCP 의 문제점 

    : 구현 객체를 변경하려면 클라이언트 코드를 수정해야함 -> 다형성을 사용했지만, OCP원칙은 깨짐

      -> 해결 : 객체를 생성하고, 연관관계를 맺어주는 별도의 조립, 설정자가 필요함

 

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

: 인터페이스와 구현체가 있을 때, 하위 클래스는 인터페이스 규약을 다 지켜야한다는 것이며, 단순히 컴파일 성공의 문제가 아님.

 

5. ISP: 인터페이스 분리 원칙 (Interface segregation principle)

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

 즉, 쇼핑 인터페이스 -> 구입 인터페이스, 검색 인터페이스로 분리

 -> 장점 : 인터페이스가 명확해지고, 대체 가능성이 높아진다. 

 

6. DIP: 의존관계 역전 원칙 (Dependency inversion principle) - 중요함

: 추상화에 의존하고 구체화에 의존하면 안된다. 즉, 인터페이스(역할)에 의존 ! 

 

하지만, 

OCP에서 설명한 MemberService는 인터페이스에 의존하지만, 구현 클래스도 동시에 의존한다.

MemberService 클라이언트가 구현 클래스를 직접 선택

  MemberRepository m = new MemoryMemberRepository();

 

-> 즉, DIP 가 위반된다는 것을 볼 수 있다. 

-> 즉, 다형성만으로는 부족하다. 해결방법은 추후 공부하면서 다룰예정이다. 

 

7. 정리

객체 지향의 핵심은 다형성이다. 하지만,  쉽게 부품을 갈아 끼우듯이 개발할 수 없으며,
구현 객체를 변경할 때 클라이언트 코드도 함께 변경된다.

즉, 다형성 만으로는 OCP, DIP를 지킬 수 없다. 따라서 더 필요한 무엇이 있다. ( 뒤에 나옴 ) 

 

04. 객체 지향 설계와 스프링


1. 스프링의 강점

: 스프링은 DI 컨테이너를 통해 다형성 과  좋은 객체 지향의 요소인 OCP, DIP 를 가능하게 지원해준다. 

: 클라이언트 코드의 변경없이 기능이 확장 가능하다. 

 

2. 스프링의 단점

: 인터페이스를 도입하면, 추상화라는 비용이 발생함

-> 기능을 확장할 가능성이 없다면, 구체 클래스를 직접 사용하고, 향후 꼭 필요할 때 리팩터링해서 인터페이스를 도입하는 것도 방법.