Spring이 어떻게 객체 지향 프로그래밍을 지원하는지 알아보고자 합니다.
김영한 님의 인프런 강의를 토대로 정리했습니다.
객체 지향의 핵심 원칙인 SOLID는 모두에게 익숙하리라 생각합니다.
SRP는 주어진 메서드/클래스/컴포넌트를 변경할 이유가 하나여야 한다는 원칙이다
(출처: 클린코드)
우리가 객체, 클래스, 컴포넌트에게 바라는 것은 '하나', 즉 단일한 것이어야 합니다.
이 때 '바라는 것'의 의미는 '기대하는 역할', 혹은 '책임' 이라고도 할 수 있습니다.
class Shef {
void cook() {//선주문 선조리};
void serve() {//선주문 선서빙};
}
소프트웨어 요소는 확장에는 열려 있으나 변경에는 닫혀 있어야 한다
다형성과 밀접하게 닿아있는 원칙입니다. 기능의 사용은 인터페이스에 의지하도록 하고, 기능의 실제 구현은 인터페이스를 구현한 클래스에서 수행하도록 개방-폐쇄 원칙을 지키는 코드 작성에 도움이 됩니다.
인터페이스에 대한 내용은 여기에 더 자세히 정리해 두었습니다.
하지만, 분명 다형성을 사용했지만 OCP 원칙을 지킬 수 없는 경우가 발생한다.
이를 해결하기 위해서는 객체를 생성하고 연관관계를 맺어주는 별도의 조립, 설정자가 필요한데 이것이 바로 스프링이다.
from 김영한 님의 인프런 강의
프로그램의 객체는 프로그램의 정확성을 깨뜨리지 않으면서 하위 타입의 인스턴스로 바꿀 수 있어야 한다.
특정 클라이언트를 위한 인터페이스 여러 개가 범용 인터페이스 하나보다 낫다
프로그래머는 "추상화에 의존해야지, 구체화에 의존하면 안된다."
하지만 정말 모든 상황에서 이것을 지키는 것이 가능한 것일까? 답은 '혼자서는 불가능하다'입니다.
위에서도 언급했듯, 혼자서는 객체 지향을 지킬 수는 없습니다.
인터페이스에 의존하는 방식으로 코드를 작성할 수는 있겠지만, 결국 코드를 실행(혹은 컴파일)하기 위해서는 구현체가 필요합니다.
public class Main {
private MemoryInterface memoryInterface;
public void doSomething() {
memoryInterface.someMethod();
}
}
위처럼 아무리 메서드가 구현 클래스가 아닌 인터페이스에 의존하게 만들어도, 결.국. 우리는 이 코드를 쓰는 것을 피할 수 없습니다.
private MemoryInterface memoryInterface = new MemoryInterfaceImpl();
new가 등장하는 순간, DIP는 끝이 납니다...
구현체의 생성을 외부에서 관리하도록 하는 것, 이를 통해 DIP를 유지하는 것이 바로 제어의 역전입니다.
이 제어의 역전을 통해 '나(개발자)'는 더 이상 구현을 명시해야 할 필요가 없어졌습니다.
Spring 프레임워크에게 이 일을 맞길 수 있게 되었기 때문입니다.
프레임워크(Framework) vs 라이브러리(Library)
면접 질문을 검색하면 자주 나오는 질문 중 하나인데, 얘기가 나온 김에 정리해보려고 합니다.
- 프레임워크(Framework)
주도권이 프레임워크에게 있습니다. '나(개발자)'는 프레임워크가 요구하는 양식에 따라 코드를 작성합니다.
실행 시점에는 프레임워크가 내가 작성한 코드를 제어합니다.- 라이브러리(Library)
반면에 라이브러리는 내가 내 입맞에 맞춰서 가져다 쓰면 됩니다. 즉, '나(개발자)' 직접 제어의 흐름을 담당합니다.
IoC로 인해 우리는 Spring에 기댈 수 있게 되었습니다. 클래스 내부에 생성자를 두지 않아도 Spring이 런타임에 외부에서 객체를 생성해서 주입시켜 줍니다.
의존성 주입에는 3가지 방법이 있습니다 (자세한 내용은 여기에서)
생성자 주입(Constructor Injection): 생성자에 @Autowired 메서드를 붙여주면 됩니다.
필드 주입(Field Injection): 필드에 @Autowired 어노테이션을 붙여주면 됩니다.
수정자 주입(Setter Injection): setter 메서드에 @Autowired 어노테이션을 붙여주면 됩니다.
이처럼 스프링 덕분에 자바 진영은 추운 겨울을 이겨내고 Spring을 맞이할 수 있었습니다.
Spring이 오픈소스 프로젝트라는 것이 다행이다 싶은 순간입니다!