스프링 프레임워크에 대해 공부하면서, 스프링의 가장 큰 두가지 특징으로 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