스프링은 왜 어려운가?
대한민국은 자바로 대동단결이 되어있다. 국가에서 발주하는 프로젝트가 모두 전자정부프레임워크라는 것을 사용하게 되어있고 전자정부 프레임워크 내에 중추적인 역활을 스프링이 하고 있기 때문에 전자정부프레임워크를 한다는 것은 스프링 프레임워크를 사용한다는 것이 된다.
개인적으로 국가의 입장에서는 꾀나 성공한 사업이라고 생각한다. 이전까지는 개발사마다 국가의 SI 사업에 각자의 기술 각자의 소스를 가지고 와서 개발을 하였기 때문에 어찌보면 프로젝트를 하고 난 뒤 국가기관이 개발사에 락인이 되어 주객이 전도되는 상황이 발생하는 경우가 빈번하였다고 한다. 하지만 전자정부프레임워크 기반으로 모든 개발을 진행하게 되니 어찌되었든 소스의 큰 틀과 구조는 같은 상황이 생기게 되었고 그런 락인 효과에서 벗어나는 역활을 했다고 생각한다.
국가기관이 선택하고 국가에서 직업교육으로 양성성하여 개발자까지 끌어 들이니 밀어주고 당겨주고 하여 정책적인 부분은 어디까지나 성공한 것으로 보인다. 하지만 무분별하게 양상되고 개발자 시장에 흘러들어가 프리렌서활동을 하는 등으로 전체적인 개발자 수준은 낮게 만들었지만 정부의 간지러운 부분은 긁어졌으니 무엇인가 해결은 된 것 같다.
여튼 이렇게 스프링은 대한민국에서 자바개발자라면 누구나 써야되고 쓰고 있고 쓸 수 있는 프레임워크가 되었다. 자바개발자중에 스프링을 안쓰는 사람을 찾기 힘든 상황이 되어버렸는데...
과연 스프링은 잘 다룰 줄 아는가? 라는 부분에서 대해서는 의문을 가지고 싶다. 닷넷개발자로 살다가 향수병 때문에 고향에 내려와서 정부 SI 사업을 하는 회사에 다니면서 자바를 처음 접하였다. 스프링을 공부하면서 개발을 했는데 나에게는 스프링은 상당이 어려운 녀석이였다. 일단 설정부터가 만만하지 않았는 고행의 연속이였다. (이후 스프링 부트가 나왔는데, 자바진영에서는 이렇게 좋아졌다! 라고 반겼는데 나의 생각은 이런게 왜 이제 나오지? 오히려 복잡한 설정이 방식이 뒤에 나와야되는데...)
이렇게 스프링을 조금씩 알아 가게 되었을 때, 재미있는 사실을 알게 되었다. 많은 개발자들이 스프링을 왜 쓰는지 모르고 있다는 것이다. 특히 SI 프리렌서 시장에 있는 개발자들에게 '스프링을 왜 써요?'라고 질문을 하면 대답을 제대로하는 개발자를 본적이 없다. 대부분 미사어구를 넣은 형용사가 남발하는 수식어 때문에 쓴다고 하는 말만 장황하게 하였다. 대충 이런식 '효율적으로 코드를 관리할 수 있고 사용이 쉽고 어쩌고 저쩌고 이쁘고 아름다워서 씁니다' 라고 말하는 식이다.
내가 생각했을때 스프링 프레임워크를 상당히 어려운 프레임워크이다. 스프링을 왜 사용하는지를 알게 되면 어려워 질 수 밖 없다는 것을 조금 이해하게 될 것라 본다.
1. 의존성 문제
객체지향 프로그래밍을 하면 객체와 객체가 관계를 맺으며 처리가 되는 것이 대다수이다. 때로는 어떤 객체의 안에서 다른 객체를 생성하기도 하는데, 이런 상황은 객체지향 설계 5대원칙이라는 SOLID 원칙중에서 D(Dependency Inversion Priciple:의존관계역전원칙)를 위배하는 상황이 발생한다. 이 원칙을 위배하는 것이 무슨 형법을 위배하거나 그런 것이 아니라. 저 원칙을 위배하게 될 경우 코딩을 하면 할 수록 복잡하게 되어지는 상황이 오게 된다는 것이다.
객체 안에서 객체가 생성될 경우 생성되어야되는 객체 클래스가 다른 클래스로 변경이 된다면 그 객체의 생성 코드는 모두 변경되어야되는 상황이 발생된다. 이런 상황을 강한결합(Tight coupling)이라고 하는데 소스코드가 강하게 결합하게 된다는 것은 의존성에 엮인다는 것이다. 한쪽을 수정하면 다른 쪽도 같이 수정이 동반되어야되는 이런 상황을 이야기하는 것이다. 이런 상황은 코드가 변경될 때마다 같이 변경을 수반함으로 좋지 않은 상황이 된다. 그래서 코드는 느슨한 결합(loose coupling)이 이루어지도록 개발하는 것이 좋다고 권한다.
2. Factory 패턴
객체지향 설계를 하다보면 반복적인 객체와의 관계를 이런 식의 패턴으로 만들면 이런 상황에서는 이런 문제를 해결 할 수 있습니다. 라고 우리보다 선배 개발자가 'GoF의 디자인 패턴'이라는 책으로 발표를 하였다. 이 책에서 패턴을 크게 '생성, 구조, 행위'라는 3분류로 나누어서 23가지 패턴을 다루고 있는데 이중에 객체 생성과 관련된 Factory 패턴이 있다.
팩토리 패턴의 구현 방법은 인터넷에 많이 다루므로 코드는 표기하지 않겠다. 팩토리 패턴이 하고자 하는 것 객체가 필요한 부분에서 팩토리에게 객체생성을 미룸으로서 어떤 객체가 생성되는지는 팩토리가 다루게 함으로서 객체 생성의 끈끈한 결함을 끊어서 코드를 변경에 유연하게 대처할 수 있도록 바꾸는 것을 목표로 하는 것이다.
그래서 객체지향설계를 하게 되면 프로젝트내에 팩토리 패턴을 많이 구현해두게 되는 것이다.
3. 스프링 기능 중 최고의 기능
스프링 프레임워크가 제공하는 많은 기능 중에 가장 많이 쓰며 스프링을 대표할 수 있는 기능이라고 한다면 누구든 주저 없이 'IoC 컨테이너 기능' 이라고 말 할 것이다. 바로 이 기능이 팩토리기능을 별도로 코드로 구현해두지 않아도 사용할 수 있도록 해주는 기능이다.
코드로 본다면 @Autowired라는 어노테이션으로 인터페이스나 클래스를 선언하면 스프링이 실행시점에 컴포넌트 스캔을 통하여 객체생성을 자동으로 해서 의존성을 해결 해주는 기능이다.
그래서...
스프링이 어려운 이유는 스프링 최고의 기능인 IoC 컨테이너 기능을 이해하고 체득하기 위해서 일련의 과정이 필요하기 때문이다. 일단 객체지향을 다룰 줄 알아야하며, 객체지향 설계를 하다가 매우 호된 맛을 본 경험있어야 한다.(이과정은 생략될 수 있다) 의존성이 높아져서 상황이 꼬여가는 상황을 맛보다 보면 이 해결점을 찾게 될 것이다. 그럼 선배개발자들의 해결제안인 '디자인패턴'을 볼 수 밖에 없으며 'SOLID 원칙'을 알 수 밖에 없다. 그러다가 IoC/DI 에 대해서 알게 되고 그걸 해주는 컨테이너 역활을 하는 프레임워크로 유명한 스프링이 있구나라는 결론에 도달하는 것이다.
이런 컨테이너 라이브러리는 꼭 스프링만 있는 것이 아니다. 다른 라이브러도 있으며 다른 언어에도 오픈소스로 많이 존재한다. 한가지 확실한 것은 이런 컨테이너류를 왜 써야하는지 당위성을 찾게 되면 한번도 안 쓸 수는 없지만 한번만 쓸수는 없다는 것이다.
나는 닷넷에서 AutoFac, Unity, CastleWindsor까지 사용하고 있다. 정말 미려하게 사용하는 것은 아니지만 항상 구현해야되는 팩토리와 싱글턴 구현이 없어지는 점 그리고 의존관계 없이 깔끔한 코드가 작성되는 것을 보게 된다면 더듬더듬어서라도 쓸 수 밖에 없었다.
스프링 그냥 쓰기만 하고 왜 쓰는지 이유를 모른다면 다시 한번 스프링 프레임워크에 대해서 공부해볼 필요가 있다고 본다. 물론 스프링이 컨테이너 역활만 하는 것이 아니다. 그외 다른 기능들까지도 정말 대단한 것을이 많이 있다. 객체지향 프로그래밍에서 간지럽던 많은 부분을 해결해주는 좋은 프레임워크이기 때문에 수많은 사람들이 쓰고 있고 발전해나가고 있다.