Spring은 정말 어려운 프레임워크이다. 왜냐하면 개발자들이 정말 오랜 기간 동안 고민하면서 개발 패러다임의 격변을 가져왔던 객체지향에 관한 생각, 그리고 끊임없이 연구되어 왔던 자바를 활용한 다양한 디자인 패턴들이 모두 함축되어 있는 프레임워크이기 때문이다. 대략적으로만 생각해보더라도 스프링의 핵심 기술에는 IoC/DI, AOP, PSA 등이 있고, 그 외에도 데이터베이스 용도로 응용하여 활용할 수 있는 기술들인 JPA, QueryDSL 등도 존재한다. 또한 아직 사용해보거나 접해보지 못한 부분들에는 더 많은 내용들이 녹아 있을 것이다.

그중에서도 스프링에서의 객체지향 설계의 기본이 되는, IoC와 DI에 대해 간단히 정리해 보았다.

 

IoC (Inversion of Control, 제어의 역전)

간단하게 설명하면 말 그대로이다. 제어의 역전. 제어권이 역전되어 있는 상황을 의미한다.

그렇다면 제어의 역전이란 곧 기존의 제어 방식을 뒤집었다는 말인 것 같은데, 기존의 방식은 과연 어떠했을까?

기존 프로그램의 경우 클라이언트의 구현 객체가 스스로 필요한 서버 구현 객체를 생성하고, 연결하고, 실행하는 등 프로그램의 제어 흐름을 스스로 조종했다. 즉, 코드의 제어권은 개발자가 갖고 있는 것이다.

그러나 Spring에서는 코드에서 제어권을 프레임워크가 갖고 있고, 개발자는 일종의 config 파일만을 활용하여 프레임워크에게 제어할 수 있는 방법을 제공한다. 이후 프로그램의 제어 흐름 자체는 개발자가 직접 제어하지 못하고, 프레임워크 단에서만 관리가 가능해진다. 사용자가 작성하는 부분은 프레임워크의 라이프사이클 속에서 일종의 콜백 형식으로 적절한 위치에서 자동으로 호출되게 된다. 이러한 상황을 제어의 역전, IoC라고 한다.

Spring에서는 구현 객체를 생성하고 연결하는 책임을 AppConfig 단에서만 담당하게 되어, SRP(단일 책임 원칙)에도 부합하는 소프트웨어를 개발할 수 있게 해준다.

 

DI (Dependency Injection, 의존관계 주입)

DI는 스프링에서 클래스 간 또는 클래스와 인터페이스 간의 의존 관계들을 정의해주기 위해 필요한 개념이다. 의존 관계에는 정적인 클래스 의존 관계와 런타임에 결정되는 동적인 객체(인스턴스) 의존 관계 두 가지 종류가 존재한다.

정적인 클래스 의존 관계의 경우, 클래스에서 사용하는 코드만을 통해서도 의존관계를 쉽게 판단할 수 있다. 예를 들어 주문 관련 Service가 존재한다면, 해당 Service내에서 어떤 Repository 인터페이스를 사용할지 등의 내용은 이미 요구사항 분석과 클래스 다이어그램을 작성하면서 어느정도 구상이 끝나 있었을 것이다. 하지만, 이러한 클래스 의존 관계만을 통해서는 실질적으로 어떤 객체가 Service에 주입될지, 즉 각 인터페이스 내에 어떤 구현체가 사용될지에 관한 내용을 파악하기는 어렵다.

이를 위해 동적인 객체 인스턴스 의존 관계 파악이 필요하다. 동적인 객체 인스턴스 의존 관계는 애플리케이션의 실행 시점에 실제 생성된 객체 인스턴스의 참조가 연결된 의존 관계를 의미한다.

이때 애플리케이션 실행 시점, 즉 런타임에 실제 구현 객체를 생성하고, 클라이언트에 전달하여 실제 의존 관계가 연결되는 것의존관계 주입, DI라고 한다. 의존관계 주입을 통하여 클라이언트 코드를 변경하지 않고 호출 대상의 타입 인스턴스를 변경할 수 있으며, 정적인 클래스 의존 관계를 변경하지 않고 동적인 객체 인스턴스 의존 관계를 쉽게 변경할 수 있다.

스프링에서는 IoC를 구현하기 위하여 의존 관계 주입을 사용하고 있고, 이는 AppConfig 파일 내에서 객체를 생성하고 관리하면서 의존 관계를 연결해 주고 있다. 이러한 것을 IoC 컨테이너 또는 DI 컨테이너라고 부른다.

Spring에서는 DI 컨테이너를 이용하여 객체 인스턴스를 클라이언트 코드 대신 생성해서 클라이언트 코드에 의존 관계를 주입하고 있다. 즉, 클라이언트 코드는 추상화에 의존하여 개발할 수 있고 이를 통해 DIP(의존관계 역전 원칙)에도 부합하는 소프트웨어를 개발할 수 있게 해준다.

또한 DI 컨테이너만을 이용하여 의존 관계를 변경할 수 있게 되면서 애플리케이션을 사용 영역과 구성 영역으로 나누어 주기 때문에 클라이언트 코드는 변경하지 않아도 되며, 결국 소프트웨어 요소를 새롭게 확장해도 사용 영역의 변경은 닫혀 있도록 구현이 가능해진다. 이는 OCP(개방 폐쇄 원칙)에 부합하는 소프트웨어를 개발할 수 있게 해준다.

반응형

스프링 프레임워크에 대해 공부하면서, 스프링의 가장 큰 두가지 특징으로 DI와 IoC가 존재한다는 것을 배웠었다.

그런데 스프링에서 DI와 IoC를 도입하게 된 이유로 되돌아 올라가 보면, 싱글톤 패턴을 적용하면서 객체지향에서의 SOLID 원칙을 따르기 위해 해당 개념을 사용했다고 한다. 그러나 해당 개념에 대해서 이해하기 어려웠던 점도 있고, 최근 코딩 테스트 이후 CS 시험들을 2차 테스트로 보면서 SOLID 원칙에 대해 어느정도 상세히 이해하고 있는지에 대해서 묻는 문제들이 자주 출제되었다. 그래서 스프링 공부를 하면서 겸사겸사 SOLID 원칙에 대해 간단하게 정리해 보았다.

SOLID란 로버트 마틴의 좋은 객체 지향 설계의 5가지 원칙으로, 해당 원칙들의 맨 앞글자들을 따서 만든 용어이다. 이 원칙을 알아야 하는 이유는 시스템의 기능이 확장되거나 변동사항이 있을 때, 객체지향적인 설계가 추구하는 점인 기존의 시스템들이 영향을 받지 않는 방향을 갖기 위해서이다.

 

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

소프트웨어의 한 객체는 단 하나의 책임만 가질 수 있다.

변경이 있을 때 파급 효과가 작은 경우 SRP를 잘 따랐다고 할 수 있으며, 책임의 범위를 적절하게 조절할 필요가 있다.

객체 간의 응집도를 최대화하고, 객체 간의 결합도를 최소화하는 것이 좋은 프로그램이라고 볼 수 있다.

 

 

2. OCP(Open/Closed Principle, 개방 폐쇄 원칙)

소프트웨어가 기존의 코드를 변경하지 않고(Closed) 확장할 수 있다(Open).

확장에는 열려 있고, 변경에는 닫혀 있어야 한다.

이때 자바의 경우 다형성을 사용하는데, 인터페이스를 구현한 새로운 클래스를 만듬으로써 새로운 기능을 구현한다.

그러나 구현 객체를 변경하려면 결국 클라이언트 코드를 변경해야 하는 문제점이 있고, 이때 OCP가 깨지게 된다. 따라서 스프링에서는 이 원칙을 DI를 이용하여 지원하고 있다.

 

 

3. LSP(Liskov Substitution Principle, 리스코프 치환 원칙

객체는 프로그램의 정확성을 깨트리지 않으면서 하위 타입의 인스턴스로 변환할 수 있어야 한다.

클래스를 상속하는 자식 클래스들은 부모 클래스의 규약을 지켜야 한다는 것으로, 기능적으로 보장이 필요하다는 의미이다. 인터페이스에 대한 구현체를 구현할 때, 인터페이스의 규약을 지켜줘야 한다.

컴파일 단계에서 문제가 생기지 않을수는 있지만, 부모 클래스가 규정하고 있는 기능을 무시하거나 오버라이딩을 자제해야 한다는 의미이다.

 

 

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

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

여러 개의 인터페이스를 구현함으로써 대체 가능성을 향상시키고, 인터페이스의 기능을 명확하게 표현할 수 있다.

일반적인 인터페이스를 구체적인 여러 인터페이스로 나눠줌으로써 ISP를 만족하도록 설계할 수 있다.

 

 

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

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

구현체보다는 인터페이스나 추상 클래스에 의존하는 편이 좋다는 의미로, 클라이언트 코드가 구현 클래스를 바라보는 것이 아닌, 인터페이스를 바라보도록 하는 것을 의미한다. 즉, 역할에 의존하게 한다는 의미로써, 클래스에서 역할의 의미를 갖는 인터페이스에 의존해야 한다는 것이다.

그러나 일반적인 경우, 인터페이스가 구현 클래스를 선택하게 되기 때문에 이때, DIP의 위반이 발생할 수 있다. 따라서 이 문제점도 스프링에서는 DI를 이용하여 클라이언트 코드 변경 없이 기능을 확장할 수 있도록 제공하고 있다.

 

 

반응형

+ Recent posts