수업 내용들을 들으면서 메모 했던 것을 정리한다.
스프링이라는 프레임워크는 하나의 함수이고 도구라고 생각한다.
왜 도구인가? 개발자들이 귀찮은 작업들을 하지 않고 개발에만 신경쓸 수 있도록 도와주기 때문이다.
왜 함수인가? 우리가 원하는 값을 요청하면 스스로 뚝딱뚝딱 원하는 값을 주는 모양새이기 때문이다.
먼저 발전이 어떻게 이루어졌는지 이해하는 과정을 적어보려고한다.
스프링으로의 발전 역사를 탐구하면서 이해해보도록 하자.
미리 알아야 할것은 다음 시간적 흐름에 등장하는 개발자들은 굉장히 귀차니즘이 팽배한 인간들임을 알리고 시작한다.
버전 1.1
처음 개발자들이 개발할때에는 의존이라는 개념이 없었다. 다형성 조차도 생각을 못했을 때이다.
의존이고 뭐고 다 내려놓고 생각해보자.
어떤 객체가 다른 객체를 쓰려고 한다
그러려면 사용하고자 하는 대상을 new 연산자을 통해 만들어야 했다.
예를 들어 Car 라는 객체가 있고, 이 객체는 타이어라는 객체를 의존하고 있다고 생각해보자.
버전 1에서는 Car 객체가 타이어 객체를 직접 new를 통해 생성해서 끼워주어야 했다.
ex) class Car {
HankookTire tire= new HankookTire();
roll(HankookTire tire){}; // 차의 메소드, 한국 타이어를 매개변수로 한다
}
버전 1.2
그렇게 개발을 하다보니 타이어라는 객체가 한국타이어도 있고, 금호 타이어도 있는데 매번 다른 타이어를
끼우려고 하니 문제가 생겼다. 매번 직접 Car 객체로 가서 타이어에 대한 부분을 죄다 수정해주어야 했다.
이는 인터페이스를 통한 다형성 개념을 통해 해결되었다.
ex) class Car {
//HankookTire tire= new HankookTire(); 매번 주석처리 하기도 불편하니....
GumhoTire tire = new GumhoTire(); // 금호타이어로 바꿔주었다!
roll(HankookTire tire){}; // 앗... 금호타이어로 또 바꿔주어야 하잖아... ㅜㅜ
}
-> 개선!
ex) class Car {
Tire tire = new HankookTire();// 한국타이어는 안쓰니까 주석처리하고,
Tire tire = new GumhoTire();
roll(Tire tire){};
/* 인터페이스를 사용해서 귀찮은 작업량이 많이 줄어들었다.(실제로 이런 메소드같은 것들이 수십개 있다고 생각해본다.)*/
}
버전 2.1
하지만 번거로움은 가시지 않았다. 왜냐하면 인터페이스를 통해 타이어에 대한 부분을 고치는 작업량 자체는 많이 줄어들긴 했지만 이래나 저래나 Car 객체로 가서 어떤 타이어를 쓸것인지에 대해 명시를 해주어야
했기 때문이다.
버전 2로 와서 개발자들은 차를 직접만들 것이아니라 조립공장을 세우는 것을 생각해낸다.
이것이 무슨 말인고 하니,
예를 보도록 하자
ex) class Car {
Tire tire = new HankookTire();// 주석 처리를 하던지 해서 하나만 선택해야 한다
Tire tire = new GumhoTire();
roll(Tire tire){};
}
-> 개선!
class Factory{
Tire tire = new GumhoTire(); // 타이어 생성
Car car = new Car(tire); // 차 객체 생성 -
}
어떤 점이 개선되었나? 바로 차를 생성할때에 타이어를 넣어주었다. Car 객체는 생성자에 타이어를 매개변수로만 지정하면 되는 것이다. 이것은 타이어를 변경할때에 직접 차객체로 갈 필요가 없어지게 되었다.
클래스가 하나 더 생기기 했지만 수많은 객체를 관리하기에는 더할 나위 없이 편해졌다.
버전 2.2
생성자를 매번 생성하는 것보다는 흔히 사용하는 세터메소드를 이용하는 것이 더 유연했기에,
개발자들은 세터, 게터메소드를 통해 필드값들을 다루었다.
접근자는 private 로 규약을 걸어둠으로써 보안적인 측면에서도 훨씬 강화되었다. (정보은닉)
버전 3
개발자들이 공장을 여러군데 세워놓기 시작했다. 그러다보니 과거와 같은 문제점이 발생하기 시작했다.
개발 규모가 커지면 커질수록 공장이 여러군데 생기게 되었고, 유지보수를 하기위해서는 이 공장 저 공장 여기저기 떠돌아다니기 시작한 것이다.
개발자들은 공장을 초월하는 공장, 빈 컨테이너라는 것을 만들기로 한다.
하나의 컨테이너는 다루고자하는 객체들을 빈이라고 부르기로하고 그것들을 싹다 긁어모아서
자신의 내부에 쌓아두기 시작했다.
개발자들은 유지보수를 하기위해 이곳 저곳 떠돌지 않고 큰 창고로가서 볼 수 있으니 아주 편했다.
객체를 실제 생성하는 곳이 컨테이너 한곳이 된것이다.
도구로서의 프레임워크의 탄생 순간이었다. (아직은 초기단계지만...)
특히 웹에서는 이 컨테이너를 어플리케이션 영역에 둠으로써 그 관리영역이 명확해졌다.
버전 4
개발자들이 요로코롬 살펴보고 있자니 컨테이너영역에서 조립을 해줄때에는 자신들이 개입해야하는 번거로움이 남아있었다.
개발자들은 매우 게으른 사람들이었다. 창고가 객체들을 죄다 끌어모으고 있긴 했지만
결국에는 개발자들이 하나하나 객체들을 가져와서 스스로 조립해야 하는 귀찮음이 있었다.
개발자들이 누구인가, 귀찮은 반복작업은 컴퓨터에게 위임해버리는 악덕 지주같은 사람들이었다.
우리 착한 컴퓨터들은 프로그래밍 되어진대로 작업을 하기 시작했다.
여기서는 Reflection API가 사용되어지는데 조금은 어려운 내용이니 돌아가는 과정은 축소해서 생각한다.
Reflection의 사전적 뜻은 거울에 비친 상, 반영 이란 내용인데, 즉 객체 내부를 들여다 본다는 의미로 생각하면 된다.
개발자들은 먼저 객체를 사용하는 객체와 사용되어지는 객체로 나누었다.
그리고 데이터 바인딩이라는 것을 쓰는데, 대화로 간략히 표현하였다.
--
개발자가 다른 객체를 사용하고자 하는 객체에게 먼저 물어본다
개발자 : 어떤 것이 필요해?
사용하는 객체 : 저는 타이어가 필요해요!
개발자: 알았어 , 야 여기 창고 안에서 타이어라는 이름 가진놈 후딱 나오도록 하자!
사용되어지는 객체 : 저요, 저 여기 있어요
개발자 : 응 일루와 너 쟤한테 들어가
사용되어지는 객체 : 넵.
개발자: 야 컴퓨터야 봤지 ? 이제 니가 해
컴퓨터 : 넵
--
객체가 다른 객체를 사용하는 것을 어려운 말로 의존이라고 한다.
그리고 위 대화에서 개발자가 객체를 불러다가 사용하고자 하는 객체에 넣어주는 과정을 의존주입이라고 한다.
그리고 개발자는 이 과정을 프로그래밍해서 컴퓨터에게 넘겨주었다.
우리가 알고 있던 창고는 이제 창고이자 의존주입까지 해주는 조립공장으로서의 역할도 하게 되었다.
개발자들은 이러한 컨테이너를 IOC 컨테이너라 불렀다.
IOC는 Inversion of Controll의 약자로서 제어의 역전. 즉 , 과거에는 개발자들이 직접 의존 주입에 대한 제어권을 가지고 있었는데 이제는 컨테이너가 그러한 작업들을 자동으로 해주게 된것이다.
창고기능 말고도 조립까지 해주는 도구. 얼마나 편한지...
이것을 웹의 MVC 관점에서 보게 된다면
1. View 영역에서 클라이언트가 정보를 요청한다. (파라미터로 1,2,3이 같이 들어온다 생각하자)
2. DispatcherServlet 에서는 해당 요청을 분석하고 요청에 알맞는 Controller를 불러온다.
3. 그리고 빈 컨테이너 영역에서 Controller 에게 서블릿이 물어본다.
4 .뭐가 필요해? / 나는 00이 필요해!
5. 서블릿은 물어본 내용을 토대로 View에서 넘어온 값들을 하나의 객체로 만들어서 컨트롤러에게 보내준다. (1,2,3 을 00에 담는 것이라 생각한다)
6. 컨트롤러는 값이 채워진 00을 토대로 로직을 수행하고 요청에 대응하는 값을 서블릿에게 보내주고, 필요하다면 어느 뷰로 보여줄지에 대한 값도 보내준다.
7. 서블릿은 받은 값을 뷰 페이지에 뿌려주고 완성된 페이지를 클라이언트에게 보내준다.
-- 위 과정을 보면 개발자가 담당하는 곳은 단 두곳뿐이다. 데이터를 어떻게 처리할지에 대한 컨트롤러와 처리된 데이터를 어떻게 보여줄지에 대한 뷰 페이지.
내가 글 서두에 함수로의 프레임워크라고 한 부분이 바로 이점이다. 클라이언트에서 어떤 값을 넣어주기만 하면 알아서 컨트롤러에게 가공된 값을 뱉는다. 컨트롤러가 다시 그것을 클라이언트에게 보내줄때에는 가공된 값을 넣어주기만 하면 알아서 뷰페이지를 만들어서 보내준다.
View FrameWork(request) {
result = Controller(request);
return result;
}
요런 느낌이랄까.
---------------------------------------------------
스프링이 발전한 느낌적인 느낌을 시간적 흐름을 통해 알아보았다.
데이터 베이스 관련 프레임워크인 마이바티스가 스프링과 만나면서 더욱 더 편리해졌다.
먼저 마이바티스의 작업을 간략히 표현하면 다음과 같다.
SQL들을 따로 xml 파일에 두고 DAO 객체의 메소드들과 하나하나 매핑시켜주는 역할.
스프링은 마이바티스까지 흡수하면서 데이터베이스 관련 객체들과 매퍼 객체들을 품었고
@ 어노테이션으로 만으로도 간단히 컨테이너 안에서 의존주입이 되도록 만들었다.
--
나중에 기회가 된다면 더 자세하게 , 그림들이나 동영상 강의 등을 만들어 봐야겠다.
댓글
댓글 쓰기