ajax로 검색한 결과 :: 시소커뮤니티[SSISO Community]
 
SSISO 카페 SSISO Source SSISO 구직 SSISO 쇼핑몰 SSISO 맛집
추천검색어 : JUnit   Log4j   ajax   spring   struts   struts-config.xml   Synchronized   책정보   Ajax 마스터하기   우측부분

회원가입 I 비밀번호 찾기


SSISO Community검색
SSISO Community메뉴
[카페목록보기]
[블로그등록하기]  
[블로그리스트]  
SSISO Community카페
블로그 카테고리
정치 경제
문화 칼럼
비디오게임 스포츠
핫이슈 TV
포토 온라인게임
PC게임 에뮬게임
라이프 사람들
유머 만화애니
방송 1
1 1
1 1
1 1
1 1
1

ajax로 검색한 결과
등록일:2008-03-16 15:51:38
작성자:
제목:[프레임워크 전략 ⑤] 대안 언어 프레임워크 활용 전략


흔히 인터넷을 바다와 비유하곤 한다. 웹 애플리케이션의 개발은 끝도 보이지 않는 넓은 바다의 자원을 이용하기 위한 시도이기에, 그리 녹록한 작업이 아니다. 노 젓는 법을 겨우 배운 풋내기 뱃사공이 작은 돛단배에 몸을 싣고 바다로 향하는 것은 누가 보아도 무모한 짓이다. 바다를 항해하는 것조차 이리 어려운 일인데, 그 바다에 크고 튼튼한 구조물을 짓는 일이야 두말할 필요 없을 것이다. 특집 5부에서는 웹 애플리케이션 개발에 사용할 수 있는 프레임워크인 장고와 씨사이드의 활용법에 대해 알아본다.

웹 개발자들의 가장 큰 숙제는 바로 쉽고 빠르게 안정적인 웹 애플리케이션을 개발하는 것이다. 루비 온 레일즈를 필두로 하는 빠른 웹 개발 프레임워크들 가운데 장고(Django)는 파이썬으로 만들어진 웹 프레임워크이다.

장고는 웹 개발에서 반복적으로 사용해야 하는 패턴을 제공할 뿐 아니라 똑똑한 기본값(Default)을 제공하여 최소의 설정으로 웹 사이트를 구현할 수 있도록 지원하는 특징을 가지고 있다.

5부에서 함께 알아볼 씨사이드(Seaside)는 스몰토크(Smalltalk) 기반의 웹 개발 프레임워크이다. 스몰토크는 굉장히 쉽고 간결한 언어이지만 국내에 자료가 많지 않은 탓에 어려운 언어라는 오해를 받고 있다. 여러 가지 예제들을 통해 스몰토크에 대한 오해를 풀고, 씨사이드의 매력에 흠뻑 취해보자.

장고(Django)

사실 파이썬은 더 이상 대안 언어라고 부르기 어색해진 언어다. 이미 파이썬의 쉽고 강력함에 매료된 구글을 비롯한 여러 기업들이 파이썬을 사용하고 있고, 점점 더 그 사용빈도가 높아지고 있는 탓이다.

실제로 지난 2006 대안 언어 축제에도 많은 참가자와 발표자들이 파이썬에 높은 관심을 보였다. 또한 그 강력함 덕에 이제는 프로토타입용 언어라는 꼬리표도 떼어 버린 상황이다. 많은 실험용 코드들이 몇몇 수정만으로도 실제 서비스에 이용되기도 한다. 여기에서 알아볼 장고는 바로 파이썬 사용자들을 위한 웹 프레임워크이다.

장고는 미국의 온라인 신문사인 월드 온라인(World Online)에서 처음 시작되었다. 2003년 가을, 계속되는 뉴스 기사들의 추가와 새로운 콘텐츠의 제공 요구, 다가오는 데드라인 등의 압박에서 벗어버리고자 시작된 프로젝트였다.

아드리안과 사이몬이란 두 개발자는 여러 문제점을 해결하기 위해 기존에 사용하던 PHP를 벗어버리고, 파이썬으로 웹 사이트를 구현하기로 결정했다.

그리고는 2년 뒤인 2005년 여름, 구현된 웹사이트의 재사용된 부분들을 오픈 소스로 공개하기로 하고, 이름을 장고로 지은 것이다. 사실 장고란 이름은 아드리안이 좋아하는 재즈 기타리스트인 Django Reinhardt의 이름에서 따왔다.

웹사이트에 사용된 오픈소스 소프트웨어들인 아파치와 PostgreSQL, 파이썬이 없으면, 장고도 의미가 없다는 생각에 개발자들은 장고 역시 오픈소스로 추진하였다. 또 이러한 일련의 작업들을 그들 스스로 자랑스러워했다.

그 덕분에 우리도 이처럼 좋은 프레임워크를 자유롭게 쓸 수 있게 된 셈이다. 오픈된 장고는 전 세계의 개발자들의 노력이 더해져 더욱 더 발전하게 되었다. 장고는 월드 온라인에서 3년간 방대한 트래픽들을 처리하면서, 안정성을 인정받았다.

또, 폭주하는 요청들에 대한 다양한 분산 요구사항들도 만족하면서 실용성을 높였다. 무엇보다도 장고의 주요목적인 쉽고, 빠른 웹 사이트 개발 환경은 많은 개발자들을 매료시키기에 충분했다. 워싱턴포스트를 비롯한 주요 신문사 웹사이트들이 앞 다퉈 장고를 사용하기 시작하면서 다양한 웹 애플리케이션들을 위한 웹 프레임워크로 자리매김하게 되었다.

파이썬과 같은 스크립트 언어로 웹 애플리케이션을 만드는 일은 몇 가지 문제들로 인해, 그 실용성에 많은 문제가 제기되어 왔다. 매 요청마다 그때그때 인터프리터가 메모리로 올라와야 했고, 그로 인한 성능 저하를 감수해야만 했다. 이를 피하기 위해서 다양한 방법들이 고안 되었지만, 어느 것 하나 개발자들의 고민을 시원하게 해결해 줄 수 있는 방법이 없었다.

올해 10월 공개된 파이썬 2.5는 다양한 방법들에 대한 공통된 API인 WSGI(Web Server Gateway Interface)를 지원한다. 장고는 그 이전부터 WSGI를 자체적으로 제공하여, 다양한 웹 환경에서의 동작을 가능하게 하였다.

이를 테면, 아파치와 mod_python을 이용한다던가, 아파치와 FastCGI를 혹은 파이썬 비동기 네트워크 프레임워크인 Twisted의 web2를 이용하는 등의 작업이 모두 가능하다.

근래의 소프트웨어들은 그 설계에 있어서, 모델(데이터)과 뷰(보여주는 방법)를 분리하는, MVC(Model View Controller) 패러다임의 방법을 자주 이용해 왔다.

웹 프레임워크도 이 개념을 이용하여, 웹 개발을 모델(데이터베이스)과 뷰(HTML, CSS)를 적절히 분리하고, 이를 적절히 연결하는데 주안점을 두고 있다. 장고의 MVC 개념도 이와 유사한데, 약간은 다른 용어를 사용하고 있다.

장고의 MVC


• 모델(Model) : 구조화되는 데이터. 객체와 관계 데이터베이스를 연결하여, ORM(Object-relational mapping)이라고도 한다.
• 뷰(View) : URL 요청별로 데이터를 준비하는 역할을 한다.
• 템플릿(Template) : 뷰에 준비된 데이터를 어떻게 보여줄 것인가에 대한 역할을 한다.




장고에서는 뷰가 컨트롤러의 역할과 유사하고, 템플릿이 뷰의 역할과 유사하다. 이처럼 다른 용어를 사용한 이유는 뷰의 개념을 어떻게 보여줄지 보다는 어떤 데이터를 준비할 것인가에 대한 역할을 강조하기 위해서이다. 그래서 혹자는 장고의 MVC를 MTV(Model Template View)라고 이야기하기도 하지만 그다지 중요한 차이는 아니다.

여기서, 또 다른 파이썬의 웹 프레임워크 가운데 하나인 터보 기어(Turbo Gears)와의 차이점을 볼 수 있다. 터보 기어는 각 요소별로 기존에 존재하는 파이썬 라이브러리를 이용하였고, 그것들을 조합한 반면 장고는 각각을 직접 구현하였다.

장고 개발자들은 기존에 존재하던 도구들의 조합보다는, 빠른 웹 사이트 제작을 위한 보다 더 최적화된 직접적인 구현을 선호하였던 셈이다.

장고의 중요한 특징 중 하나는 관리자 웹 인터페이스가 자동으로 제공된다는 점이다. 보통 웹 애플리케이션을 작성할 때 관리자 인터페이스는 꼭 필요한 것이면서도 일반적 기능과도 많이 중복되어 구현이 번거로웠던 것이 사실이다.

사용자 관리, 사용자 그룹관리, 사용자 별 권한(permission)에 대한 것뿐 아니라, 각각의 모델객체에 대해서, 목록/추가/삭제/변경의 기능이 관리자 인터페이스에서 모두 제공된다.

그 덕에 데이터베이스나 웹 애플리케이션을 실험적으로 작성하기에 아주 편리하다. 데이터베이스 모델링만으로(models.py 파일을 작성하는 것만으로) 웹 애플리케이션의 작동을 실험해 볼 수 도 있다. 생물 정보 관련 업무를 수행하는 필자 역시, 이 방법으로 데이터베이스화해야 할 많은 정보들을 별다른 수고 없이 관리하고 있다.

그 밖에 세련된 URL 설계와 디자이너에게 친숙한 템플릿 기능도 장고의 특징 중 하나이다. 가끔씩 게시판이나, 메신저 등에서 보이는 하염없이 길기거나, ‘?a=b&c=d’ 등과 같이 깔끔하지 못한 URL은 장고로 만든 웹 애플리케이션에서는 찾아볼 수 없다.

URL을 해석하는 부분에 정규식(Regular expression)을 사용하여, 개발자는 원하는 어떤 형태로든 URL을 설계할 수 있다. 구조화되고 이해하기 쉬운 URL의 설계가 웹 애플리케이션의 전체적인 구조를 가늠하게 한다는 점을 생각해 볼 때, 이는 매우 반가운 기능이다.

템플릿 기능은 다른 웹 프레임워크들 역시 가능한 한 쉽고 빠른 웹 디자인을 할 수 있도록 하기 위해 노력하는 부분이다.

장고도 비 XML을 사용한다던가, 템플릿 태그를 확장 가능하도록 하는 등의 방법들을 통해 이를 지원하고 있다. 얼마 전 파이썬 창시자 귀도는 장고의 템플릿 기능이 타 프레임워크에 비해 더 세련되었다고 이야기한 바 있다. 그 외에도, 폭주하는 요청들을 처리해야 하는 대형 웹 사이트들을 위한 최적화된 캐시(cache) 프레임워크가 제공되어 있다.

그 덕에 메모리상의 캐시, 파일시스템 캐시, 데이터베이스 캐시 및 분산화 방법 등을 통해 높은 성능을 발휘할 수 있다. 국제적인 웹 사이트를 위한 국제화(Internationalization) 지원도 충분하게 이루어지고 있다. <그림 1>은 장고의 일반적인 웹 요청 처리 절차를 설명하고 있다.
<그림 1> 장고의 일반적인 웹 요청 처리 절차

웹 브라우저에 입력된 URL(request)은 URL resolver에서 해석하여 적절한 뷰로 넘긴다. 뷰는 모델과 함께 데이터를 준비하고, 템플릿과 함께 어떻게 보여줄 지를 결정한 뒤에 웹 브라우저로 결과(response)를 보낸다.

<그림 1>에서 동그랗게 색칠된 부분은 미들웨어 역할의 콜백 함수로써 요청 결과(response)를 직접 조작한다. 이는 웹 로봇 요청은 뷰까지 보내지 않도록 한다던가, 모델에서 중요한 정보는 결과로 내보내지 않도록 하는 등의 작업을 가능하게 한다.

장고로 블로그 만들기

지금까지 장고의 특징들에 대해 알아봤다. 이제, 직접 간단한 블로그를 만들어 봄으로써, 장고의 내부를 들여다보도록 하자. django-admin.py로 프로젝트를 하나 만들고, 그 안에 blog 애플리케이션을 만들자. 블로그는 저자가 글(포스트)을 쓸 수 있고, 방문자가 코멘트를 달 수 있다. 각 포스트는 태그를 가진다.

데이터 모델링
블로그 애플리케이션의 모델은 포스트와 코멘트, 태그로 나뉜다. 각 요소는 1:다, 다:다 관계를 갖는다. 글 하나에 여러 개의 코멘트가 달릴 수 있고, 여러 개의 태그가 붙어있을 수 있으며, 각 태그는 여러 개의 포스트에 등록될 수 도 있기 때문이다. 이를 models.py에 기록하면 <리스트 1>과 같다.


<리스트 1> models.py 예제


from django.db import models

class Post(models.Model):
title = models.CharField(maxlength=200)
content = models.TextField(maxlength=2000)
ctime = models.DateTimeField(auto_now_add=True)
mtime = models.DateTimeField(auto_now=True)
is_public = models.BooleanField()
tags = models.ManyToManyField('Tag')

class Comment(models.Model):
post = models.ForeignKey(Post)
who = models.CharField(maxlength=30)
content = models.TextField(maxlength=1000)

class Tag(models.Model):
name = models.CharField(maxlength=30)





필자는 예전에 객체지향 프로그래밍을 익히면서 객체를 관계형 데이터베이스 레코드와 어떻게 연결할 것인가에 대해 오랜 고민을 한 적이 있다. 다양한 시도들을 해봤으나 좀처럼 매끄러워 지지 않았다.

반면에 장고의 모델 코드는 가장 파이썬답게 객체를 데이터베이스 레코드와 연결하고 있다. 사실 이것은 프레임워크를 쓰는 또 다른 이유이기도 하다. 직접 구현의 방법도 있지만, 경험 많은 개발자들의 검증되고 안정된 방법들을 손쉽게 쓸 수 있다는 사실은 프레임워크의 노칠 수 없는 매력이다.

URL 설계
‘http://yourdomain.com/post’로 모든 포스트 목록들을 보고, ‘/post/1’(포스트 아이디)로 특정 블로그의 내용을 보고 싶다. 그리고 ‘/admin/’ 으로 관리자 페이지에 가고 싶다면 urls.py를 <리스트 2>처럼 작성하면 된다.


<리스트 2> urls.py 예제


from django.conf.urls.defaults import *

urlpatterns = patterns('',
(r'^post/$','blog.views.post_list'),
(r'^post/(?P\d+)/$', 'blog.views.post_detail'),
(r'^post/(?P\d+)/comment/$', 'blog.views.add_comment'),
(r'^admin/', include('django.contrib.admin.urls')),
)





장고는 urlpatterns에 매칭 되는 패턴이 없으면 ‘HTML 404 페이지 없음’ 오류 페이지를 출력한다. 각각의 URL 패턴들은 두 값을 가진 튜플들로 구성되어 있다. 앞의 것은 정규식 패턴이고, 뒤의 것은 해당 URL에 연결될 뷰이다. 정규식 패턴을 보면, 각각의 포스트를 보기 위해 패턴 가운데 post_id가 숫자 형태로 전달됨을 알 수 있다.

include함수는 URL 정의를 하위 urls.py에 일임하고자 할 때 사용한다. <리스트 2>에서 ‘/admin/’ 이하의 모든 URL 패턴들은 장고에서 제공되는 admin.urls에서 처리함을 알 수 있다. add_comment 뷰는 코멘트를 입력하는 부분에 사용된다.

뷰 만들기
위 URL 설계에 의하면 post_list와 post_detail, 두 개의 뷰와 코멘트 입력을 담당할 add_comment 뷰가 필요하다. post_list는 목록을 보여주는 역할을 하고, post_detail은 특정 포스트를 보여주는 역할을 한다. 이들은 views.py에 <리스트 3>처럼 작성된다.


<리스트 3> views.py 예제


from django import forms
from django.http import HttpResponseRedirect
from django.shortcuts import render_to_response
from blog.models import Post, Comment

def post_list(request):
return render_to_response('post_list.html', {
'posts' : Post.objects.order_by('-ctime')[:5],
})

def post_detail(request, post_id):
post = Post.objects.get(id=post_id)
return render_to_response('post_detail.html', {
'post' : post,
'comments' : post.comment_set.all(),
'comment_add_form' : forms.FormWrapper(Comment.AddManipulator(), {}, {}),
})

def add_comment(request, post_id):
manipulator = Comment.AddManipulator()
comment_data = request.POST.copy()
comment_data['post'] = post_id
manipulator.do_html2python(comment_data)
manipulator.save(comment_data)
return HttpResponseRedirect("../")





render_to_response 함수의 두 인수 가운데 앞엣것은 해당 뷰를 어떻게 보여줄 지에 해당하는 템플릿 파일을 지정하는 것이다. 두 번째 인수는 그 템플릿에 전달할 컨텍스트(데이터)이다. ‘Post.objects.order_by(‘-ctime’)[:5]’는 Post 테이블에서 최근 다섯 개의 목록을 가져오는 구문으로 SQL로 표현하면 ‘SELECT * FROM Post ORDER BY ctime DESC LIMIT 5’이다.

‘[:5]’ 부분만을 보고 SQL LIMIT 구문을 쓰지 않고, 전체 리스트에서 슬라이싱 하는 것이 아닐까 하고 생각할 수 있을 것이다. 하지만, 모델 객체가 직접__getitem__ 메소드를 오버라이드하여 LIMIT 구문을 삽입하는 역할을 한다. 또한 특정 Post에 연결된 코멘트들은 comment_set 속성으로 접근할 수 있다.

코멘트 입력을 받기 위해 폼 데이터도 준비해야 한다. 장고의 AddManipulator는 모델 입력 용 폼을 위한 처리자로서, 입력 데이터가 올바른지 검증하는 역할까지 자동으로 수행한다.

템플릿 만들기
포스트들의 목록을 출력하는 템플릿 post_list.html은 <리스트 4>처럼 작성된다.


<리스트 4> post_list.html 예제


최근 5개 글 목록








{% %} 는 장고 템플릿에서 태그라고 말하는 것으로써 for와 if, ifequal 등의 제어 구문을 이용할 수 있다. {{ }} 안에는 View에서 넘겨준 변수를 적어주며, ‘.’ 이후에 해당 변수의 속성을 적어준다. 포스트의 상세 목록을 표시하는 템플릿 post_detail.html은 <리스트 5>처럼 작성한다.


<리스트 5> post_detail.html 예제


{{ post.title }}


{{ post.content }}



태그



{% for tag in tags %}
{{ tag.name }}
{% endfor %}



코멘트



    {% for comment in comments %}
  • {{ comment.content }} -- {{ comment.who }}

  • {% endfor %}











폼 부분을 보면 어떤 input 타입을 쓸지가 정의되지 않았음을 알 수 있다. input 타입은 별도의 정의를 하지 않아도 모델에서의 속성에 맞게 자동으로 만들어 진다.

동작 확인
이제 블로그가 다 만들어졌다. 글 쓰는 기능은 안 만들었다고? 아하, 글을 쓸 때는 장고의 관리자 모드를 이용하면 되겠다. URL ‘/admin/’ 으로 접속하면 <화면 1>와 같은 화면을 볼 수 있다.

웹 애플리케이션에서 자주 이용되는 User, Group 에 대한 기능들은 이미 만들어져 있음을 볼 수 있다. 각 모델에 ‘class Admin: pass’ 라는 속성을 추가하면 지금까지 설계한 블로그 모델도 입력할 수 있다.

<그림 1> 장고의 관리자 인터페이스

<화면 2>깔끔한 인터페이스의 관리자 화면. 사용자, 사용자 그룹 및 작성한 모델들의 목록/생성/수정/삭제 가 모두 가능하다

자, 이제 관리자 인터페이스에서 글을 쓰면 된다. URL ‘/post/’ 로 가면 최근 글 목록 다섯 개가 표시된다. 또, ‘/post/post_id’로 가면 포스트 내용이 표시되고, 코멘트도 입력 가능한 블로그 웹 애플리케이션이 완성되었다.

지금까지 별 다른 수고 없이 깔끔하게 데이터베이스 기반의 웹 애플리케이션을 만들어 봤다. 이런 방법으로 웹사이트를 만드는 것은 직접적인 CGI 프로그래밍의 방법보다 훨씬 더 그럴 듯 하고 안정적이면서도 쉽고 빠르다. 여기서 빠르다는 것은 시사 하는 바가 크다.

‘개발 시간이 0에 가까워질수록 인터넷 세상은 어떻게 변할 것 같은가?’ 라는 최근 IT 업계의 질문을 잘 생각해보면 느껴지는 바가 많을 것이다. 장고를 비롯한 최근의 웹 프레임워크들은 이러한 현실을 앞서서 만들어가고 있다.

장고는 해외의 각종 온라인 신문사 등을 비롯하여 여러 기업에서 다양하게 활용되고 있다. 반면에 국내에서는 그다지 많이 활용되지 않는 듯하다. 필자가 직접 관여했던 프로젝트들을 소개하면 다음과 같다.

- Genome ajax Viewer(http://insilicogen.com/dj/gavi) : 유전체(genome) 탐색기. 사용자가 직접 유전체학 실험결과를 가지고, 지도를 그리고, 추가 정보를 관리할 수 있다.

- GMP Study(http://biohackers.net/dj/gmpstudy) : 굿모닝팝스 뉴스받아쓰기 사이트. 이 사이트의 개발과정이 2006 대안언어축제에 소개되었다. 각 단계별로 어떻게 만들었는가를 확인할 수 있다. http://altlang.org/fest/EnglishStudyWithDjango

씨사이드(Seaside)

씨사이드(Seaside)는 스몰토크라는 언어로, 스몰토크 환경의 철학으로 디자인되고 구현된 프레임워크이다. 또, 컨티뉴에이션 기반 웹 프레임워크(Continuation based web framework)이기도 하다. 이런 특징 덕에 씨사이드는 다음과 같은 몇 가지 장점을 가진다.

• 스몰토크라는 동적 타입 언어로 개발하는 까닭에 정적 타입 언어에 비해서 동적 타입 언어만의 기민함을 느낄 수 있다.
• 컨티뉴에이션 기반 웹 프레임워크로 세션을 포함한 웹상의 일련의 작업 흐름을 연속적인 코드의 서술로 표현할 수 있다.
• 콜백(callback) 기반으로 HTTP 요청을 처리할 수 있다. 마치 이벤트 드리븐 프로그래밍을 하는 느낌이다. 이는 씨사이드만의 독특한 특징인데 추후 코드로 살펴보도록 하자.
• 재사용성이 높은 컴포넌트 기반의 웹 개발이 가능하다.
• 스몰토크 환경과 웹상에서의 강력한 개발 및 디버깅 도구를 제공한다. 웹 개발도 점진적이고 빠른 피드백의 개발이 가능함을 보여준다.

이렇게만 보면 보통 첫 페이지에서 소개하는 다른 웹 프레임워크들의 특징 소개와 그다지 다를 것이 없어 보인다. 이제 각 특징들에 대해 좀 더 자세히 살펴보자.

스몰토크(Smalltalk)
씨사이드가 스몰토크로 구현되었다는 점은 레일즈가 루비로 구현된 것만큼이나 큰 의미를 가진다. 스몰토크는 루비처럼 순수 OO(Object Oriented) 언어이며 동적 타입의 언어이다. 더불어 매우 유연하며 간결하면서도 직교적인 표현력도 가지고 있다.

또한 스몰토크를 설명하면서 빼놓을 수 없는 요소가 바로 ‘스몰토크 환경(Smalltalk Enviroment)’이다. 일종의 ‘객체들의 세상(Object World)’인 스몰토크 환경은 언어 차원에서의 OOP 문법 지원 차원이 아닌 그 이상의 유연성과 개발환경, 관리환경을 제공해주며 OOP를 하기에 정말 편리하고 직관적인 환경을 제공해준다.

씨사이드를 쓰면 스몰토크의 객체를 다루듯 웹 애플리케이션을 손쉽게 다룰 수 있다. 이는 추후의 코드를 보면서 생각해보도록 하자.

<화면 3>는 스몰토크 환경의 구현물인 스퀵(Squeak)에서 로드한 씨사이드 이미지(image)이다. 여기서 말하는 ‘이미지’는 그림 파일이 아닌, 스퀵 환경에서 이용하는 일종의 스냅 샷을 의미한다. 참고 사이트에서 이미지 파일을 구할 수 있으며 스퀵에서 이미지를 로드하는 즉시 씨사이드 개발환경이 갖춰진다.


<화면 4> 카운터 어플리케이션

‘++’ 링크를 클릭하면 숫자가 증가를 하고 ‘--’ 링크를 클릭하면 숫자가 감소를 하는 간단한 예제이다. 자 그럼 재미있는 실험을 해보자. 3까지 증가를 시킨 카운터를 URL 복사를 통해서 새로운 브라우저에 하나 더 띄워보자. 새로 복사된 카운터 역시 3을 나타낸다. 즉 같은 URL의 동일한 카운터 애플리케이션이 만들어졌다. 새로 만들어진 카운터의 숫자를 5까지 증가시켜보자.

여기서 내는 퀴즈! ‘3’이라고 표시되는 이전의 카운터의 ‘--’ 링크를 클릭하면 답은 2가 될까? 4가 될까?

<화면 5> 실험 과정 중. 3 이라 표시된 카운터의 ‘--’를 클릭하면?

비슷한 퀴즈를 하나 더 내보겠다. 카운터를 5까지 증가시키고 웹브라우저의 ‘뒤로 가기’ 버튼을 두 번 눌러서 예전의 화면인 ‘3’이 표시되도록 해보자. 그 상태에서 ‘++’ 링크를 클릭하면 답은 6이 될까? 4가 될까?

<화면 6> 실험 과정 중. 뒤로 가기 버튼 두 번을 누른 카운터의 ‘++’을 누르면?

씨사이드에서 첫 번째 퀴즈의 답은 2, 두 번째 퀴즈의 답은 4가 된다. 컨티뉴에이션 기반의 웹 애플리케이션에서는 URL 복사를 통해 같은 애플리케이션을 복사를 해서 변형을 가해도 이전 창의 애플리케이션은 이전의 실행 상태를 그대로 유지하게 된다.

심지어는 웹 브라우저의 ‘뒤로 가기’ 버튼을 눌러도 이전 상태로 되돌아가게 되어 그 시점에서부터 실행이 가능해진다. 물론 ‘뒤로 가기’ 버튼에 대한 행동은 컨티뉴에이션을 쓰지 않고도 구현이 될 수 있지만 씨사이드는 지금 예시뿐만이 아니라 컨티뉴에이션을 통하여 웹 개발에 대한 여러 부분에서 높은 차원의 추상화를 이룰 수 있게 되었다.

또 다른 예로 ‘사용자의 이름을 물어보고 사용자가 입력한 이름에 대해 인사로 답’하는 작업의 흐름이 필요한 웹 애플리케이션을 씨사이드에서는 <리스트 6>처럼 코드의 연속으로 구현하게 된다.


<리스트 6> 입력한 이름에 대해 인사하는 코드


go
| name |
name := self request: 'what is your name?'.
self inform: 'Hi ', name.





<리스트 6>에서 입력한 코드의 결과는 <화면 7>과 같다.


<화면 7> 결과화면

만약 이 코드를 씨사이드가 아니라 php로 만들었다면 <리스트 7>처럼 길어졌을 것이다. 코드 흐름이 최대한 한 텍스트에 있도록 모델 1 형태로 작성해보았다.


<리스트 7> PHP로 만든 입력한 이름에 대응하는 코드


if ($mode == ‘’ || $mode ==’form’) {
echo "

What is your name?

" . "
\n"
echo "





일부러 모델 1 스타일에 하나의 파일로 같은 예를 작성 했지만 개념의 차이가 있다. 바로 코드의 연속성 문제이다. 코드가 연속적으로 구현되고, 최대한 흐름과 관련된 코드들이 텍스트 상으로 가까운 예제가 프로그램을 이해하는 데 더 쉽고 코드 간의 사고나 내비게이션의 점프가 적어진다.

그리고 실수할 수 있는 가능성도 더 적어진다(이에 대해서는 Goto statement is considered harmful 관련 마소 기사를 참고하도록 하자). 컨티뉴에이션 기반 프레임워크는 이처럼 같은 기능 내에 있는 코드들이 연속성을 가지도록 하는데 도움을 준다. 이를 좀 더 발전시킨 모습이 바로 이제부터 알아볼 콜백(callback) 기반의 웹 요청 처리이다.

콜백(callback) 기반의 웹 요청 처리
고전적인 웹 개발 방법을 사용한다면 앞의 예제와 같은 카운터 애플리케이션의 ‘++’와 ‘--’ 링크를 어떻게 구현했을 지 생각해보자. 링크를 클릭하면서 카운터를 동작시켜야 한다. 그러려면 일단 각 링크마다 다른 요청을 보내도록 만들고 표시된 페이지에서는 HTTP 요청에 따라 내부적으로 수행해야 할 객체의 메소드를 선택하는 코드를 작성해야 한다.

또, 그 결과를 다시 받아서 웹 페이지로 숫자를 출력할 것이다. 이때 겉으로 보이는 ‘++’, ‘--’ 말고도 이들 요청을 처리하기 위한 부수적인 작업들이 내부적으로 필요하게 된다. 여기에서는 지면 관계상 씨사이드 코드만 싣도록 하겠다. <리스트 8>은 카운터 애플리케이션을 웹 브라우저를 통해 요청할 때 사용되는 메소드 코드다.


<리스트 8> 카운터 예제 코드


renderContentOn: html
html heading: count.
html anchorWithAction: [self increase] text: '++'.
html space.
html anchorWithAction: [self decrease] text: '--'





처음 보는 언어의 코드라고 그냥 넘기지 말고 간단한 영어 문장을 읽는다는 기분으로 코드를 읽어보자. 생각보다 읽기 편할 것이다. 중요한 부분은 html anchorWithAction: [수행할 명령] text: ‘링크 텍스트’이다. 예를 들어 카운터 증가 링크의 경우 ‘++’라는 텍스트 링크를 클릭하면 ‘self increase’ 즉 카운터 객체의 increase 메소드를 호출하라는 의미가 된다.

[수행할 명령] 부분을 블록(Block) 이라고 하는데, 루비를 사용해 본 독자들은 아마 이러한 문법에 익숙하리라 생각된다. 바로 루비에의 클로저(closure) 문법인 {}와 같은 역할을 한다. [] 안의 코드 묶음 자체가 일종의 커맨드(Command) 객체로, 여기에 연결된 ‘++’ 혹은 ‘--’ 링크를 클릭하면 호출되는 콜백 객체이다.

일종의 이벤트 드리븐 프로그래밍(Event Driven Programming)과 같은 형태인데 앞에서 말한 ‘연속성’이 유지되어 프로그래밍하기 편하다.

컴포넌트 기반의 웹 개발
씨사이드에서는 웹 애플리케이션을 개발할 때 컴포넌트 단위로 개발을 하게 된다. 그리고 컴포넌트와 컴포넌트들을 조합하여 새로운 애플리케이션을 만들어 낼 수 있다.

카운터 애플리케이션의 경우 실제 구현물은 WAComponent를 상속받은 WACounter라는 클래스인데, 이 또한 컴포넌트로서 다른 웹 애플리케이션 내의 모듈로 사용된다. 예제를 통해 간단히 Hello Seaside 라는 애플리케이션을 만들어보자. 거기에 WACounter를 이용한 카운터 다섯 개를 만드는 예제이다. 먼저 Hello Seaside를 만들어보자.

씨사이드의 가장 기본이 되는 상위 클래스는 WAComponent인데, 이를 상속받고 renderContentOn: html 메소드만 구현하면 기본적으로 컴포넌트가 된다.


<리스트 9> Hello Seaside 코드


"클래스 선언부"
WAComponent subclass: #CHHello
instanceVariableNames: 'counters'
classVariableNames: ''
poolDictionaries: ''
category: '1002-Exam'

"기본 출력과 관련한 메소드 : 오버라이드하여 사용한다"
renderContentOn: html
html text: 'Hello Seaside!'.





<화면 8>는 <리스트 9>에서 만든 Hello Seaside 코드의 실행 결과이다.

<화면 8> CHHello 컴포넌트

자, 여기에 WACounter를 다섯 개 붙여서 멀티 카운터를 만드는 예제는 <리스트 10>과 같다. 초기화(initialize) 시 카운터 인스턴스를 다섯 개 만드는 새로운 컴포넌트를 만들고, children이라는 자식 컴포넌트들을 리턴하는 메소드를 만든다. 그 뒤에 출력 관련 메소드에 자식 컴포넌트들을 render 메소드를 이용하여 출력한 뒤, HR 라인으로 나누어 출력하면 <화면 9>과 같은 메소드 출력 결과를 얻을 수 있다.


<리스트 10> WACounter 다섯 개 붙이기


initialize
super initialize.
counters := (1 to: 5) collect: [:i | WACounter new]
children
^ counters
renderContentOn: html
counters
do: [:ea | html render: ea]
separatedBy: [html horizontalRule]





<화면 9> 다중 카운터. 단순히 카운터 인스턴스 다섯 개를 만들고 render 하는 것만으로 가능하다.

정말 재미있는 점은, 이 페이지 내에 표시되는 다섯 개의 카운터가 ‘전부 독립적인 컴포넌트’라는 점이다. ++와 --를 누르면 신기하게도 각 컴포넌트들이 전부 독립적으로 동작한다.

GUI 프로그래밍을 할 때 컨트롤들을 붙여서 애플리케이션을 구성하던 때가 연상되지 않는가?

강력한 개발 및 디버깅 도구

스몰토크 개발 환경인 스퀵은 굉장히 동적인 개발 환경을 갖추고 있다. 거기에 덧붙여 씨사이드는 웹 기반의 다양한 개발 및 디버깅 도구도 제공한다. 개발과 관련된 여러 가지 도구가 있지만, 여기서는 씨사이드에서의 디버깅 도구에 대해서만 살펴보기로 하자.

잠깐 앞의 카운터 예제에서 간단한 버그를 내보도록 하자. Divide By Zero를 내본다.


<리스트 11> Divide By Zero 버그


renderContentOn: html
| temp divider |
divider := 0.
temp := 10 / divider.
html heading: count.
html anchor callback: [count := count+1]; text: '++'.
html space.
html anchor callback: [count := count-1]; text: '--'





에러를 만든 뒤에 웹상에서 카운터 애플리케이션을 실행하면 <화면 10>과 같은 에러 메시지가 표시된다.

<화면 10> 웹 애플리케이션 중 에러 발생 시의 에러 페이지 화면

이때 Debug를 클릭하면 재미있는 일이 발생한다. 바로 스퀵 환경에서 디버거가 뜨는 것이다.

<화면 11> 에러 페이지에서 ‘debug’링크 클릭 시 표시되는 스퀵의 디버거 화면

디버거 상에서 잘못된 코드에 대해 콜 스택(call stack)을 보고 찾을 수 있고, 현재 코드 내의 변수 값과 인스턴스의 값을 바로 확인할 수 있다. 적절하게 코드를 수정한 뒤에 Proceed 버튼을 누르면, 디버거 창이 닫히면서 프로그램은 다시 올바른 결과 화면을 표시한다.

<화면 12> 버그가 수정된 버전

이 밖에도 씨사이드 시스템 브라우저를 이용하여 웹상에서 코드를 수정할 수 있다. 프로파일러(Profiler)를 이용하여 수행시간과 메모리 사용량을 측정할 수도 있고, 인스펙터(Inspector)를 통해 인스턴스 변수의 현재 값 등을 살펴보는 등 편리하고 다양한 개발 환경을 제공한다.

지금까지 iBatis와 씨사이드의 특징들에 대해 간단히 알아보았다. 짧은 지면 내에서 씨사이드의 전반적인 모습을 보이려고 했으나, 무언가 빠진 듯 한 느낌을 지울 수 없다. 글이라는 매체를 통해서 전달하기에는 손실되는 정보와 느낌이 많다는 느낌이 들곤 한다. 필자가 <마소>의 발행 부수만큼 복제 될 수 있다면 잡지의 부록으로 끼어들어가 이 글을 읽는 모든 독자와 짝 프로그래밍을 해보고 싶다.

실제로, 이 글을 쓴 필자 중 한 명인 강석천도 씨사이드를 김승범과의 짝 프로그래밍을 통해 씨사이드를 익힐 수 있었다. 스몰토크 환경인 스퀵과 관련한 관련 문서들과 서적들도 조금씩 늘어나고 있으니 참고 자료를 참조하여 즐겁게 가지고 놀면 좋겠다.

마지막으로, 필자가 씨사이드에서 가장 중요하게 여기는 부분은 바로 ‘스몰토크로 구현되었다는 점’이다. ‘너무 언어 종속적인 생각 아닌가? 개념만 정의되면 다른 언어로의 포팅은 쉬운 것 아닌가’하고 반문하는 독자도 있겠다. 하지만, 개인적인 견해로는 씨사이드가 스몰토크 기반이었기에 이처럼 재미있는 성격의 프레임워크가 나올 수 있었다고 믿고 있다.

스몰토크는 최초의 OOP 언어이면서 동시에 OOP 컴퓨팅 환경이다. 수많은 현대 프로그래밍 언어들이 OOP에 영향을 받았고, 이제는 OO 개념이 들어가지 않은 프로그래밍 언어는 보기 힘들어졌다.

하지만 스몰토크만큼 순수하고 간결하면서, 사람을 변화시키는 철학까지 갖춘 OOP 언어는 드물다. 그러한 스몰토크 언어+환경의 장점과 철학을 고스란히 물려받아 구현된 웹 프레임워크가 바로 씨사이드가 아닐까 한다. @


참고자료
1. 장고 홈페이지(http://www.djangoproject.com)
2. The pragmatic programmer: from journeyman to master (Andrew Hunt, David Tomas, ISBN:020161622X )
3. Python Web Server Gateway Interface v1.0, http://www.python.org/dev/peps/pep-0333/
4. TurboGears 홈페이지, http://www.turbogears.org
5. 귀도의 웹 프레임워크 템플릿 관련 코멘트, Django vs. Cheetah: 1-0, http://www.artima.com/weblogs/viewpost.jsp?thread=146606
6. 스몰토크 환경인 스퀵 메인 사이트(http://squeak.org)
7. 한국 국내 스퀵 사용자 모임(http://squeak.or.kr)
8. 씨사이드 메인 사이트(http://seaside.st)
9. http://dabbledb.com
10. 다익스트라가 goto에 시비(?)를 건 진짜 이유는? - 마이크로소프트웨어2003년 4월호
11. 이상한 나라의 스퀵 1,2,3 마이크로소프트웨어 2005.11 ~ 2006.1월 연재기사
12. Squeak :A Quick trip to objectland - 아주 예쁘고 친절한(?) 스퀵 입문서.
[:2008년 03월 16일 15:54:25 수정되었습니다.:]