최근 몇달 간 클라우드 및 인프라 공부를 하며 스프링 개발을 하지 않은지 꽤 되었던거 같다. 여러 사람을 만나고, 몇가지 활동들을 참여하며 최근에 내린 결론은 '어떤 직무를 희망하든 개발 능력은 기본적으로 구비되어야 한다'는 것이다. 이러한 결론을 내린 뒤 책을 통해 꾸준히 스프링 공부를 하고 있었는데, 객관적으로 바라보았을 때 내가 정말 깊이 있게 스프링을 알고 있지는 않다는 생각이 들었다. 어떠한 어노테이션이 있다고 했을 때, '내가 봤던 자료나 책에서 000 장점이 있으니 써야한다' 정도의 생각으로만 접근했지, 이걸 사용하지 않았을 때 어떤 문제점이 야기되는지 이러한 것들이 궁극적으로 어떠한걸 위하는지 등에 대한 고려를 전혀하고 있지 않았다. 내년 휴학 인턴 구직을 위해서든, 2년 뒤 취업시장에서의 나를 위해서든 나의 문제점을 깨달았을 때. 그리고 그 시점이 다시 늦지 않았다고 느껴질 때 감사함과 함께 다시 공부를 시작하는 것이 좋을 것 같다는 생각이 들었다. 그래서 이제 다시 시작으로 돌아가 공부한 것을 차분히 기록하며 성장을 도모하고자 한다.
스프링 부트의 장점
- Tomcat같은 웹 서버를 내장해서 별도의 웹 서버 설치가 필요하지 않다
- 손쉬운 빌드 구성을 위한 starter 종속성 제공
- 외부 라이브러리 버전에 대해 크게 고민하지 않아도 된다
- 메트릭 모니터링(시스템의 성능과 상태에 대한 통계적인 정보 ex) CPU 사용률, 메모리 사용량, 응답 시간 등) 지원
스프링의 진짜 핵심
- 자바 기반의 framework -> 객체 지향 언어가 지닌 강력한 특징을 살려내는 프레임워크
- 좋은 객체 지향 어플리케이션을 개발할 수 있도록 도와준다
* API사용을 잘 하는 것이 스프링을 잘한다는 의미가 절대 아니다*
그렇다면 좋은 객체 지향 프로그래밍이란 무엇일까?
1. 핵심 키워드는 다형성
이해하기 쉽게 설명하면 역할이 interface고 이를 구현한 것이 개체이다. 이를 통해(구현한 개체들) 클라이언트에게 영향을 주지 않고 확장(새로운 기능 제공)을 할 수 있다.
자동차 역할(inteface)를 따르기만 한다면 얼마든지 자동차 구현을 할 수 있고 운전자는 이를 따라 구현된 자동차 개체들을 이용할 수 있다.
다른 예시를 들어보자
두 배우의 역할을 저 두 배우가 아니더라도 다른 배우들을 통해 대체할 수 있으며 대체가 가능해야만 한다. 이것이 바로 유연하고 변경에 용이하다는 의미를 나타낸다.
즉 역할(interface)과 구현(class or 객체)으로 구분하면 단순,유연,변경 편리라는 장점을 취할 수 있다.
클라이언트 입장에서 얻을 수 있는 장점들은 다음과 같다.
- 대상의 역할(interface)만 알면된다
- 구현 대상의 내부 구조를 몰라도 된다
- 구현 대상의 내부 구조가 변경되어도 영향을 받지 않는다
- 구현 대상 자체를 변경해도 영향을 받지 않는다.
하지만 한계점도 존재할 수 밖에 없다. 한계점은 다음과 같다
- interface 변경 시, 클라이언트, 서버 모두에 큰 변경이 발생한다
2. SOLID
SRP : 단일 책임 원칙
- 한 클래스는 하나의 책임만 가져야 한다
- 변경이 있을 때 파급효과가 적어야 한다
OCP : 개방-폐쇄 원칙
- 확장에는 열려 있으나 변경에는 닫혀 있어야한다
- 이를 위해 DI, IOC컨테이너가 필요하다
LSP : Liskov 치환 원칙
- 하위 타입의 인스턴스로 바꿀 수 있어야 한다
- 하위 클래스는 인터페이스 규약을 다 지켜야 한다
ISP : 인터페이스 분리 원칙
- 적당한 크기의 인터페이스를 분리하여야 한다
DIP : 의존관계 역전 원칙
- 구현 클래스에 의존하지 말고, 인터페이스에 의존하라(추상화에 의존해야한다. 구체화에 의존X). 즉 역할에 의존해야함을 의미한다
하지만 다형성만으로는 위의 것들을 가능하게 할 수 없다.
이를 가능하게 하기 위해서 사용되는 것들에는 DI, DI 컨테이너 등이 있다
이제 코드를 통해 직접 관련 내용들을 알아볼 차례다.