Clean Code that Works.

아하하핫. 공부 합시다.

내용을 살펴 보기 전에 관점지향 프로그래밍(Aspect Oriented Programming, 이하 AOP)이란
무엇인가에 대하여 간단히 알아 보도록 하겠습니다..

(AOP의 핵심, 횡단 관심사를 코드에서 분리)

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

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

- http://www.zdnet.co.kr/ArticleView.asp?artice_id=00000039147106 기사 발췌-

자세한 내용은 위 기사를 확인 해 보시면 AOP가 무엇인지에 대하여 감을 잡으실 수 있습니다.

저도 감만 잡았지 확실하게 이해 하지는 못했습니다. -,.-
하지만 관심사의 분리가 가장 중요한 개념이라는 생각만 가지고 계시면 될 것 같습니다. ㅎㅎ;;;

 

그럼 AOP에 대해선 이정도만 알아 보고,
jQuery AOP에 대하여 알아보도록 하겠습니다. 

사이트 : http://code.google.com/p/jquery-aop/
레퍼런스 : http://code.google.com/p/jquery-aop/wiki/Reference

레퍼런스를 확인해 보시면 알겠지만, 사용법이 대단히 간단 합니다.
before, after, around등을 지원 합니다.

그럼 샘플 코드를 살펴 보면서 AOP를 어떻게 적용 했는지 보도록 하겠습니다.

As-Is Script

$( '.moveFirst').click( function(){
  if ( isClickAble( this))
    return;
  $( '#FavoriteList').children().remove();
  getFavorite( publicUserType, 0);
});

$( '.moveLast').click( function(){
  if ( isClickAble( this))
   return;
  $( '#FavoriteList').children().remove();
  var page = ($( this).parent().find( '#currenPage').val() + 1) * $( this).parent().find( '#limit').val();
  getFavorite( publicUserType, page);
});

$( '.movePrev').click( function(){
  if ( isClickAble( this))
    return;
  $( '#FavoriteList').children().remove();
  var page = ($( this).parent().find( '#currenPage').val() - 1) * $( this).parent().find( '#limit').val();  getFavorite( publicUserType, page);
});

$( '.moveNext').click( function(){
  if ( isClickAble( this))
    return;
  $( '#FavoriteList').children().remove();
  var page = ($( this).parent().find( '#currenPage').val() + 1) * $( this).parent().find( '#limit').val();
  getFavorite( publicUserType, page);
});


 

음.. 이 Script를 보시면.. 뭔가 마틴 파울러란 사람이 말했던 bad smells in codes(http://en.wikipedia.org/wiki/Code_smell)...인가 그게 생각나지 않습니까?

-,.-;; 저도 생각나다 말았습니다. ㅋ_ㅋ
리팩토링 관점으로 본다면야, 아래 코드가 중복되어 있기 때문에 메서드로 추출해서 쓰면 되겠다.. 싶으실 껍니다. 하지만 이번엔 AOP적인 마인드로 생각을 해 보면.  

아래의 코드는 비즈니스 로직과 관련이 없는 횡단관심사항인것으로 판단 할 수 있습니다.
그러니까 이 코드가 바로 AOP를 적용할 조인포인트(joinpoint)로 생각할 수 있습니다.

// 클릭 가능한지 않는지 판단( 페이징에서 처음 페이지일때 처음 버튼 클릭 못하게 할 경우)
if ( isClickAble( this))
    return;
// 페이징시 이전 페이징된 리스트들을 삭제.  
$( '#FavoriteList').children().remove();

 

그럼 AOP를 적용하여 보도록 하겠습니다.

To-Be Script 

// 메서드에 AOP를 적용하기 위에 이벤트 안의 내용들을 메소드로 추출 했습니다.
$( '.moveFirst').click( function(){
  movePageFirstHandler( this);
 });

 $( '.moveLast').click( function(){
  movePageLastHandler( this);
 });

 $( '.movePrev').click( function(){
  movePagePrevHandler( this);
 });

 $( '.moveNext').click( function(){
  movePageNextHandler( this);
 });

jQuery.aop.around({ target: window, method: /movePage*/},
  function( invocation){
   if ( isClickAble( invocation.arguments)) {
    return null;
   }  else {
    $( '#FavoriteList').children().remove();
    invocation.proceed();
   }
  }
 );

 

이렇게 바뀌게 됩니다!!
이 AOP 플러그인은 특정 메서드를 지정하거나, 정규 표현식을 사용해서 AOP를 걸 수 있습니다.

위 코드에서는 /movePage*/를 사용(정규식)해서 movePage로 시작하는 메서드들에 해당
around aop를 위빙(weaving)하고 있습니다.(정규식 테스트 사이트)

오우 사용 방법이 생각보다 어렵진 않습니다. AspectJ 나 SpringAOP에 비하면.. 쉬운것 같습니다.

Plus.
AOP를 적용하지 않았을 경우 발생할 수 있는 문제점.




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