-
[Spring 개념] 객체 지향 설계와 스프링Back-End/Spring Boot 2022. 9. 29. 12:24
나는 스프링의 원리에 대해 잘 이해하고 있는가?라고 질문하면 아니라고 말할 수 있다. 이번에 면접 준비를 하면서 기본 개념들에 대해 알아보는 시간을 가졌는데, 짧은 시간에 많은 개념을 맛보기로 알 수 있었다. 이상태론 취업을 한다고 해도 내 실력과 이해력에 내가 먼저 지칠 것 같아 다시 탄탄하게 스프링에대해 공부해보려고 한다. 기간은 2달 정도로 잡았고 인프런 김영한 강사님의 스프링 완전 정복 로드맵을 파고들 예정이다. 무려 52만원이나 주고 구매했다는,, 열심히 배워서 작은 프로젝트라도 하나 만들고 포트폴리오 다시 재정비해서 올해안에 취업하는게 새로운 목표다.!
📑 스프링 프레임워크와 스프링 부트
Spring Framework와 Spring Boot는 스프링을 공부했다고 하면 필수로 알아야될 부분인데, 그 개념에 대해 먼저 잡고 가려고 한다.
🔨 Spring Framework 란?
스프링 프레임워크는 자바 플랫폼을 위한 오픈소스 애플리케이션 프레임워크로서 간단히 스프링이라고 불린다. 동적 웹 사이트를 개발하기 위한 여러가지 서비스를 제공하고 있다.
- 핵심 기술 : 스프링 DI 컨테이너, AOP, 이벤트 ,,,
- 웹 기술 : 스프링 MVC, 스프링 WebFlux
- 데이터 접근 기술 : 트랜잭션, JDBC, ORM 지원, XML 지원
- 기술 통합 : 캐시, 이메일, 원격 접근, 스케줄링
- 테스트 : 스프링 기반 테스트 지원
- 언어 : 코틀린, 그루비
🔨 Spring Boot 란?
스프링 프레임워크는 기능이 많은 만큼 환경설정이 복잡한 편이다. 이에 어려움을 느끼는 사용자들을 위해 나온 것이 바로 스프링 부트! 즉) 스프링 부트는 스프링 프레임워크를 사용하기 위한 설정의 많은 부분을 자동화하여 사용자가 정말 편하게 스프링을 활용할 수 있도록 돕는다. 단독으로 실행할 수 있는 스프링 애플리케이션을 쉽게 생성해준다.
- Tomcat 같은 웹서버를 내장해서 별도의 웹 서버를 설치하지 않아도 된다.
- 손쉬운 빌드 구성을 위한 starter 종속성 제공
: 이전 spring framework에서는 각각의 dependency들의 호환되는 버전을 일일이 맞추어 주어야 했기에 하나의 버전을 올리고자 하면 다른 dependency에 영향을 미쳐 version 관리에 어려움이 많았다. 하지만) 스프링 부트는 starter가 대부분의 dependency를 관리해 주므로 이런 걱정을 던다.
- 스프링과 3rd parth(외부) 라이브러리 자동 구성 , 최적회
- 메트릭, 상태확인, 외부 구성 같은 프로덕션 준비 기능 제공
- 관리에 의한 간결한 설정
스프링은 자바 언어 기반의 프레임워크로 객체 지향 언어의 특징을 가진다. 즉) 객체 지향 애플리케이션을 개발할 수 있도록 도와주는 프레임워크이다. 스프링에대해 알아보기 앞서 좋은 객체 지향 프로그래미잉 뭔가에 대해 정리해보겠다.
📑 객체 지향 프로그래밍
객체 지향 프로그래밍은 컴퓨터 프로그램을 명령어의 목록으로 보는 시각에서 벗어나 여러개의 독립된 단위, 즉 "객체"들의 모임으로 파악하고자 하는 것이다. 각각의 객체는 메시지를 주고받고, 데이터를 처리할 수 있다. 즉) 협력할 수 있다. 객체 지향 프로그래밍은 프로그램을 유연하고 변경이 용이하게 만들기 때문에 대규모 소프트웨어 개발에 많이 사용된다.
객체 지향 프로그래밍의 특징으론 아래와 같은 4가지가 있다.
1. 추상화
2. 상속
3. 다형성
4. 캡슐화이 중 가장 중요한 것, 스프링에서 핵심 내용은 다형성이다. 다형성을 이해할 때 역할과 구현으로 구분하면 이해하기 쉬운데, 역할은 인터페이스, 구현은 인터페이스를 구현한 클래스, 구현 객체라 생각하고 역할과 구현을 명확하게 분리한다.
예를들어) 운전자는 자동차의 역할만 알면, 즉) 자동차를 운전할줄만 알면 그 자동차가 무엇인지, 자동차 구현에 대해선 알 필요가 없는 것이다.
정리해보자면 다음과 같은데, 객체 설계시 역할(인터페이스)을 먼저 부여하고, 그 역할을 수행하는 구현 객체를 만들면 된다.
1. 클라이언트는 대상의 역할(인터페이스)만 알면 된다.
2. 클라이언트는 구현 대상의 내부 구조를 몰라도 된다.
3. 클라이언트는 구현 대상의 내부 구조가 변경되어도 영향을 받지 않는다.
4. 클라이언트는 구현 대상 자체를 변경해도 영향을 받지 않는다.자바의 다형성으로 오버라이딩을 떠올려보자. 다형성으로 인터페이스를 구현한 객체를 실행 시점에서 유연하게 변경할 수 있다. 예를 들어 MemberService라는 클라이언트, 요청을 하는 클래스가 있다. 여기서 save() 라는 메서드를 호출했는데 이 메스드는 MemberRepository라는 인터페이스에 정의되어 있다. 이 인터페이스를 구현하는, 재정의 오버라이딩하는 클래스 2가지가 있는데, 이 클래스 중 어느 것을 가져다 써도 상관 없다. 요청이 필요할 때 클라이언트를 변경하지 않고, 유연하게 적합한 클래스를, 적합한 서버 구현 기능을 가져다 사용할 수 있는 것. 이게 바로 다형성의 특징이다.
❗ 따라서 인터페이스를 안정적으로 잘 설계하는 것이 중요하다.
📑 좋은 객체 지향 설계의 5가지 원칙 (SOLID)
1. SRP (Single Responsibility Principle) : 단일 책임 원칙
2. OCP (Open/Closed Principle) : 개방 - 폐쇄 원칙
3. LSP (Liskov Substitution Principle) : 리스코프 치환 원칙
4. ISP (Interface Segregation Principle) : 인터페이스 분리 원칙
5. DIP (Dependency Inversion Principle) : 의존관계 역전 원칙📌 1. SRP (Single Responsibility Principle) : 단일 책임 원칙
한 클래스는 하나의 책임만 가진다.
: 모든 클래스는 각각 하나의 책임만 가져야 하며, 수정할 이유는 단 한 가지여야 한다. 즉) 클래스는 그 책임을 완전히 캡슐화해야 함을 말한다.
예를 들어, 결제 클래스가 있다면 이 클래스는 오직 결제 기능만을 책임지고, 만약 이 클래스를 수정해야 한다면 결제에 관련된 문제이다.
변경이 있을 때 파급 효과가 적으면 단일 책임 원칙을 잘 따른 것.
📌 2. OCP (Open/Closed Principle) : 개방 - 폐쇄 원칙
확장에는 열려있고 변경에는 닫혀 있어야 한다.
: 소프트웨어의 구성요소(컴포넌트, 클래스, 모듈, 함수)는 확장에는 열려 있어야 하지만 변경에는 폐쇄적이어야 함을 의미한다. 즉) 기존의 코드를 변경하지 않으면서, 기능을 추가할 수 있도록 설계가 되는 원칙을 말한다.
예를 들어, 캐릭터 하나를 생성한다고 할 때 각 캐릭터마다 움직임이 다를 경우, 움직임 패턴 구현을 하위 클래스에 맡긴다면 캐릭터 클래스의 수정은 필요 없고, 움직임 패턴만 재정의하면 된다.
추상화와 다형성을 활용할 수 있는데, 구현 객체를 변경하려면 클라이언트 코드를 변경해야 하는 문제점이 생길 수 있다. 다형성을 사용했지만 OCP 원칙을 지킬 수 없는 것. 이런 문제를 스프링에서 객체를 생성하고 연관관계를 맺어주는 별도의 조립, 스프링 컨테이너 설정자가 필요하다. 이 문제점은 앞으로 스프링 DI를 공부하면서 더 자세히 알아갈 예정
📌 3. LSP (Liskov Substitution Principle) : 리스코프 치환 원칙
서브 타입은 언제나 자신의 기반 타입으로 변경할 수 있어야 한다.
: 상위 타입은 항상 하위 타입으로 대체할 수 있어야 한다. 즉) 부모 클래스가 들어갈 자리에 자식 클래스를 넣어도 역할을 하는데 문제가 없어야 한다는 의미이다.
다형성에서 하위 클래스는 인터페이스 규약을 다 지켜야 한다. 다형성을 지원하기 위한 원칙으로 인터페이스를 구현한 구현체를 믿고 사용하려면 LSP 원칙이 필요하다.
예를들어, 자동차 인터페이스의 엑셀은 앞으로 가야되는 기능이다. 이런 기능을 뒤로 가게 구현한다면 LSP 위반이다. 속도를 바꾸더라도 무조건 앞으로 가야한다.
📌 4. ISP (Interface Segregation Principle) : 인터페이스 분리 원칙
하나의 일반적인 인터페이스보다 여러 개의 구체적 인터페이스가 낫다.
: 인터페이스 분리 원칙은 각 역할에 맞게 인터페이스를 분리하는 것이다. 인터페이스 내에 메서드는 최소한 일수록 좋다. 즉) 최소한의 기능만 제공하면서 하나의 역할에 집중하라는 뜻이다.
예를들어, 자동차 인터페이스가 있을 때 이를 운전, 정비 인터페이스로 분리한다. 이는 인터페이스가 명확해지고, 대체 가능성이 높아진다. 물론 가독성이나 유지 보수도!
📌 5. DIP (Dependency Inversion Principle) : 의존관계 역전 원칙
구체적인 것이 추상화 된 것에 의존해야 한다. 자주 변경되는 구체 클래스에 의존하지 마라.
: 의존 관계를 맺을 때 변화하기 쉬운 것 또는 자주 변화하는 것보다는 변화하기 어려운 것, 거의 변화가 없는 것에 의존하라는 것이다. 즉) 구체적인 클래스보다 상위 클래스, 인터페이스, 추상 클래스와 같이 변하지 않을 가능성이 높은 클래스와 관게를 맺으라는 의미이다.
반응형'Back-End > Spring Boot' 카테고리의 다른 글
[Spring Boot] 스프링 컨테이너 ApplicationContext 생성과 빈 등록, 의존 관계 설정 (0) 2022.09.30 [JAVA 객체 지향 설계의 원칙] OCP, DIP 예제로 완전 정복 ( + 관심사 분리) (0) 2022.09.30 [Spring Boot] 스프링 웹 개발 흐름 살펴보기 - 정적, MVC, API (1) 2022.09.26 [SpringBoot] IntelliJ 프로젝트 cmd로 빌드하기 (0) 2022.09.26 [SpringBoot] IntelliJ로 프로젝트 생성 후 실행 방법 ( +Gradle) (1) 2022.09.26