본문 바로가기
Spring/기본

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

by wch_t 2023. 7. 18.

Q. EJB(Enterprise Java Beans) 란?

 

개념

 

 ▶ 기업 환경에서 사용되는 분산 컴포넌트 아키텍처를 위한 표준 Java 기술

 

 

 

장점

 

 1. 분산 애플리케이션 개발을 위한 기본 구조를 제공한다.

 2. 트랜잭션 관리와 보안 : 트랜잭션 관리와 보안을 자동으로 처리하여, 개발자가 직접 구현할 필요가 없다.

 

 

 

단점

 

 1. 복잡한 모델을 가지고 있어, 설정 및 배포 작업에 시간이 걸린다.

 2. 순수 객체지향적이지 않다. (Session Bean, Entity Bean)

 3. 컨테이너 환경 없이 단위 테스트하기 어려움

 

 * 복잡성과 기술적 제약으로 개발 생산성과 유연성이 감소된다.

 

 

 


 

 

 

Q. Spring 이란?

 

개념

 

 ▶ Java를 기반으로 하는 기업용 애플리케이션 개발을 위한 경량급 프레임워크

 

 

 

등장 배경

 

- 기존의 자바 엔터프라이즈 개발은 EJB와 같은 복잡한 스펙과 컨테이너에 의존했다.

Spring은 이러한 복잡성을 줄이고 더 간편하게 개발할 수 있도록 하기 위해 등장했다.

 

 

 

구성

 

 1. Spring Core : IoC 컨테이너와 DI 를 포함한 Spring Framework의 핵심 기능 제공

 

 2. Spring MVC : 웹 애플리케이션 개발을 위한 모듈로서, MVC 아키텍처 지원

 

 3. Spring Data : 데이터 액세스 기술을 단순화하고 통합하는 기능 제공

 

 4. Spring Security : 인증과 권한 부여를 위한 보안 모듈

 

 5. Spring Boot : Spring 애플리케이션을 빠르고 쉽게 개발하기 위한 프레임워크로

                                필요한 초기 설정을 간편하게 처리, 자체적인 웹 서버를 내장하고 있어 빠르고 간편한 배포 가능

 

 

 

핵심 컨셉

 

 - IoC(Inversion of Control)

 

 : 객체의 생명 주기와 의존 관계를 프레임워크가 관리하는 것 (=제어의 주도권이 넘어감)

   이를 통해, 개발자는 객체 생성과 의존성 주입에 집중할 필요 없이 핵심 로직을 구현할 수 있음

 

 * Annotaion / SpringConfig 사용하여 객체를 Spring Bean으로 등록

 

 

- DI(Dependency Injection)

 

 : 객체가 의존하는 다른 객체를 외부에서 주입받는 것

   이를 통해, 객체 간의 결합도를 낮추고 유연성과 재사용성을 높일 수 있음

 

 : 사용자가 직접 new 키워드를 사용하여 객체를 생성하지 않고, 외부(컨테이너)에서 생성된 객체를 주입받는 방식

   즉, 의존하는 객체를 직접 생성하는 대신 스프링 컨테이너로부터 의존 객체를 주입받는 방식

 

 

 - AOP(Aspect Oriented Programming)

 

 : 공통 관심사(cross-cutting concern)를 모듈화하여 코드의 중복을 줄이고 관리를 용이하게 함 (Proxy 사용)

 

 

 

장점

 

 1. EJB보다 경량화되어 있으며, 필요한 기능만 선택적으로 사용할 수 있다.

 2. DI를 통해 객체의 생성과 관리를 프레임워크에 위임하여, 코드의 유연성과 재사용성을 높일 수 있다.

 

 3. 다양한 라이브러리와의 통합을 지원해, 단위 테스트와 통합 테스트를 용이하게 가능하다. (JUnit, Mock Test)

 

 

 


 

 

 

 +. 강의 내용

 

1) 스프링

 

 > 문맥에 따라 다르게 사용된다.

 

 - 스프링 DI 컨테이너 기술

 

 - 스프링 프레임워크

 

 - 스프링 부트, 스프링 프레임워크 등을 모두 포함한 스프링 생테계

 

 

 

 

 

2) 스프링의 진짜 핵심

 

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

 

 

 

 

 

3) 다형성

 

 추상화 된 하나의 인터페이스를 통해 여러 타입을 처리할 수 있는 것

 

역할(interface)구현(class)으로 구분

 

클라이언트는 구현 대상의 내부 구조를 모르거나 변경되어도 상관없다.

→ 역할(interface)만 알면 된다.

 

 

- 다형성의 본질

 

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

 

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

 

 

 

 

 

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

 

 1. SRP (Single Responsibility Principle)

 

       - 단일 책임 원칙

       - 변경이 있을 때 파급 효과가 적으면 단일 책임 원칙을 잘 따른 것

         (ex. UI 변경, 객체의 생성과 사용을 분리)

 

 

 2. OCP (Open/Closed Principle)

 

       - 개방 폐쇄 원칙

       - 확장에는 열려 있으나 변경에는 닫혀 있어야 함

         (ex. Config(?), 다형성과 DI 활용)

         (최소한의 변경..??)

       

 

 3. LSP (Liskov Substitution Principle)

 

       - 리스코프 치환 원칙

       - 프로그램의 정확성을 깨뜨리지 않으면서, 서브 타입은 기반 타입의 인스턴스로 치환해도 문제 없이 동작해야 한다.

         (위반 ex. 직사각형-정사각형)

 

 

 4. ISP (Interface Segregation Principle)

 

       - 인터페이스 분리 원칙

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

   

 

 5. DIP(Dependency Inversion Principle)

 

       - 의존관계 역전 원칙

       - 프로그래머는 "추상화(=인터페이스, 역할)에 의존해야지, 구체화(=클래스, 구현)에 의존하면 안된다.

        → 클라이언트가 인터페이스에 의존해야 유연하게 구현체를 변경할 수 있다.

 

 

 

 

 

5) 정리

스프링은 "다형성 + OCP, DIP" 를 가능하게 지원한다!

- DI : 의존관계 주입

 - DI 컨테이너 제공



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

 

 

 

실무 고민

 

- 인터페이스를 도입하면 추상화라는 비용이 발생한다. (구현체가 무엇인지 한눈에 파악하기 힘듦)

 

- 기능을 확장할 가능성이 없다면, 구체 클래스를 직접 사용하고

향후 꼭 필요할 때 리팩터링해서 인터페이스를 도입하는 것도 방법이다.

 

 

 

 

출처 : 김영한님의 스프링 핵심 원리 - 기본편 (link)