Firebug debugging

Console Logging Functions

FireBug makes a console object available to all web pages. This object has the following functions:

Basic Logging

console.log("message" [,objects]) - Logs a string to the console. The string may contain any of the patterns described below in the "String Formatting" section. The objects passed after the string will be substituted for each of the patterns in the string in order.

Logging Levels

It is often useful to separate messages according to different levels of severity. There are four different functions for this purpose. In addition to the visual separation, these functions are also different from log in that they automatically include a link to the line number in the source where they are called.

console.debug("message" [,objects]) - Logs a debug message.
console.info("message" [,objects]) - Logs an informative message.
console.warn("message" [,objects]) - Logs a warning.
console.error("message" [,objects]) - Logs an error.

Assertions

Assertions are a great way to enforce rules in your code. The console object includes a set a common types of assertion functions, and also allows you to write your own.

console.assert(a, "message" [,objects]) - Asserts that an a is true.
console.assertEquals(a, b, "message" [,objects]) - Asserts that a is equal to b.
console.assertNotEquals(a, b, "message" [,objects]) - Asserts that a is not equal to b.
console.assertGreater(a, b, "message" [,objects]) - Asserts that a is greater than b.
console.assertNotGreater(a, b, "message" [,objects]) - Asserts that a is not greater than b.
console.assertLess(a, b, "message" [,objects]) - Asserts that a is less than b.
console.assertNotLess(a, b, "message" [,objects]) - Asserts that a is not less than b.
console.assertContains(a, b, "message" [,objects]) - Asserts that a is in the array b.
console.assertNotContains(a, b, "message" [,objects]) - Asserts that a is not in the array b.
console.assertTrue(a, "message" [,objects]) - Asserts that a is equal to true.
console.assertFalse(a, "message" [,objects]) - Asserts that a is equal to false.
console.assertNull(a, "message" [,objects]) - Asserts that a is equal to null.
console.assertNotNull(a, "message" [,objects]) - Asserts that a is not equal to null.
console.assertUndefined(a, "message" [,objects]) - Asserts that a is equal to undefined.
console.assertNotUndefined(a, "message" [,objects]) - Asserts that a is not equal to undefined.
console.assertInstanceOf(a, b, "message" [,objects]) - Asserts that a is an instance of type b.
console.assertNotInstanceOf(a, b, "message" [,objects]) - Asserts that a is not an instance of type b.
console.assertTypeOf(a, b, "message" [,objects]) - Asserts that the type of a is equal to the string b.
console.assertNotTypeOf(a, b, "message" [,objects]) - Asserts that the type of a is not equal to the string b.

Measurement

The following functions allow you to measure certain aspects of your code.

console.trace() - Logs a stack trace showing the point of execution where this is called.
console.time("name") - Begins a timer and gives it a unique name.
console.timeEnd("name") - Stops the timer with the given name and logs the number of milliseconds that have ellapsed since it was started.
console.count("name") - Logs the number of times that the line of code where this is called has been executed.

String Formatting

All of the console logging functions can format a string with any of the following patterns:

%s - Formats the object as a string.
%d, %i, %l, %f - Formats the object as a number.
%o - Formats the object as a hyperlink to the inspector.
%1.o, %2.0, etc.. - Formats the object as an interactive table of its properties.
%.o - Formats the object as an array of its property names.
%x - Formats the object as an interactive XML markup tree.
%1.x, %2.x, etc.. - Formats the object as an interactive XML markup tree with n levels expanded.

If you need to include a real % symbol, you can escape it with a backslash like so: "\%".

Command Line Functions

The following built-in functions can be accessed from the command line:

$("id") - A shortcut for document.getElementById().
$$("css") - Returns an array of elements that match a CSS selector.
$x("xpath") - Returns an array of elements that match an XPath selector.
$0 - Variable containing the most recently inspected object .
$1 - Variable containing the next most recently inspected object .
$n(5) - Returns the nth most recently inspected object that has been inspected.
inspect(object) - Displays an object in the Inspector.
dir(object) - Returns an array of property names on an object.
clear() - Clears the console.


http://www.digitalmediaminute.com/screencast/firebug-js/

by 방마루 | 2009/03/10 11:24 | 트랙백(1) | 덧글(0)

Oracle Lite JDBC Connection

모바일에 설치된 Oracle Lite DB 파일을 PC로 가져와 엑세스해야 하는 일이 생겼다.

ODBC로의 연결은 별 어려움 없이 성공하였으나, PC마다 DSN을 설정하는 번거로움이 싫어서 JDBC로의

연결을 고민하였다.

타DB 의 DSN Less 자료는 인터넷상에 많은데, Oracle Lite용 자료는 찾기가 어렵다.


Class.forName("oracle.lite.poljdbc.POLJDBCDriver");
.
.
.

String URL = "jdbc:polite:UID/PWD:polite;DataDirectory=DB파일절대경로;Database=데이타베이스명"
.
.
.


아래는 참고한 사이트
http://evikas.com/blog/viewtopic.php?t=15

by 방마루 | 2009/02/16 17:15 | 트랙백 | 덧글(0)

Eclipse Decompiler JD-Eclipse


Eclipse 3.4도 지원한다.

http://java.decompiler.free.fr/?q=node/192

by 방마루 | 2009/02/11 19:34 | 트랙백 | 덧글(0)

Oracle PK 변경하기

1.변경하고자 하는 COLUMN으로 Unique Index를 생성한다.
: CREATE UNIQUE INDEX PK명 ON TABLE명(COLUMN명) TABLESPACE TABLESPACE명;

2.해당하는 PK를 삭제한다
: ALTER TABLE TABLE명 DROP CONSTRAINT PK명;

3.PK에 속성을 추가한다.
: ALTER TABLE TABLE명 ADD CONSTRAINT PK명 PRIMARY KEY(COLUMN명);

by 방마루 | 2009/02/04 10:04 | 트랙백 | 덧글(0)

oracle startup / shutdown

ORACLE DB 기동 및 Down

Unix 에서 Oracle DB 기동에 대해 알아보도록 하겠다.

디비에는 다양한 프로세스가 존재하지만
실제 DB를 체크할때는 다음과 같은 두개의 프로세스를 챙기게 된다.

ps -ef | grep pmon
ps -ef | grep tns

여기서 pmon이란 db 자체가 떠있나를 체크하는 프로세스이며
tns는 리스너를 의미한다.
리스너란 db에 오는 요청을 받아들이는 역할을 한다.

[LGEMGT1Q:xsgjjsk]/KIC/xsgjjsk>ps -ef | grep ora_pmon | grep -v grep
  oracle 23308     1  0  Mar 25  ?        49:41 ora_pmon_AUTOSDB
[LGEMGT1Q:xsgjjsk]/KIC/xsgjjsk>ps -ef | grep tns | grep -v grep
  oracle 23117     1  0  Mar 25  ?        475:48 /data01/app/oracle/product/9.2.0/bin/tnslsnr AUTOSDB -inherit


일반적으로 Down 및 Up의 순서는 다음과 같다.

Down
web프로그램(iplanet, apache) - Was(weblogic , tomcat) - 리스너 - 디비
Up
디비 - 리스너 - Was(weblogic, tomcat) - web프로그램(iplanet, apache)

리스너 Down & Up 방법
#su - 오라클 유저
#cd ~ (오라클 유저의 홈디렉토리)
#cd bin (위의 예시의 경로로 치면 /data01/app/oracle/product/9.2.0/bin)
# lsnrctl stop(start) 리스너 이름

DB Down & Up 방법
#su - 오라클 유저
#sqlplus '/as sysdba'
#들어가서 다음 명령어 기동
#startup -> 기동
#shutdown immediate

DB 다운 시 오류가 나는경우
#shutdown abort
#startup
#shutdown immediate
로 강제로 내린후 정상으로 올라오는지 확인후 정상 down을 하면된다.

해당 방법으로 DB 가 올라오지 않는 경우에는 원인을 첨부터 분석하는 방법을 사용해야한다.

by 방마루 | 2008/12/31 20:04 | 프로그래밍 지식 | 트랙백 | 핑백(1) | 덧글(0)

HTML DOCTYPE

HTML <!DOCTYPE> tag





Definition and Usage


The <!DOCTYPE> declaration is the very first thing in your document,
before the <html> tag. This tag tells the browser which HTML or XHTML
specification the document uses.





Tips and Notes


Note: The <!DOCTYPE> tag does not have an end tag!





HTML


HTML 4.01 specifies three document types: Strict, Transitional, and
Frameset.


HTML Strict DTD


Use this when you want clean markup, free of presentational clutter. Use this
together with Cascading Style Sheets (CSS):





<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">

HTML Transitional DTD


The Transitional DTD includes presentation attributes and elements that W3C
expects to move to a style sheet. Use this when you need to use HTML's
presentational features because your readers don't have browsers that support
Cascading Style Sheets (CSS):





<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">

Frameset DTD


The Frameset DTD should be used for documents with frames. The Frameset DTD
is equal to the Transitional DTD except for the frameset element replaces the
body element:





<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN"
"http://www.w3.org/TR/html4/frameset.dtd">





XHTML


XHTML 1.0 specifies three XML document types: Strict, Transitional, and
Frameset.


XHTML Strict DTD


Use this DTD when you want clean markup, free of presentational clutter. Use
this together with Cascading Style Sheets (CSS):





<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

XHTML Transitional DTD


Use this DTD when you need to use XHTML's presentational features because
your readers don't have browsers that support Cascading Style Sheets (CSS):





<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

XHTML Frameset DTD


Use this DTD when you want to use frames!





<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">

To check that you have written a valid XHTML document with a correct DTD,
you can link your XHTML page to an XHTML validator.


<출처: http://www.w3schools.com/tags/tag_DOCTYPE.asp>

by 방마루 | 2008/07/02 11:14 | 트랙백 | 덧글(0)

eclipse plugin

Eclipse Explorer
http://www.harald-schubert.net/update/releases

by 방마루 | 2008/06/30 12:04 | 트랙백 | 덧글(0)

eclipse 시작시 오류코드 (2) 해결법

JVM terminated. Exit code=2
C:\WINDOWS\javaw.exe
-cp C:\eclipse\startup.jar org.eclipse.core.launcher.Main
-os win32
-ws win32
-arch x86
-showsplash C:\eclipse\eclipse.exe -showsplash 600



해결법

regedit로 해당 레지스트리를 변경한다.

HKEY_LOCAL_MACHINE/SOFTWARE/JavaSoft/Java Runtime Environment
의 CurrentVersion 값이 변경되었는지 확인해보자.

오라클, JBuilder, Together 등 설치시 Jre를 추가로 설치하는 프로그램들이 레지스트리를 건드려서

동 현상이 발생할 수 있다.

물론 JRE를 Uninstall 후 재설치하여도 해결된다.

by 방마루 | 2008/06/04 17:41 | 트랙백 | 덧글(0)

MAX 대체 Hint 사용

MAX함수
 - 새로운 값을 INSERT하기 위해서 기존에 있는 값 중에서 가장 큰 값을 찾기 위함
 - 해당 데이터를 전부 다 읽어야 최대값을 찾을 수 있는 전체적인 처리를 하기 때문에 실행시간이 많이 걸리는 단점

예)

기존)
SELECT MAX(SEQ)+1
  FROM PRODUCT
 WHERE DEPTNO = '12300'


개선)
SELECT /*+INDEX_DESC(A INDEX1)*/ SEQ+1
  FROM PRODUCT A
WHERE DEPTNO = '12300'
    AND ROWNUM = 1;

by 방마루 | 2008/05/09 12:49 | 트랙백 | 덧글(1)

인생 30년 계획 : 첫 10년, 그 다음 10년, 마지막 10년


인생 30년 계획: 첫 10년, 그 다음 10년, 마지막 10년




관련기사: [조선일보] 송명근 건국대병원 흉부외과 교수

일단 위의 기사를 보세요.


명근 교수님, 정말 멋진 분이네요. 지금까지 심장수술을 8천 번 했고, 지금도 하루에 네다섯 번의 수술을 하신다네요. 18년간
일한 병원에서 원로 대접을 해서, 수술을 하기 위해 박차고 나와서 70세까지 메스 잡고 현역으로 일하실 거라 하며, 재산도 모두
사회에 환원하신다는군요.

어떤 삐딱한 사람들은 이런 분을 보고서 자기과시욕이 심하다고 할 지도 모르겠지만, 천만에요. 송명근 교수의 스승인 앨버트 스타 교수가 다음과 같은 말을 해주었다고 합니다.

첫 10년은 과감하게 일해서 너 자신을 유명하게 만들어라. 그래야 지원을 많이 받을 수 있다. 그 다음 10년 동안은 전력 투구해서 일을 확대시켜라. 그리고 마지막 10년은 그때까지 한 일을 꽃피우라.


말 사회에 기여하겠다는 꿈이 있다면 먼저 자신이 유명해져야 합니다. 그래야 힘을 얻고 지원을 받을 수 있죠. 물론 이 과정에서
변질되는 사람들이 아주 많은데, 송명근 교수처럼 초심을 끝까지 지키는 사람들도 분명히 있습니다. 마음이 담긴 수술과 재산의 사회
환원 등만 보더라도 송명근 교수는 존경 받을만한 가치가 충분합니다.

사실 자기애와 인류애는 종이 한장 차이라고 생각합니다. 자기애로 그치느냐, 아니면 더 나아가서 사회에 커다란 기여를 하느냐 하는 것의 차이.

큰 일을 꿈꾸는 사람들에게 있어서는 좋은 롤 모델이 아닐까 합니다. 그 외에도 수술을 잘하는 의사들이 예술적인 재능이 있다는 등(IT에서도 마찬가지죠) 좋은 내용들이 많으니 기사를 꼭 읽어보세요.

출처 : 류한석의 피플웨어

by 방마루 | 2008/04/18 09:06 | 트랙백 | 덧글(1)

hsqldb 에서 페이징쿼리

ROWNUM 키워드는 Oracle용으로, hsqldb 를 비롯한 대부분의 rdbms에서는 사용할 수 없는 키워드다.

최근 hsqldb를 사용해 보려고 하던중에, 자료를 찾아보았다.

HSQLDB에서는 LIMIT를 이용해 페이징을 처리할 수 있다.

http://sourceforge.net/forum/forum.php?thread_id=1296082&forum_id=73674

by 방마루 | 2008/04/08 11:48 | 트랙백 | 덧글(0)

첫 만남에서 이러면 곤란하지... 사파리(Safari)

윈도우가 지원되는 사파리(Safari)가 출시(public beta)했다는 소식을 듣고, 부리나케 사파리로 달려갔다.

약관에 동의하고 설치했다.

아직은 때가 아닌가...


by 방마루 | 2008/04/03 16:08 | 트랙백 | 덧글(0)

ProcessExplorer의 갑작스런 배신(?)!

훌륭한 Task Manager인 ProcessExplorer 로 윈도우 작업관리자를 대체하여 사용하고 있었는데,

어느날 갑자기 Process Column 이 안보이는 황당한 상황이... (메뉴에서 활성화도 막혀있다...)

나와 같은 곤란을 겪은 다른 사용자들이 있을까하여 검색해 보았는데, 

국내 사용자중엔 동변상련을 느낄 사용자가 없나보다.

저어 멀리 Hawaii, Maui 에서 만났다^^

해결 법은 지극히 원초적이더라.

HKEY_CURRENT_USER\Software\Sysinternals\Process Explorer 키를 삭제...


출처링크 : http://west-wind.com/WebLog/posts/9849.aspx

by 방마루 | 2008/04/03 10:24 | 트랙백 | 덧글(1)

[Javascript] option 태그의 disabled 속성이 IE에서 안된다?

이상한일이다.

http://www.w3schools.com/htmldom/dom_obj_option.asp 를 보아도 IE4 버전 이상부터 지원하는 속성이라고

되어 있는데 도무지 적용되지 않는다.

방법을 찾아보니, optgroup 을 이용하는 법이 있지만, 이건 정상적인 방법이 아니다...

혹시, 안되는 이유나 방법을 아시는 분... 계실려나?

<select id="mySelect">
   <option>Apple</option>
   <option>Orange</option>
   <option disabled="disabled">Pineapple</option>   <---- IE7에서 (6은 확인못해봄) 이 속성이 적용되지 않는다...
   <option>Banana</option>
</select>

by 방마루 | 2008/02/27 11:08 | 트랙백 | 덧글(0)

Windows Live SkyDrive 무료웹하드 서비스

내가 기다리던 서비스가 시작됐다.

고맙게도(^^) MS에서 5기가의 용량을 무료로 제공한다.

이제 구글메일을 통해 나한테 메일을 보내지 않아도 된다^^

단일파일의 크기가 50MB가 넘지 않는 한도에서 파일, 문서등을 다양하게 올리고 활용할 수 있게 되었다.

폴더별로 친구간 공유, 일반공유, 공유안함 설정도 가능하고,

Active X 를 설치하면, Drag & Drop가 가능해져서, 활용도가 월등히 향상될수 있다.

부품맘을 앉고 조금전 사용해보았다.

흠... 업로드 속도가 느리잖아...  하지만! 무료니까^^

by 방마루 | 2008/02/22 15:09 | 트랙백 | 덧글(1)

Cruise Control을 설치해보자.

개발 프로젝트에 일어서 CI툴이 필요함을 느껴서, PC설치해서 사용해보기로 했다.

여러 CI툴을 알아보다가, Cruise Control은 명성은 익히 들어왔고,

Younghoe.Info 에서 Hudson을 알게되었다. 설정에 관련된 UI까지 지원하는 모습을 보니 도구 결정에 흔들리기 시작했다.

새로운 도구을 사용하게 되면 삽질은 필수일테고, 저변이 넓지 않은 도구를 사용하게 되면

실제 프로젝트사용에 있어서 다수의 반대에 부딪힐 수가 있다.

일안 Cruise Control부터설치해서 사용법을 익히고, 여유가 있으면 Hudson도 사용해보자(UI가 상당히 맘에 든다)

by 방마루 | 2008/02/22 09:21 | 트랙백 | 덧글(0)

[IBM dw] Ajax와 XML: 채팅(chat)용 Ajax

dw를 둘러보다가 괜찮은 자료를 발견했다.

php를 이용한 소스코드와 함께 구현에 대한 설명을 제공하니, 초보자도 이해하기가 쉽게 작성되어 있다.

간단히 따라해보면 좋을듯.

http://www.ibm.com/developerworks/kr/library/x-ajaxxml8/index.html



덧붙임 :

따라해 보다보니, mysql db를 이용한다.  연습용으루 DB스키마까지 정의하는 것이 번거로운

나같은 사람을 위해 jsp와 Application Context를 이용하여 작성해보았다. AjaxChat.7z

by 방마루 | 2008/01/23 11:05 | 트랙백 | 덧글(0)

머리를 좋게 하는 7가지 두뇌생활습관

머리를 좋게 하는 7가지 두뇌생활습관

아무리 머리가 좋다고 해도 제대로 관리하지 않으면 학습능력은 반감될 지 모른다. 도대체 공부를 잘하려면, 머리를 좋게 하려면 평소 어떻게 관리해야 할까. 미래를 열어갈 차세대 리더, 한국과학영재고 학생 425명의 두뇌활용습관을 물어 뇌 건강을 지키는 방법을 정리했다.

1. 명상과 산책

마음을 평온히 유지하는 것은 자신의 상태를 정확히 인식하는데 있어 중요한 생활습관이다. 집중이 안 될 때, 자신의 현재 상태를 알고자 할 때, 현재 상태에서 무언가 변화를 주고자 할 때 명상이나 호흡, 산책같이 심신을 바르게 하는 것은 자신의 뇌 상태를 평안한 지점으로 회복하는 지름길이다.

2. 집중이 안 될 땐 다른 일을 한다.

현재 나의 상태에 무언가 문제가 있을 때, 가장 좋은 것은 시간과 공간을 달리 하거나 새로운 것을 하는 것이다. 뇌가 새로운 환경에 직면하게 되면 새로운 정보가 들어와 뇌에 신선한 자극이 되기 때문에 금세 뇌 상태가 전환된다. 영재학생들처럼 집중이 안 될 때 숙면을 취하거나 명상, 음악, 운동, 게임 등 기존의 상태에서 빠르게 벗어나는 것은 훌륭한 두뇌활용 습관이다.

3. 적절한 운동

체력관리는 뇌 상태를 맑게 유지하는데 기본이 된다. 영재고 학생 중 10명 중 8명이 기본적으로 구기운동에서부터 간단한 스트레칭 등 스스로 체력관리를 하고 잇는 것으로 나타났는데 육체를 움직이는 것은 두뇌활동을 원활이 하는 데 큰 도움을 준다.

4. 예습보다 복습

미리하는 것보다 뇌 속의 정보를 다시 한번 정리하는 것이 더욱 효과적이다. 영재고 학생 10명 중 8명이 복습이 예습보다 더 중요하다고 생각하고 있다. 인간의 기억이 잘 이뤄지려면, 반복성이 중요하기 때문에 예습보다는 해당 정보를 한 번 더 뇌에 입력하는 습관이 기억 측면에서도 더욱 좋다.

5. 시간이 부족할 땐 부족한 것에 집중

모든 것을 다 할 수는 없는 법. 한정된 시간이 주어질 때는 잘하는 것보다는 부족한 것에 집중한다. 시간 대비 효과, 자신감 측면을 고려했을 때 다소 부족한 것의 정보를 습득하는 것이 효과적이다.

6. 꾸준한 독서

책을 많이 읽을수록 좋다는 것은 동서고금의 진리. 기존 학습지나 교과서 이외에도 색다른 정보를 받아들이는 것은 두뇌활용 측면에서 유연성을 확대하고 새로움에 대한 뇌기능 발달에 있어서도 효과적이다. 무엇보다 책은 삶을 살찌우는 보고이므로 어릴적부터 독서습관을 기르는 것은 그 어떤 것보다 중요하다고 볼 수 있다.

7. 중요한 날 전에는 충분한 휴식

뇌가 긴장하게 되면 뇌기능이 쉽사리 발현되지 않는다. 중요한 날 전에는 뇌를 평안한 상태로 두거나 정리한 내용을 위주로 체크하는 것이 뇌를 최적의 상태로 유지하는데 효과적이다.
 

/헬스조선 편집팀
/출처: 뇌교육전문지 ‘브레인’

by 방마루 | 2007/12/27 10:10 | 글과 자기 표현 | 트랙백 | 덧글(0)

[1日30分] 인생 승리의 공부법 55

몇일전 직장 상사의 책상에 놓인 책을 발견하고 흰 바탕의 심플한 표지를 보고 집어들었다.

"삼일만 빌려주세요" 하고 다짜 고자 읽기 시작했다.



[1日30分]

인생승리의 공부법55
Learn to Win

- 후루이치 유키오


전체적으로 공감이 가는 내용이 서술되어 있는데,

끈기, 타이밍, 습관, 계획, 의지, 휴식, 수첩 등의 단어로 정리될 수 있겠다.

이를 한 문장으로 정리하자면, "계획적으로 꾸준히 노력하자."


이것만은 기억하자


- '공부하고 싶다'는 생각이 들었을 때가 공부 의욕이 가장 높은 때이다. 이 시기에 집중점으로 공부하면 평소보다 몇 배나 효율적으로 지식을 습득할 수 있다.

- 하루 5시간씩 1주일간 공부하는 것보다 날마다 30분씩 5년간 꾸준히 공부하는 것이 몇십 배는 더 효과적이다.

- 작심삼일이라도 좋다. 작심삼일도 1년간 50번만 반복하면 150일이나 공부한 것이 된다.

- 처음 배운 날로부터 1주일 후에 복습하고, 그 2주 후에 두 번째 복습하여 다시 이때부터 1개월 이내에  세 번째 복습하는 방법이 가장 효율적인 학습 방법이다.

- y(공부성과) = a(교재와 서비스 질) X b(집중력) X x^2(공부 시간의 제곱) + c(과거의 공부량)

- 지식을 효율적으로 습득하려면 비용을 자신이 부담해야 한다. 자신이 비용을 투자하지 않는 사람은 지식의 흡수력이 거의 0에 가깝다.

- 자기 투자를 하면 반드시 몇 년 후에 결실을 거둘 수 있다.

- TV를 보지 않으면 1년동안 약 2개월의 시간을 확보할 수 있다.

- 회사에는 공부 도구가 갖추어져 있다. 30분~1시간 빨리 출근하여 공부하자. 카페도 공부할 수 있는 공간으로 활용할 수 있다.

- 편도 45분 통근 시간을 공부에 할애하면 연간 약 400시간의 공부 시간을 확보할 수 있다.

- 이동시간(자동차, 도보)에는 음성을 이용해 공부한다.

- 생활 습관을 아침형으로 바꾸어 아침에 공부하는 편이 효율적이다.

- '단시간 공부(30분) ->휴식(15분)'을 1세트로 하여 기본적으로 2, 3세트 반복한다. 집중력이 떨어져 공부가 싫어지기 전에 중단하는 것이 요령이다.

- 장시간 공부를 하여 집중력이 떨어지거나, 싫증을 느끼기 시작하면 곧바로 공부를 시작한다.

- 장시간 공부를 하여 공부할 마음이 생기지 않거나 의욕이 없는 시기가 오면 2, 3일 완전히 공부에서 손을 놓을 것. 계획이나 목표가 명확한 사람은 '진자의 원리'에 따라 자연스럽게 의욕이 생긴다.

- 단기 성과를 목표로 할 때에도 목전에 닥칠 때까지 기다리지 말고 미리미리 공부를 시작한다.

- 단기 집중형 학습에서는 모든 활동을 공부에 집중한다. 공부와 관계없는 활동은 되도록 자제하고 평일 3시간 이상, 휴일 8시간 이상 공부한다.

- 장기 계획형은 하루 공부 시간을 조금 적게 정하여 날마다 꾸준히 하는 것이 요령이다. 결과적으로는 공부의 양이 증가한다.

- 공부하는 동안에는 고독할 수 밖에 없다. 고독을 견디려면 공부하는 목적을 확고하게 설정해야 한다.

- 영어가 좀처럼 늘지 않는 이유는 필요한 공부의 질을 잘못 선택했기 때문이다. 원어민은 시험에 나오는 어려운 표현이나 간접적인 말투, 어려운 단어는 거의 사용하지 않는다.

- 회화 학원에 다녀도 실력이 좀처럼 향상되지 않는 이유는 공부량이 절대적으로 적기 때문이다.

- 듣기 실력 향상에는 기본 문장 암기, 듣기 & 보기, 올바른 발음 익히기, 연음 등의 지식이 필요하다.

- 독해 향상을 위해서는 영문을 매일 30분 정도 빠르게 읽는 연습을 계속해야 한다.

- 영작문의 향상을 위해서는 실제로 영문을 쓰고 지도자에게 첨삭 지도를 받아야 한다.

- 영어를 일정 레벨 이상 끌어올리기 위해서는 연간 1,000시간, 최소 750시간은 공부해야 한다.

- 꿈을 실현하기 위해서는 먼저 목표를 종이에 적고 시각적으로 체크한다.

- '최종 목표 달성일 설정->장기 목표설정-> 1일 목표 설정'이라는 방식으로 목표를 점차 세분화하면 달성 시기가 빨라진다.

- 많은 사람들이 목표 달성에 실패하는 가장 큰 원인은 결단하지 않기 때문이다. 우선, 기일을 포함해 '실현하고 싶은 꿈과 목표'를 명확하게 결정하자.

- 수첩에 목표를 기록하여 가지고 다니면 목표의 실현 속도가 빨라진다.

- 목표를 매번 반복해서 읽으면 무의식에 변화가 생기고, 무의식이 변하면 행동이 바뀐다. 그리고 행동이 바뀌면 결과가 달라진다.

- 식사는 공부 효율을 떨어뜨리는 적이다. 따라서 이를 예방하기 위해서는 한번에 조금씩 자주 꼭꼭 씹어서 먹거나 식사를 마친 후에는 곧바로 공부를 하지 않는다. 그리고 식사는 야채와 밥을 중심으로 하자.

- 아침~정오는 과일만 먹고, 정오~저녁8시는 '야채+밥' '야채+단백질'을 섭취하는 습관을 기르자. 그렇게 하면 식후 10분 후 공부나 일을 시작할 수 있다.

- 공부 효율을 향상시키거나 배운 내용을 기억으로 정착시키기 위해서는 수면이 중요하다. 이상적인 수면시간은 7시간 반이며 적어도 6시간은 수면을 취해야 한다.

- 아침에 일어나 따뜻한 물로 샤워를 하면 곧바로 공부를 시작할 수 있다.

- 타이머를 이용, 공부시간과 휴식 시간을 적절히 교대하여 집중력을 유지한다.

- 밖에서 공부할 때는 귀마개와 A4클립보드가 무기가 된다.

- 책상보다 의자에 돈을 투자하자. 의자는 허먼밀러사의 에어론 체어를 추천한다.

- '의자->조명->책상'순서로 투자를 하면 비용대비 효과를 가장 높일 수 있다.






by 방마루 | 2007/12/12 16:55 | 글과 자기 표현 | 트랙백 | 덧글(0)

객체지향을 더욱 객체지향적으로 관점지향(AOP)

객체지향을 넘어 관점지향으로 AOP

이일민 (DevelopGate 기술 컨설턴트)   2006/05/01






전세계 자바 EE 개발 프로젝트의 80%가 원래 계획했던 목표를 다 이루지 못하고 실패로 끝나고 만다는 사실은 한편으로는충격적이지만 어쩌면 당연한 결과라고 받아들여지고 있다. 개발자들은 좀 더 단순한 방법을 찾아야하고 그에 따라 더욱 효과적으로명확한 결과를 얻어낼 수 있어야 한다. 소프트웨어 개발의 단순함의 핵심에 바로 관점지향 프로그래밍, AOP가 존재한다.

최근 몇 년 간 자바 개발자들이 경험하고 있는 새로운 기술의 흐름과 방향을 한마디로 말해보자면‘단순함(simplicity)의추구’라고 할 수 있다. 아무리 정교하고 잘 설계된 프로그래밍 기술과 개발 방법론, 분석설계 기술을 사용한다고 하더라도개발자들이 이해하고 구현해야 하는 애플리케이션의 구조와 구현 내용은 갈수록 복잡하고 다차원적이 되어가고 이를 감당하기 위해서개발자들은 점점 복잡한 미로 속으로 빠져들어 갈 수밖에 없다.

관점지향 프로그래밍(Aspect Oriented Programming, 이하 AOP)이라는 말을 처음 들어보면 객체지향프로그래밍(Object Oriented Programming, 이하 OOP)이 떠오른다. AOP는 결국 OOP의 뒤를 잇는 또하나의 프로그래밍 언어 구조라고 생각될 수 있다. 지금까지 프로그래밍 기술은 기계어와 같은 초기 언어를 기반으로 한프로그래밍으로부터 출발해서 절차적 프로그래밍을 거쳐 OOP에 이르렀다. 20여년 이상 현장에서의 적용과 내부적인 개념의 발전그리고 자바나 C# 같은 대중적인 언어의 등장에 힘입어 이제는 OOP가 전체 소프트웨어 개발의 대표적인 패러다임으로 자리 잡고있다.

그럼 이제 AOP의 등장으로 OOP는 사라져 갈 것이고, AOP가 OOP를 대체하게 될 것이라고 할 수 있을까? 결코 그렇지않다. AOP와 관련된 가장 중요한 개념은‘AOP는 결코 OOP의 자리를 대신하기 위해서 등장한 기술이 아니다’라는 것이다.오히려 AOP는 OOP를 더욱 OOP답게 만들어줄 수 있다고 할 수 있다. 많은 AOP 기술의 주도자들과 개발자들은 AOP가OOP를 사라지게 하는 것이 아니라 더욱 완전하게 만들어 줄 수 있다고 주장한다. 또 AOP는 OOP뿐만 아니라 기존의 절차적프로그래밍에도 적용되어질 수도 있다. 결국 AOP는 지금까지의 프로그래밍 기술 변화의 흐름에 다른 차원의 관점을 제시함으로써새로운 프로그래밍 패러다임을 이끌어내고 있다고 볼 수 있다.

AOP의 필요성
AOP의 필요성을 이해하는 가장 기초가 되는 개념은‘관심의 분리(Separation of Concerns)’이다. 관심의 분리는컴퓨터 프로그래밍의 가장 기초가 되는 원리 중 하나이다. 거의 모든 프로그래밍 패러다임은 바로 이 관심의 분리 과정을 통해 문제영역(problem domain)을 독립적인 모듈로 분해한다. 절차적 프로그래밍에서는 분리된 관심을 프로시저로 구성하고OOP에서는 이를 클래스로 작성한다. 여기서 AOP는 OOP를 적용한다고 할지라도 충분히 분리해 낼 수 없는 부분이 있다는 문제제기에서 출발한다.

AOP에서 주목하고 있는 부분은 OOP와 같은 모듈화가 뛰어난 방법을 사용하더라도 결코 쉽게 분리된 모듈로 작성하기 힘든요구사항이 실제 애플리케이션 설계와 개발에서 자주 발견된다는 점이다. AOP에서는 이를 횡단 관심(crosscuttingconcerns)이라고 한다. 이에 대비해서 해당 시스템의 핵심 가치와 목적이 그대로 드러난 관심 영역을 핵심 관심(coreconcerns)이라고 부른다. 이 핵심 관심은 기존의 객체지향 분석/설계(OOAD)를 통해 쉽게 모듈화와 추상화가 가능하다.하지만 횡단 관심은 객체지향의 기본 원칙을 지키면서 이를 분리해서 모듈화하는 것이 매우 어렵다.

이는 횡단 관심의 특징을 모듈로 구현하는 것이 어렵기 때문이 아니다. 문제는 그 구현된 모듈이 다른 핵심 관심을 구현한 모듈과매우 긴밀하게 결합되어 있기 때문이다. 심지어는 어떤 시스템 영역의 모든 모듈과 연동되어야 하는 경우마저 있다. 그래서 기존의핵심 관심을 구현한 모듈과 달리 횡단 관심은 그 구현 시점에서 그 분리가 쉽지가 않다. 기존의 OOP 언어와 기술로는 뾰족한답이 안 나오는 것이다.

대부분의 엔터프라이즈급 애플리케이션은 로그작성(logging)과 보안/인증(security/authentication),트랜잭션(transaction), 리소스 풀링(resource pooling), 에러 검사(error checking), 정책적용(policy enforcement), 멀티쓰레드 안전관리(multithread safety), 데이터 퍼시스턴스(datapersistence) 등의 적용이 필요하다. 이러한 관심들은 애플리케이션의 핵심 관심과 다른 형태로 존재한다.

예를 들어 은행 업무를 처리하는 시스템을 생각해보면 핵심 관심은 예금입출금, 계좌간이체, 이자계산, 대출처리 등으로 구분할 수있다. 이는 전체 애플리케이션의 핵심요구사항과 기능들을 구분해서 모듈화할 수 있고 OOP에서라면 클래스와 컴포넌트 형태로 구성이가능하다. 각각 모듈화된 클래스들은 추상화 등의 작업을 통해 서로 느슨한 연결 상태(loosely coupled)로 만들어서일부 모듈을 타 시스템에서 재활용할 수 있고, 또 구현의 확장이나 교환도 쉽게 가능하다. 객체지향 기술이 우리에게 준 비전이바로 이러한 코드의 모듈화와 추상화를 통해 간결하고 깔끔한 코드 작성이 가능하고 재활용성을 뛰어나게 해주는 것이다.

<그림 1> 프로그래밍 패러다임의 변화

하지만 현실은 그렇지 못하다. 실제로 개발되어 돌아가는 은행 업무의 각 모듈에는 사실 해당 업무를 처리하기 위한 내용만존재해서는 불완전할 수밖에 없다. 일단 각 업무를 처리하는 클래스와 구현된 메쏘드에는 향후 시스템을 분석하거나 추적을 위해로그를 작성하는 기능이 필요하다. 또 인증 받은 사용자가 접근하는지를 체크하고 권한 여부를 따지는 보안 기능이 필요하다. 거기다내부에서 사용하는 퍼시스턴스 처리를 위해 트랜잭션을 시작하고, 또 필요에 따라서 그것을 커밋 또는 롤백하는 부분도 들어가야한다. 예외 상황이나 문제가 발생했을 때는 그것을 기록에 남기는 부분도 있어야 하고, 필요하면 관리자에게 이메일을 발송해야한다. 어떤 경우는 특정 업무를 사용하는 사용자의 패턴을 분석하기 위해 통계처리를 위한 기능도 포함 돼야 한다.

이러한 부가적인 기능들은 각각 구현을 독립적인 클래스로 작성될수 있지만 그렇게 구현된 기능들을 호출하고 사용하는 코드들이 핵심모듈 안에 필요한 영역에 모두 포함될 수밖에 없다. AOP를 적용하지않은 OOP에 의해서만 작성된 간단한 계좌이체 처리를 위한클래스의 구성을 살펴보자.

로깅, 인증, 권한체크, DB 연동, 트랜잭션, 락킹, 에러처리 등의 기능을 아무리 뛰어난 OOP 기술을 이용해 모듈로 구성하고추상화를 통해 최대한 독립시킨다고 해도 <리스트 1>에서 보듯이 핵심 모듈의 모든 클래스와 메쏘드 속에 이와 연동되는부분이 매우 깊이 그리고 상당한 양을 갖으면서 자리 잡고 있다. 실전에서 사용되는 핵심 모듈 클래스들은 이보다 더 복잡하면복잡했지 더 단순하지는 않을 것이다. 이 코드에서 핵심기능을 담당하고 이 클래스가 설계된 바탕의 핵심 관심을 구현하는 코드는 단다섯줄에 불과하다. 하지만 그 외의 부가적인 코드를 포함하지 않으면 엔터프라이즈급 애플리케이션으로는 쓸모없을 수밖에 없다.

<그림 2> 횡단 관심

이러한 횡단 관심을 구현하고 또 그 모듈과 연동이 되는 코드들이 거의 모든 핵심 모듈에 다양한 형태로 존재할 수밖에 없다.실제로 모듈화가 잘 된 애플리케이션 클래스를 보더라도 핵심기능을 위한 코드보다 이런 저런 부가적인 기능과 처리를 위한 부분의양이 더 많아지그런데 만약 이렇게 개발된 클래스가 한 수천 개가 되고 대부분이 앞의 코드와 갈이 작성됐다고 했을 때 어느 날새로운 은행 캠페인이 시작되어서 각 메쏘드에서 사용되는 계좌정보에서 내용을 뽑아내어 통계처리를 하도록 새로운 요구사항이 생겼다면어떻게 해야 하겠는가?

그와 관련된 모든 클래스들을 찾아 <리스트 1>과 같은 코드 틀 안에 또 새로운 통계처리용 코드를 삽입하는 수밖에없다. 또 만약 다른 종류의 로깅플랫폼을 사용해 로그처리하는 클래스와 메쏘드가 달라지고 로그 메시지가 변경이 되었다면? 또개발자들은 모든 클래스 안에 있는 로그관련 코드를 일일이 다 수정해 주는 수밖에 없다. 그러다가 만약 중요한 클래스에서 한두군데 로그기록 코드가 빠졌고 이로 인해 결과를 확인하는데 문제가 생겼다면? 이를 다시 확인하고 찾아내는 일만 해도 엄청난 작업이아닐 수 없을 것이다.는 것이 현실이다.

더 나아가서 이렇게 OOAD와 OOP를 이용해 개발한 시스템의 일부 모듈을 타 은행에서 재활용하고 싶다고 생각해보자. 과연이것이 가능한가? 아마 매우 어려울 것이다. 객체지향 기술이 코드의 재활용성을 높여줄 수 있다는 것은 이론적으로는 맞는 일이지만현실적으로는 복잡하게 섞여있는 횡단 관심 코드로 인해 이 부분을 다 수정하기전에는 다른 환경에서 같은 핵심기능을 처리하는 코드를사용한다는 것은 불가능하다. AOP가 적용되지 않은 방식의 프로그램 코드에서 보면 핵심 관심 모듈에서 횡단 관심 모듈을 찾고사용하는 구조로 작성되어있다. 이렇게 작성된 애플리케이션은 몇 가지 심각한 문제를 가지고 있다.


 <리스트 1> AOP를 적용하지 않은 간단한 계좌이체 처리 클래스


◆ 중복되는 코드 : 복사&붙이기에 의해 만들어진 여러 모듈에서 중복되는 코드의 문제점은 이미 잘 알려져 있다. 하지만 AOP를 사용하지 않은 대부분의 애플리케이션에서는 어떠한 추상화와 리팩토링을 통해서도 반복되는 코드를 피하기가 어렵다.

◆ 지저분한 코드 : 횡단 관심과 관련된 코드들이 핵심기능 코드 사이사이에 끼어들어가 있기 때문에 코드가 지저분해지고 이에 따라 가독성이 떨어지며 개발자들의 실수나 버그를 유발하고 후에 코드를 유지보수하는데 큰 어려움을 준다.

◆ 생산성의 저하 : 문제영역에 대한 지식과 분석을 토대로 이를구현해야 하는데 충실해야 하는 애플리케이션 개발자들이 자주 등장하는 횡단 관심을 구현한 코드를 함께 작성해야 하기 때문에 개발의집중력을 떨어뜨리고 결과적으로 전체 생산성의 저하를 가져온다. 또 모듈별로 개발자들을 구분하고 분산시키는 것이 한계를 가질수밖에 없다.

◆ 재활용성의 저하 : 이미 언급했듯이 OOP의 장점인 재활용성이 매우 떨어진다.

◆ 변화의 어려움 : 한번 작성된 시스템은 새로운 요구사항이생겼을 경우에 전체적으로 많은 부분에 영향을 미치는 경우 쉽게 새로운 요구사항을 적용하기 힘들게 된다. 또 새로운 관심영역의등장이나 이의 적용을 매우 어렵게 한다. 좋은 툴의 도움 없이는 리팩토링을 하는 것도 어렵게 된다.

이러한 문제점을 AOP를 적용하면 어떻게 될 것인지 <리스트 1>의 클래스를 만약 AOP를 이용한 시스템에서 작성을 했을 때의 코드로 살펴보자.

public class AccountTransfer extends AbstractAccountModule {
 public void transafer(Accouno fromAcc, Account toAcc, int amount) {
  if (fromAcc.hasEnoughMoney(amount) == false) {
   throw new AccountException(“not enough money”);
  }
  fromAcc.withdraw(amount);
  toAcc.credit(amount);
 }

}

놀랍게도 AOP를 적용하지 않았을 때의 코드에 비해 매우 심플한 구조로 바뀌었다. 계좌이체 모듈을 객체지향적으로 설계했을 때 그설계에 나오는 핵심기능 코드만 존재하게 된 것이다. 그럼 이렇게 작성된 코드가 앞에서 작성된 코드와 똑같은 기능과 방식으로동작할수 있는 것인가? 그렇다. 새로운 캠페인을 위한 통계코드나 로깅모듈이 바뀌는 일이 일어나도 이 핵심 관심 코드는 결코변하지 않는다. 문제영역 자체가 바뀌지 않는 한 이 코드는 그대로 사용할 수 있다. 만약 같은 요구조건과 기능을 가진 다른은행이 이 코드를 가져다 쓰고 싶더라도 거의 코드에 손을 대지 않고 재사용이 가능하다. 물론 로그, 보안, 인증, 퍼시스턴스등의 처리 방법과 환경이 완전히 달라진다고 해도 상관없다.

<그림 3> 위빙

그렇다면 그 많은 로그 처리와 보안, 트랜잭션 관리, 예외상황 처리등의 코드는 어디로 간 것인가? 그 부분은 독립된 형태의 단일 모듈로 각각 작성이 되고 AOP를 통해서 필요한 시점에서 핵심 코드에 삽입되어져 동작하게 된다.

AOP의 동작원리
AOP가 핵심 관심 모듈의 코드를 직접 건드리지 않고 필요한 기능이 작동하도록 하는 데는 위빙(weaving) 또는크로스컷팅(crosscutting)이라고 불리는 특수한 작업이 필요하다. 핵심 관심 모듈이 자신이 필요한 횡단 관심 모듈을 찾아사용하는 대신에 AOP에서는 위빙 작업을 통해 핵심 관심 모듈의 사이사이에 필요한 횡단 관심 코드가 동작 하도록 엮어지게만든다. 이를 통해 AOP는 기존의 OOP로 작성된 코드들을 수정하지 않고도 필요한 횡단 관심 기능을 효과적으로 적용해 낼 수있다.

이런 작업은 기존의 자바 언어와 컴파일러에서는 쉽게 구현할 수 있는 방법이 아니다. 현재의 AOP 언어와 툴이 개발되기 전에는크게 두 가지 방법으로 AOP와 비슷한 기능을 구현해보려는 시도가 있었다. 첫째는 EJB와 같은 컨테이너 또는 서버를 이용한방법이다. EJB는 트랜잭션과 보안, 오브젝트 풀링과 같은 횡단 관심 기능을 컨테이너를 통해 그 위에서 동작하는 EJB 모듈에적용하고 있다. 일종의 엔터프라이즈 서비스 기능인 EJB의 이러한 처리 방식은 EJB가 엔터프라이즈급 애플리케이션 개발과 운영에적극적으로 수용되는 만큼 중요한 이유 중의 하나이다. 하지만 EJB는 제공할 수 있는 서비스가 매우 제한적이고 임의의 서비스추가 등이 불가능하기 때문에 본격적인 AOP 방법으로 사용되기는 어렵다. 더군다나 컨테이너 위에서만 특별한 스펙에 따라 작성된코드와만 연동해서 동작하기 때문에 POJO(Plain Old Java Objects) 기반의 일반 애플리케이션에는 적용하기가불가능하다.

두 번째 시도된 방법은 JDK 1.3부터 지원되기 시작한 다이내믹 프록시(Dynamic Proxy)를 이용한 인터셉터체인(interceptor chain)기술이다. JBoss를 비롯한 컨테이너 개발자들을 통해 많이 사용된 방식이다. 하지만다이내믹 프록시를 이용한 코드는 구현이 매우 복잡하고 특정 구조의 애플리케이션 틀을 따라 작성되어야만 적용 가능하며, 역시복잡한 프레임워크 내지는 컨테이너의 도움이 필요하다는 면에서 쉽게 일반화되지는 못했다.

본격적인 AOP 기술이 등장한 것은 1990년대 후반 제록스 PARC 연구소에서 그레거 킥제일(Gregor Kiczales)에의해 AspectJ가 개발되면서라고 볼 수 있다. 그는 Asepct라는 용어와 함께 AOP라는 표현을 처음 사용하기 시작했고,자바 VM과 호환되는 최초의 AOP 툴인 AspectJ를 구현해 냈다. AspectJ는 자바의 언어를 확장한 형태의 구조로개발됐는데 자바의 클래스와 유사한 개념인 AOP의 애스팩트(Aspect)를 작성하는 방법을 통해 AOP의 기능을 사용할 수있도록 했다. 이렇게 만들어진 애스팩트는 AspectJ의 특별한 컴파일러를 통해 자바 VM에서 사용될 수 있는 코드로만들어진다. 바로 이때 AOP의 위빙 작업이 일어난다. 위빙 작업을 통해 핵심 관심 모듈의 사이사이에 애스팩트 형태로 만들어진횡단 관심 코드들이 삽입되어 애스팩트가 적용된(woven) 최종 바이너리가 만들어지는 것이다.

AOP를 이용하면 개발자들은 횡단 관심 모듈을 각각 독립된 모듈로 중복 없이 작성하고 이를 위빙을 통해 핵심 관심 모듈과결합시키기 때문에 서로 독립성을 가진 다 차원의 모듈을 작성할 수 있다. 앞에서 작성한 AccountTransfer 클래스에적용할 메쏘드 처리의 시작과 끝을 기록하는 로그 작성용 애스팩트의 코드를 살펴보자.

public aspect MethodLoggingAspect {
 Logger logger = MyLog.getLogger(“methodcall”);
 pointcut methodcall() : execution (void AccountTransfer.transfer(..)) &&
  !within(MethodLoggingAspect);
 before() : methodcall() {
  logger.begin(thisJoinPointStaticPart.getSignature().getName());
 }
 after() : methodcall() {
  logger.end(thisJoinPointStaticPart.getSignature().getName());
 }
}

기존의 자바 언어의 문법을 확장한 구조를 가지는 AspectJ에서는 횡단 관심 모듈을 aspect라는 키워드를 가지는 코드로작성이 가능하다. 앞의 MethodLoggingAspect를 작성한 후 AspectJ의 컴파일러를 사용해 컴파일을 하고AccountTransfer의 transfer() 메쏘드를 실행시키면 메쏘드의 실행 전후에 메쏘드의 시작과 끝을 알리는 로그가만들어진다.

이렇게 만들어진 애스팩트는 기존의 코드에 전혀 영향을 주지 않고 자연스럽게 위빙되기 때문에 핵심 관심 모듈을 개발하는 개발자들은이 부분을 전혀 고려하지 않고 그 모듈 자체의 로직에만 충실히 작성하고 후에 필요한 애스팩트를 만들어 적용할 수 있다. 앞의애스팩트 코드는 AccountTransfer 클래스의 transfer 메쏘드에만 적용하도록 한 것이다. 필요하면 포인트컷을적용해서 애플리케이션 내의 모든 메쏘드에 로그를 남기는 애스팩트가 위빙되도록 할 수 있다. 간단히 포인트컷 시그니처만 수정해주면된다.

    pointcut methodcall() : execution(* *.*(..)) && !within(MethodLoggingAspect)

이제 그 숫자와 상관없이 모든 애플리케이션의 메쏘드의 시작과 끝을 로그로 남길 수 있게 되었다. 만약 로그를 작성하는 코드가달라져야 한다면 이제는 애스팩트만을 수정해주는 것으로 모든 메쏘드의 로깅 방법을 한 번에 변경할 수 있다. AOP를 사용하지않고 일일이 모든 메쏘드의 로그 코드를 수정했던 것과 비교하면 굉장히 편리해졌음을 알 수 있다.

AOP의 구성요소
AOP에는 새로운 용어가 많이 등장한다. 이 중에서 특히 AOP를 이용해서 개발하는데 필요한 중요한 구성요소들에 대한 정의를 정확히 이해해야 한다.

조인포인트
횡단 관심 모듈의 기능이 삽입되어 동작할 수 있는 실행 가능한 특정위치를 말한다. 예를 들어 메쏘드가 호출되는 부분 또는리턴되는 시점이 하나의 조인포인트(jointpoint)가 될 수 있다. 또 필드를 액세스하는 부분, 인스턴스가 만들어지는 지점,예외가 던져지는 시점, 예외 핸들러가 동작하는 위치, 클래스가 초기화되는 곳 등이 대표적인 조인포인트가 될 수 있다. 각각의조인포인트들은 그 안에 횡단 관심의 기능이 AOP에 의해 자동으로 추가되어져서 동작할 수 있는 후보지가 되는 것이다.

포인트컷
포인트컷(pointcut)은 어떤 클래스의 어느 조인포인트를 사용할 것인지를 결정하는 선택 기능을 말한다. AOP가 항상 모든모듈의 모든 조인포인트를 사용할 것이 아니기 때문에 필요에 따라 사용해야 할 모듈의 특정 조인포인트를 지정할 필요가 있다.일종의 조인포인트 선정 룰과 같은 개념이다. AOP에서는 포인트컷을 수행할 수 있는 다양한 접근 방법을 제공한다.AspectJ에서는 와일드카드를 이용한 메쏘드 시그니처를 사용한다.

어드바이스 또는 인터셉터
어드바이스(advice)는 각 조인포인트에 삽입되어져 동작할 수 있는 코드를 말한다. 주로 메쏘드 단위로 구성된 어드바이스는포인트컷에 의해 결정된 모듈의 조인포인트에서 호출되어 사용된다. 일반적으로 독립적인 클래스 등으로 구현된 횡단 관심 모듈을조인포인트의 정보를 참조해서 이용하는 방식으로 작성된다. 인터셉터(intercepter)는 인터셉터 체인 방식의 AOP 툴에서사용하는 용어로 주로 한 개의 invoke 메쏘드를 가지는 어드바이스를 말한다.

위빙 또는 크로스컷팅
포인트컷에 의해서 결정된 조인포인트에 지정된 어드바이스를 삽입하는 과정이 위빙이다. 위빙은 AOP가 기존의 핵심 관심 모듈의코드에 전혀 영향을 주지 않으면서 필요한 횡단 관심 기능을 추가할 수 있게 해주는 핵심적인 처리과정이다. 다른 말로크로스컷팅(crosscutting)이라고 하기도 한다. 위빙을 처리하는 방법은 후처리기를 통한 코드생성 기술을 통한 방법부터특별한 컴파일러 사용하는 것, 이미 생성된 클래스의 정적인 바이트코드의 변환 또는 실행 중 클래스로더를 통한 실시간 바이트코드변환 그리고 다이내믹 프록시를 통한 방법까지 매우 다양하다.

인트로덕션 또는 인터타입 선언
인트로덕션(Introduction)은 정적인 방식의 AOP 기술이다. 동적인 AOP 방식을 사용하면 코드의 조인포인트에어드바이스를 적용해서 핵심관심 코드의 동작 방식을 변경할 수 있다. 인트로덕션은 이에 반해서 기존의 클래스와 인터페이스에 필요한메쏘드나 필드를 추가해서 사용할 수 있게 해주는 방법이다. OOP에서 말하는 오브젝트의 상속이나 확장과는 다른 방식으로어드바이스 또는 애스팩트를 이용해서 기존 클래스에 없는 인터페이스 등을 다이내믹하게 구현해 줄 수 있다.

애스팩트 또는 어드바이저
애스팩트(aspect)는 포인트컷(어디에서)과 어드바이스(무엇을 할 것인지)를 합쳐놓은 것을 말한다. 필요에 따라서 인트로덕션도포함할 수 있다. AspectJ와 같은 자바 언어를 확장한 AOP에서는 마치 자바의 클래스처럼 애스팩트를 코드로 작성할 수있다. AOP 툴의 종류에 따라서 어드바이스와 포인트컷을 각각 일반 자바 클래스로 작성하고 이를 결합한 어드바이저 클래스를만들어서 사용하는 방법도 있다.

대표적인 AOP 툴
AOP는 OOP의 확장에 가깝기 때문에 전용 언어나 독립된 개발 툴을 가지고 있지 않고 대신 기존의 OOP를 확장한 언어확장(languageextension) 또는 툴이나 프레임워크 형태로 사용할 수 있게 되어 있다. 현재 자바에서 사용할 수 있게구현된 AOP의 숫자는 10여개가 된다. 하지만 이 중에서 주로 사용되는 대표적인 AOP 솔루션은 4가지 정도를 꼽을 수 있다.대표적으로 AOP 구현의 시초가 된 이클립스 프로젝트의 AspectJ를 들 수 있다.

AspectJ는 초기에 제록스 PARC 연구소에서 개발되었다가 2002년에 이클립스 프로젝트에 기증되었고, 현재 IBM의전폭적인 지원을 받으면서 개발되어 사용되고 있다. 그리고 BEA가 중심이 되어 개발하고 있는 AspectWerkz가 있다.AspectWerkz는 AspectJ와 달리 자바 언어 자체를 확장하지 않고 기존의 자바 언어만으로 AOP의 사용이 가능하도록되어 있다. 그리고 의존성 삽입(Dependency Injection, 이하 DI) 기반의 프레임워크로 유명한SpringAOP가 있다. 가장 최근에 등장한 AOP로는 JBossAOP도 있다. SpringAOP와 함께 대표적인 인터셉터체인방식의 AOP로 꼽힌다.

<표 1> AOP 툴의 비교

이렇게 많은 AOP 툴이 존재하는 이유는 아직 AOP가 표준 스펙이나 기준이 없이 현장을 중심으로 빠르게 진화하고 있는 기술이기때문이다. 기본적인 AOP에 개념은 비슷하지만 실제 구현하는 방법이나 적용 기술은 상당한 차이가 있다. 이 중에서 무엇이 제일나은 자바 기반의 AOP 하나를 선정하기는 어렵다. 그 이유는 AOP가 사용되는 방식과 목적, 환경에 따라 각기 다른 장단점을가지고 있기 때문이다. 이렇게 다양한 툴이 존재하는 것이 처음 AOP를 접근하는 개발자들에게는 부담이 되는 것이 사실이다.하지만 각각의 AOP가 끊임없이 새로운 기능을 시도하고 발전하는 과정을 통해 AOP가 더욱 견고하고 풍부한 기능을 가질 수 있을것을 기대해 볼 수 있을 것이다.

AspectJ
AspectJ의 가장 큰 특징은 다른 AOP 툴과는 달리 자바 언어를 확장해서 만들어진 구조라는 것이다. 마치 새로운 AOP언어를 사용하듯이 aspect라는 키워드를 이용해 애스팩트나 포인트컷, 어드바이스를 만들 수 있다. 따라서 일반 자바컴파일러로는 컴파일이 불가능하고 특별한 AOP 컴파일러를 사용해야 한다. 하지만 이렇게 만들어진 바이너리는 표준 JVM에서 동작가능한 구조로 되어있기 때문에 특별한 클래스 로더의 지원 없이도 실행 가능하다.

AspectJ는 가장 오래되고 가장 많이 사용되는 AOP 툴이다. 동시에 가장 풍부한 기능을 가지고 있고 확장성이 뛰어나기때문에 가장 이상적인 AOP 툴로 꼽히고 있다. 하지만 자바 언어를 확장했기 때문에 새로운 문법과 언어를 이해할 필요가 있고프로젝트 빌드시 특별한 컴파일러를 사용해야 하는 불편함이 있다. 위빙이 컴파일시에 일어나기 때문에 포인트컷에 의해 선택된 모든클래스들은 애스팩트가 바뀔 때마다 모두 다시 컴파일이 되어야 한다.

AspectJ는 가장 오래되고 가장 많이 사용되는 AOP 툴이다. 동시에 가장 풍부한 기능을 가지고 있고 확장성이 뛰어나기때문에 가장 이상적인 AOP 툴로 꼽히고 있다. 하지만 자바 언어를 확장했기 때문에 새로운 문법과 언어를 이해할 필요가 있고프로젝트 빌드시 특별한 컴파일러를 사용해야 하는 불편함이 있다. 위빙이 컴파일시에 일어나기 때문에 포인트컷에 의해 선택된 모든클래스들은 애스팩트가 바뀔 때마다 모두 다시 컴파일이 되어야 한다.

AspectWerkz
AspectWerkz는 AspectJ와는 달리 자바 언어를 확장하지 않는다. 따라서 표준 자바 클래스를 이용해서 AOP를 구현해낼 수 있다. 일반 클래스와 메쏘드를 이용해 쉽게 구현이 가능한 어드바이스와 달리 복잡한 문법이 필요한 포인트컷은 별도의 XML파일을 이용해 설정할 수 있도록 되어 있다. 자바 클래스와 XML 설정 파일의 접근법에 익숙한 개발자들에게는 매우 편리한 접근방식이라고 볼 수 있다.

최근에는 JDK5의 지원에 따라 어노테이션을 이용할 수 있어 더욱 편리해졌다. 위빙은 특별한 클래스 로더를 이용한 로딩타임바이트코드 생성을 이용한다. AspectJ 못지않은 다양한 조인포인트와 AOP기능을 지원하고 있으며 편리한 개발을 위한 IDE플러그인이 개발되어 있다.

JBossAOP
JBossAOP는 앞의 두 가지 툴과 달리 프록시를 이용한 인터셉터 체인을 활용해서 위빙을 처리하는 것이 특징이다. 필요에따라서 JavaAssist를 통한 바이트코드 조작을 이용하기도 한다. JBossAOP는 원래 JBoss 서버의 EJB를 위한인터셉터 체인 기술을 통해 발전해 왔다. JBoss는 최초로 디플로이 시점의 코드 생성이 아닌 인터셉터 체인을 이용한 방식으로EJB 호출과 그 사이에 필요한 엔터프라이즈 서비스 기능의 삽입을 구현해냈고 이를 발전시켜 왔다. 최근 EJB3나 하이버네이트와같은 POJO 기반의 엔터프라이즈 개발이 활발해지면서 좀 더 범용적으로 AOP를 사용할 수 있는 형태로 JBossAOP를개발했다.

JBossAOP는 기본적으로 컨테이너에서 동작하지만 컨테이너와 상관없는 독립된 자바 프로그램에서도 사용할 수 있다. 하지만 주용도는 JBoss 서버와 앞으로 나올 EJB3 컨테이너 등에 AOP를 적용하는 데에 사용되어지는 것이다. AspectWerkz와마찬가지로 어드바이스는 표준 자바 코드로 작성하고 포인트컷과 다른 설정은 XML 파일이나 JDK5의 어노테이션으로 작성할 수있다. 아직까지는 JBoss 사용자의 일부에서만 사용되고 있으나 향후 EJB3를 중심으로 한 POJO 기반의 엔터프라이즈미들웨어 프레임워크가 개발되어짐에 따라 점차로 사용률이 올라갈 것으로 기대된다.

SpringAOP
SpringAOP는 스프링 프레임워크의 핵심기능 중의 한가지로 스프링의 DI 컨네이너에서 동작하는 엔터프라이즈 서비스에서 주로사용된다. SpringAOP는 다른 AOP와 달리 기존 클래스의 바이트코드를 수정하지 않는다. 대신 JDK의 다이내믹 프록시를사용해서 프록시방식으로 AOP의 기능을 수행한다. 이 때문에 다른 AOP의 기능과 비교해서 매우 제한적인 부분만을 지원한다.

하지만 SpringAOP의 구현 목적은 엔터프라이즈 애플리케이션에서 주로 사용되는 핵심적인 기능에 AOP의 장점을 살려 이를스프링내에서 사용하는 것이기 때문에 다른 AOP와 같은 AOP의 복잡한 전체 기능을 굳이 다 필요로 하지 않는다. 프록시 기반의SpringAOP는 SpringIoC/DI와 매우 긴밀하게 연동이 된다. 따라서 SpringAOP를 사용하는 방법은 스프링 내에프록시 빈을 설정해서 쉽게 사용할
수 있다.

JDK의 표준 기능만을 사용하기 때문에 특별한 빌드 과정이 필요없고 클래스 로더를 변경한다거나 하는 번거로운 작업이 없다. 대신조인포인트가 종류가 메쏘드 기반으로 제한되며 같은 클래스 안의 메쏘드 호출이나 콜백 코드를 사용했을 경우에는 프록시를 적용할 수없는 단점이 있다. 하지만 대부분의 엔터프라이즈 애플리케이션에서 필요로 하는 주요 AOP 기능들을 메쏘드 호출을 기반으로 충분히처리가 가능하기 때문에 SpringAOP는 그 제한된 AOP 기능에도 불구하고 현장에서 가장 빠른 속도로 적용되어 사용되는AOP 솔루션 중의 하나이다. SpringAOP는 어드바이스와 포인트컷을 모두 표준 자바 클래스로 작성할 수 있다.

필요에 따라서 포인트컷은 설정 파일 내에서 포인트컷 팩토리 빈을 이용해서 정규식으로 표현이 가능하다. SpringAOP의 최대단점은 복잡한 프록시 설정 구조이다. Spring빈을 정의한 파일에서 프록시를 정의한 부분의 다른 XML기반의 AOP에 비해서도복잡한 편인데 이 경우 SpringAOP가 지원하는 AutoProxyingCreatorBean 등을 이용하면 설정 코드를 매우단순하게 작성하는 것이 가능하다.

AOP의 과제
지난 5년간 AOP가 등장하고 현장에 적용되면서 항상 모든 개발자들에게 좋은 반응만 얻은 것은 아니다. 오히려 OOP에 익숙한많은 개발자들과 학자, 연구원들에게서 강한 저항을 느낄 수 있을 정도로 반발이 있었다. AOP를 반대하는 대표적인 사람이 자바의창시자인 제임스 고슬링(James Gosling)인데 그는 AOP가 자바의 OOP 정신과 원칙을 훼손하고 그로인해 실전에서개발자들에게 도움이 되기보다는 어려움을 주는 문제를 안고 있다고 비판한다.

하나의 새로운 프로그래밍 패러다임이 등장하고 발전하면서 완전히 자리를 잡아가기까지는 그만큼 충분한 시간이 필요할 것이고, 그이전 세대 패러다임과의 적지 않은 충돌을 예상해야 하는 것은 분명하다. AOP는 다른 프로그래밍 패러다임보다 훨씬 빠른 시간에현장 실무에 적용되고 자리를 잡아나가고 있고 많은 개발자들의 호응에 힘입어 놀라운 성장을 보여주고 있음에도 주류 기술로 자리잡기 위해서는 해결해야 할 여러 문제점과 극복할 장벽을 가지고 있는 것이 사실이다.

표준의 부재
AOP는 현재 정해진 표준이 없으며 표준을 정할 기구나 조직도 없다. 용어부터 시작해서 문법, 구현 방법에 이르기까지 AOP와관련해서 통일된 것이 없다. 따라서 AOP 툴을 만드는 팀과 업체에 따라서 그 내용과 형식이 상당히 차이가 나는 경우도 있다.비록 기본적인 개념은 공유하고 있다고 하지만 접근 방법이 차이가 나는 것은 AOP가 프로그래밍 표준 기술로 자리 잡는데 많은장애가 될 수밖에 없다. 이로 인해 처음 AOP를 접하는 개발자들이나 AOP를 공부하려는 사람들에게 혼란을 안겨 주기도 한다.

이런 와중에 AOSD(Internationl Conference on Aspect Oriented SoftwareDevelopment)와 같은 행사들이 꾸준히 열리면서 AOP 연구자들과 툴 개발팀, 개발자들 사이에 많은 의견을 모으고 표준을위한 노력이 시작되었다는 것은 반가운 소식이다. 또한 최근 AOP툴 업체들 간에 협력이나 통합 구조가 가시적으로 보이고 있다는것 또한 매우 좋은 현상이라고 본다. 특히 올해 들어 대표적인 AOP 툴인 AspectJ와 AspectWerkz가 협력해서통합된 AOP 툴을 만들기로 하고 지금 작업이 진행 중이라는 사실은 매우 고무적이다.

게다가 최근 AspectJ 프로젝트를 이끄는 핵심 개발자인 아드리안 콜리어(Adrian Colyer)가 그동안 몸담고 있으면서AspectJ를 개발해 왔던 IBM을 떠나 SpringAOP를 만든 Interface21에 합류하게 되었다. 이로 인해 3개의AOP 툴의 장기적인 통합도 기대할 수 있을 것 같다. 하지만 한편으로는 표준을 빨리 제정하기 보다는 아직은 AOP는 발전하고진화해야 하는 단계에 있기 때문에 다양한 창조적인 시도들이 가능한 현 상태가 어느 정도 더 유지되어져야 할 것이라는 의견도 있다.

학습의 어려움
현장에서 AOP를 접해온 개발자들의 가장 큰 AOP에 대한 비판은 AOP가 너무 어렵다는 것이다. AOP를 배우는 것은 기존OOP에 대한 완벽한 지식을 바탕으로 한다고 해도 사실 상당한 발상의 전환이 필요하고 그 개념이 난해한 부분이 많다. 새로운용어들에 익숙해지고 그 의미를 정확히 파악하는 것 또한 만만한 것이 아니다. 게다가 이를 기존 애플리케이션에 어떻게 적용해야할지그 적용 방법과 아이디어를 내는 것도 수월하지 않다. 더 나아가서 AOP로 개발된 애플리케이션을 보고 이해하는 것도 어려움이있다고 지적한다.

학습과 적응의 어려움은 OOP가 등장하고 현장에 적용되던 초기와 다를 바 없다고 생각된다. 프로시저 기반의 프로그래밍에 익숙한개발자들에게 객체지향 언어와 개념은 매우 난해했고 상당한 시간이 지나기까지 개발자들이 매우 어려워했던 것은 사실이다. 아직도OOP의 개념과 원리에 대해서 또는 OOAD에 대해 힘들어 하는 개발자가 많은 게 사실이다. AOP도 또한 초기에는 그러한적응의 과정이 필요할 것이다. 더 많은 개발자들과 이론가들이 충분히 그 기술과 개념에 익숙해져야 할 시간이 필요할 것이고, 또AOP 기반의 애플리케이션을 설계하고 구현하는데 필요한 다양한 방법론과 설계 기술들이 등장하게 될 것이라고 보여 진다.

문제는 후자의 경우인데 AOP로 만든 프로그램은 프로그램의 흐름을 이해하고 추적하기가 매우 힘들다는 주장이다. 이는 AOP에대한 오해에서 비롯된 주장이라고 보여진다. 필자를 포함해서 많은 AOP를 이용해서 애플리케이션을 개발하는 개발자들의 공통적인의견은 AOP를 적용한 후가 그렇지 않을 때에 비해 애플리케이션의 구성과 코드가 깔끔해졌고 그로 인해 전체 애플리케이션을이해하고 교육하고 유지보수하기가 한결 쉬워졌다는 것이다. 물론 AOP는 매우 다차원적으로 시스템을 이해하고 접근하기 때문에 역시해석 또한 다차원적이어야 한다는 부담감이 있다. 대신에 각 차원의 독립된 관점에 따라서 애플리케이션을 살펴보고 이를 통합해서생각하는 훈련만 된다면 이전에 많은 다른 차원의 코드들이 섞여있던 때에 비해 애플리케이션에 대한 이해는 훨씬 수월해질 것이라고기대된다.

OOP와의 충돌
AOP의 비판자들 중 상당수는 AOP가 OOP의 정신을 훼손하고 OOP의 중요 원칙을 깨뜨린다고 한다. 이 부분은 아직도 많은논쟁이 진행중인 부분이다. 대표적으로 AOP는 OOP의 캡슐화를 깨뜨리고 객체의 내부에 직접적인 영향을 줄 수 있기 때문에객체지향적인 장점을 손상하고 시스템을 복잡하게 만든다고 한다. 기존의 클래스와 코드의 어떤 부분에라도 영향을 줄 수 있다는면에서 일견 일리가 있는 주장이다. 하지만 AOP가 없이 그러한 횡단관심 기능을 핵심 모듈 내부에 직접 작성해서 쓰는 것은 과연객체지향의 원칙에 맞는 일인가? 그게 아니라면 현실적으로 객체지향적인 방법으로 그 부분을 해결할 수 있는 효과적인 방법을제시해야 할 것이다. 결국 OOP의 한계와 약점이있는 곳에서 AOP가 출발하기 때문에 이것을 노골적으로 드러내는 AOP가OOP와 충돌하는 것은 어쩔 수 없는 현실이라고 본다.

다만 AOP 만능주의자가 되어 OOP적인 바른 접근과 설계를 뒷전으로 하는 것은 진정한 AOP가 아니라고 생각된다. AOP가가장 큰 영향을 줄 수 있는 것 중의 하나는 개발방법론을 비롯한 소프트웨어 디자인과 아키텍팅 부분이다. 기존의 BUFD(BigUp Front Design)에 익숙한 객체지향 아키텍트는 딜레마에 빠지기가 쉬운데 이는 초기디자인은 어느 정도까지 하는 것이적당한 것인지 항상 고민하기 때문이다. 너무 과도한 디자인은 향후 시스템의 개발 과정이나 개발 후에 더욱 발전하거나 변화하는데장애가 되기 때문에 초기 디자인이 어디까지 나아가야 할 것인가 큰 고민일 수밖에 없다. 이런 상황에서 AOP의 도입은 초기디자인의 부담을 크게 덜어 줄 수 있다.

핵심 디자인을 거의 손대지 않고도 시스템 전반에 영향을 주는 횡단 관심 모듈을 독립성 있게 개발하고 전 시스템에 걸쳐 자유롭게삽입, 제거가 가능해지기 때문이다. 따라서 AOP는 XP(Extreme Programming) 방식을 따르는 개발자들에게는상당히 막강한 무기가 되기도 한다. 동시에 전통적인 디자인 우선 방식을 선택한 아키텍트들에게도 많은 도움이 되고 있는 것도사실이다. 여기서 한 가지 AOP에 대한 오해가 생기기 쉬운데 AOP가 잘 설계되지 못한 디자인을 완전하게 만들어 줄 것이라는환상이다. 이는 결코 그렇지 않다. AOP는 이미 잘 설계되어 있는 디자인을 더욱 쉬운 방법으로 적용할수 있게 만들어줄 뿐이다.이런 면에서 AOP를 쓴다고 해서 기존의 OOP적인 설계와 접근방법을 포기하거나 가볍게 여기는 것은 잘못된 선택이 분명하다.

AOP의 미래
AOP는 갑자기 어디서 떨어진 마법의 만능도구는 아니다. 오히려 현장에서 개발에 매진하는 개발자들이 스스로 기존 기술과 방법의문제점을 극복하기 위해 찾아낸 개발자를 위한 도구이다. 모든 소프트웨어 기술이 다 그렇듯이 AOP도 결국 좀 더 효과적인방법으로 더 나은 품질의 제품을 개발하는데 그 존재 가치가 있다. 최근에 불고 있는 POJO 기반의 개발 기술의 열풍은 이러한근본적인 문제에 대한 개발자 스스로의 반성이 현실로 나타난 것이다. 아드리안 콜리어는 POJO 기반의 애플리케이션 개발의 3대기술을 AOP, DI, 어노베이션이라고 하고 이 3가지가 앞으로의 시대를 주도하는 핵심 개발 기술이 될 것이라고 이야기한다.이미 어노테이션은 자바 5의 표준 기술로 자리를 잡았고 의존 삽입 또한 다양한 프레임워크의 지원 하에 매우 빠른 속도로 사실상의표준 기술로 자리 잡고 있다. 이제 AOP가 주류 기술로 자리 잡을 때가 다가왔다고 보여진다. AOP를 통해 더 나은애플리케이션 개발을 경험하는 개발자들이 국내에도 많아지게 되기를 기대해본다.

* 이 기사는 ZDNet Korea의 제휴매체인 마이크로소프트웨어에 게재된 내용입니다.

by 방마루 | 2007/10/26 09:29 | 트랙백 | 덧글(0)

firefox 스크립트 에러시 form이 submit 되는 현상

form 안에서 이벤트가 발생했을때, 해당 이벤트를 처리하는 과정중 예외가 발생하면, form이 submit() 되는 현상이 있었다.

휴... 원인 찾는데 한참을 헤맸다.

혹시나 하고 스크립트 구문의 예상 되는 부분에서

try {
    ...<throws Exception>
}catch (e) {
    alert(e);
    return false;
}



로 원인을 찾을 수 있었다.

firefox가 웹 표준을 준수한다고 하는데...

이 현상이 올바른 것일까??

by 방마루 | 2007/10/24 17:16 | 트랙백 | 덧글(0)

iBatis sqlmap 에 CLOB or BLOB 사용하기

국내 개발자 커뮤니티에선 해답을 찾지못하구 iBatis 홈페이지를 뒤지다 FAQ에서 방법을 찾았다.

역시 어디선가 누군가도 나와 같은 문제에 부딪혔었나보다.

친절하게도 소스까지 설명해주는 쎈스^^

http://opensource.atlassian.com/confluence/oss/display/IBATIS/How+do+I+use+a+BLOB+or+CLOB

by 방마루 | 2007/09/06 09:35 | 프로그래밍 지식 | 트랙백 | 덧글(1)

한국에서 SW 개발자가 성공하지 못하는 세가지 이유

소프트웨어 개발자 직종에 대한 회의론적인 얘기가 여기저기에서 들린다. 한때 IT 붐이 일었을 때는 많은 사람들이 개발자를지망하기도 했다. 하지만 최근 상황을 보면, 신규 유입되는 인력이 아주 적은 편이다. 요즘 젊은이들은 영악해서 이 직종에 비전이없다는 것을 너무나 잘 알고 있다.

신참 인력뿐만 아니라 고급 인력도 많이 부족하다. 현재의 사회 풍토에서 고급 인력으로 성장하는 것은 결코 쉬운 일이 아니기 때문이다. 그저 사회가 제시하는 길을 따라가다가는 고급 인력이 되는 것이 아니라 퇴출된다.

필자의 경우를 보면, 필자는 정말 프로그래밍이 좋아서 시작한 8비트 키드이다. 중학교 1학년 때 처음으로 컴퓨터를 알게 된이후로 한시도 컴퓨터와 떨어진 적이 없는 소위 컴퓨터광(geek)이다. 하지만 대학 졸업 후 사회에 나와 첫 직장인 SI업체에서 일하면서 몇 번이나 눈물을 흘렸다. 이후 프리랜서, 개인회사 창업, 벤처기업, 중소기업, 대기업, 외국계 기업을 두루걸치면서 현재까지 겨우 살아남을 수 있었다.

만일 그런 인생의 순간순간에서 이를 악물고 분발하지 못한 채 끈을 놓아버렸다면 어땠을까? 정말 아찔한 생각이 든다. 특유의헝그리 정신으로 인해 겨우 버텼으며 성격도 많이 변했다. 그간 필자 자신 그리고 선배, 동료, 후배들을 보면서 느꼈던 생각을정리해서 개발자가 성공할 수 없는 이유 세 가지를 꼽아 보았다.

SI 중심의 왜곡된 업계 구조
첫 째, 업계 구조가 SI 중심으로 왜곡되어 있다. 국내의 소프트웨어 산업은 패키지나 솔루션 비즈니스가 제대로 작동되지 않는상태에서, 대기업 중심의 SI 업체들이 시장을 차지하고 있다. 그 과정에서 산업의 혈액 순환이 잘 되지 않아, 대기업만 돈을벌뿐 중소기업들은 협력 업체라는 미명 하에 근근이 먹고 살고 있는 형편이다. 통계에 따르면 전체 매출의 80% 이상을, 그리고영업 이익의 90% 이상을 대기업 계열 SI 업체 상위 3개사가 가져가고 있다.

SI는 소프트웨어 산업을 구성하는 한 가지 요소일 뿐이지만 국내에서는 거의 SI 밖에 없는 수준이다. 그런 상태에서 빅3업체가모든 것을 가져가고 있으며, 산업 전반에 하청 및 재하청에 따른 죽음의 순환 고리를 형성하고 있다. 그런 생태 구조에서 개발자는단지 머리 수에 불과할 따름이다. 또한 전문적인 지식에 대한 가치 판단이 제대로 이루어지지 않고 있기 때문에, 소프트웨어아키텍처까지도 비전문가에게 맡겨지는 경우가 많다.

SI 중심의 산업 구조, 그리고 전문가에 대한 평가 체계가 없고 단지 머리 수에 의해 개발자에 대한 판단이 이루어지는 상황에서개발자의 성공 사례는 나올 수 없다. 대기업의 협력 업체에서 일하는 많은 개발자들이 과중한 업무로 인해 참다못해 전업을 하거나건강이 나빠져서 자의반 타의반 일을 더 이상 할 수 없게 되곤 한다. 그러한 이유 때문에 많은 개발자들이 스스로를 막장인생이라고 표현하고 있다.

엉성한 개발자 관리
둘째, 소프트웨어 업체들이 개발자를 제대로 관리하지 못하고 있다. 소프트웨어 개발은 멘탈(mental) 작업이다. 인간의 정신에의해 결과물이 만들어지고 그것이 성공과 실패를 좌우한다. 하지만 국내 대부분의 소프트웨어 업체들은 그러한 멘탈 작업에 적합한업무 환경을 제공하지 못하고 있다. 또한 커리어 관리도 이루어지지 않고 있다. 물론 실적에 대한 보상도 미비하다.

개발자들에 대해 출퇴근 시간을 정확하게 체크하고(아니, 출근시간을 지키는지 체크하고 퇴근시간은 얼마나 늦는지 체크한다), 집중할수 없는 시끄러운 환경을 제공하고, 업무 실적의 가치를 제대로 평가하지도 못한다. 심지어 복장 점검을 하기도 한다. 또한 요즘개발자들은 전문적인 교육은 고사하고 일일 세미나에 참석하는 것도 어려운 형편이다. 많은 기업들이 최소한의 투자조차 기피하고 있기때문이다.

그것은 중소기업은 말할 것도 없고 소위 초일류 기업을 지향한다는 대기업도 마찬가지이다. 열악한 업무 환경을 제공하면서 성과에있어서는 최고의 아웃풋을 강요한다. 개발 환경만 제대로 제공되지 못하는 것이 아니라 관리도 제대로 안되고 있다. 부적절한관리자들이 개발자를 정신적으로 학대하고 있다. 소프트웨어 개발자로서 생존하기 위해서는 사회 구조적 환경, 그리고 기업문화와싸워야 한다. 많은 선배 개발자들이 그런 생존을 위한 싸움에서 졌고 결국 사라져 갔다.

개발자들의 스킬 부족과 닫혀진 태도
셋째, 끝으로 개발자들의 커뮤니케이션 스킬 부족과 태도 문제를 지적하지 않을 수 없다. 이 문제는 한국적 기업문화(상명하복)와결합하여 더욱 복잡한 문제를 야기하고 있다. 개발자들은 특히 다른 직종에 비해 성격이 까칠한 경우가 많다. 자신만의 지식과세계가 있기 때문에 그것이 전부라고 우쭐한 채로, 다른 개발자나 다른 직종을 존중하지 못하는 사람들이 꽤 많다.

하지만 “타인이 원하는 것에 대해 관심을 갖지 않는 사람”은 인생의 가시밭길을 걷게 된다. 그런 태도는 타인과의 협업을 어렵게하고 결국 자기 자신이 원하는 것도 얻지 못하게 한다. 젊은 시절에는 그런 태도에도 불구하고 큰 문제가 없을 수 있겠지만,30대 중반이 넘을 때까지도 태도를 변화시키지 못할 경우 이후에 많은 고난을 겪게 된다. 그것은 이미 인간의 역사에서 증명된삶의 법칙이다.

똑똑하고 샤프한 개발자들은 종종 있다. 하지만 타인의 관심사에 진정으로 주의를 기울이고 타인에게 친절한 마음을 가진 개발자를만나기란 참으로 힘들다. 이것은 다른 직종도 마찬가지이겠지만 (개발자 출신인 필자가 볼 때에는) 개발자들의 세계에 유독 이런까칠함과 폐쇄성이 심하다.

물론 그런 독불장군적 태도가 단지 개발자들의 탓만은 아닐 것이다. 많은 개발자들이 피해 의식을 갖고 있으며 그것이 타인에 대한공격적 태도로 나타나기도 한다. 사회적 환경의 미비, 그리고 커뮤니케이션 스킬이 부족한 개발자들. 이 조합이 더욱 안타까운결과를 만들어낸다.

추가적으로 언급할 점은, 혁신해야 할 여러 가지 네가티브한 요인에도 불구하고 개발자들끼리 잘 뭉치지 못한다는 사실이다. 외국과달리 개발자 커뮤니티의 활동이 많지 않다. 물론 JCO(자바 개발자 커뮤니티), SCA(소프트웨어 커뮤니티 연합) 등 개발자들의모임이 없는 것은 아니지만 가끔 오프라인 모임이나 컨퍼런스를 개최할 뿐, 별다른 ‘사회 변혁적 활동’을 구현하지는 못하고 있다.개발자들의 실상을 알리고 대안을 마련하고 정부나 기업들과 접촉을 하고 해외에 진출하고 창업을 하는 등의 좀 더 적극적으로행동하는 것이 필요하다.

아마도 필자의 이런 글에 대해 그저 현실에 대한 비판에 불과하다고 얘기하는 이도 있을 것이다. 하지만 대응 방안을 마련하기 위해서는 먼저 냉정하게 현실을 정리하지 않을 수 없다.

요약해보자. 대기업 계열사들이 장악한 SI 위주의 산업 구조에서 개발자들은 성장하지 못하고 성공하지 못한다. 이런 사회 풍토에서과연 존경 받거나 성공한 개발자들이 얼마나 되는가? 또한 많은 소프트웨어 업체들의 기업 문화가 후진적이다. 제대로 된 업무환경을 제공하지도 못하면서 프로젝트 관리도 안 된다. 그러면서 성과에 대해서는 초일류를 원한다. 이율배반적이다.

개발자들의 태도 문제도 있다. 환경을 바꾸지 못하면 자기 자신을 바꾸어야 한다. 개발자 스스로 그런 인식을 가져야 한다.피해의식에 사로잡혀 있는 것만으로는 삶이 억울하지 않은가? 개인적으로 커뮤니케이션 스킬을 향상시키고 타인에 대해 친절한 태도를갖추는 인간 수양이 필요하다. 그리고 동료 개발자들과 함께 변혁을 위해 협업하고 개척해나갈 부분이 있다는 것을 알고서 행동해야한다.

왜곡된 업계 구조 속에서 가만히 있으면 퇴출될 뿐이다. 우리에게는 행동이 필요하다. 이후의 컬럼에서 하나씩 대응 방안을 다루어보도록 하겠다. @

출처 : Zdnet, 류한석의 스마트모델링

by 방마루 | 2007/06/29 17:57 | 트랙백 | 덧글(1)

oracle function을 코딩할때 염두에 둘점.

예를들면 코스값을 매개변수로 받아서 그 코드명을 리턴하는 함수를 코딩할때,

매개변수를 WHERE절로 질의문을 작성하여 질의 결과를 리턴하는 형식의 function을 흔히 작성하는데

이때 질의결과가 1row 이상 된다면 함수에 에러가 발생한다.


FUNCTION GET_CODE_NAME(code)
...
SELECT CODE_NAME
INTO v_RETURN
FROM CODE_TABLE
WHERE CODE_ID = CODE;
...
RETURN v_RETURN;


이 경우 GET_CODE_NAME function내에서 2ROW이상이 발생할 경우 리턴을 하지못할 뿐 아니라, 해당 FUNCTION을 호출한

쿼리에도 정상적으로 질의되지 못하는 결과를 초래한다.



SELECT GET_CODE_NAME(CODE)
FROM MSG_TABLE


1ROW 만 리턴될 수 있는 방법을 염두에 둔다.



WHERE ...
AND ROWNUM = 1

by 방마루 | 2007/04/04 14:22 | 프로그래밍 지식 | 트랙백 | 덧글(0)

SQL Formatter

괜찮은 SQL Formatter를 찾다가 정말 괜찮은 녀석을 만났다.

Applet으로 구현된 Formatter로 output Type을 Java, Asp, C# 등의 다양한 형태도로 출력 가능하다.

Gooooooooooood.

http://sqlinform.com

by 방마루 | 2007/03/23 17:04 | 세상과의 인터페이스 | 트랙백 | 덧글(0)

이유가 뭔데?

말해봐,

앞에 있는걸 잡지 않고, 머뭇거리고 있는 이유가 뭔데?

놓치기 전에 빨리 결정하라고, 도데체 머뭇거리는 이유가 뭔지 말해보라구.

by 방마루 | 2007/03/13 14:59 | 글과 자기 표현 | 트랙백 | 덧글(0)

버그관리

이전 경험의 실패와 고난 때문에, 이번 프로젝트서는 이슈관리 툴을 사용해 보고 싶다.

Trac, Scarab, iTrack


등을 견주어 보고 있다. 어떤 것이 좋을까?

by 방마루 | 2007/03/13 14:53 | 프로그래밍 지식 | 트랙백 | 덧글(1)

◀ 이전 페이지다음 페이지 ▶