Design Pattern2009.06.09 17:13
갑자기 왠 AOP냐구요? 오픈소스 프레임웍 중에서 SPRING.NET 의 중요한 부분이라서 개념부터 짚고 넘어가려 합니다.

Q. AOP는 OOP의 발전된 개념이다?
1. 맞다
2. 틀리다.


답. 2 틀리다.

왜 그런지 차근차근 살펴보도록 하겠습니다.

OOP는 프로그램 개발에 있어서 대표적인 패러다임입니다. 가장 많이 쓰는 개발방법이고, 안정화 되어 있습니다. 하지만 사람들의 욕심이 끝이 없습니다. 하나씩 살펴 보겠습니다.

1. 훌륭하게 설계된 시스템에서 어떤 반복적인 기능이 추가되어야 할때. 예를 들면 로깅
2. 공통적인 이름을 가진 메소드가 실행이 되기전/후 에 다른 추가적인 일을 해야할때
3. 잘 설계된 모듈에 공통적인 기능을 추가 하여야 할때.

이러한 기능을 추가하거나 수정할때는 상당히 많은 작업을 해야 하며, 코드가 지저분하게 바뀌어 유지보수가 힘들어 질 수 있습니다. 그러면 위 문제를 해결 하기 위한 방법으로 AOP 의 예를 들어 보겠습니다.

1. 훌륭하게 설계된 시스템에서 어떤 반복적인 기능이 추가되어야 할때. 예를 들면 로깅
   ; AOP의 위빙(Weaving) 또는 크로스컷팅(crosscutting) 이라는 작업을 통해 가능합니다.
     필요하면 포인트컷을 적용해서 애플리케이션 내의 모든 메쏘드에 로그를 남기는 애스팩트가 위빙되도록 할 수 있습니다.
     간단히 포인트컷 시그니처만 수정해주면 됩니다.

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

2. 공통적인 이름을 가진 메소드가 실행이 되기전/후 에 다른 추가적인 일을 해야할때
   ; 포인트컷으로 공통적인 이름에 대한 Before Advice, After Returning Advice 등을 통해 처리가 가능합니다.

3. 잘 설계된 모듈에 공통적인 기능을 추가 하여야 할때.
   ; 인터셉터(Interceptor)를 통한 역 제어가 가능합니다.


AOP는 OOP에 부족한 부분을 채워주는것입니다. 또한, 제가 ASP.NET MVC + SPRING.NET + iBATIS.NET 게시판을 만들면서 SPRING.NET을 사용한 이유도 여기에 있습니다. AOP에 좋은 프레임웍이 SPRING.NET은 아닙니다만, 확장성이 있고, 많이 사용되며 검증받은 프레임웍이기 때문입니다. AOP를 위해 가장 좋은 프레임웍은 AspectJ인데 자바버전이고, 닷넷 버전은 Aspect# 입니다만 2005년 6월 부터 시작된 프로젝트라서 얼마나 안정적인지는 잘 모르겠습니다. 암튼 참고만 하시고 ^^;


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

예를 들어, 은행 업무를 처리하는 시스템을 생각해보면 Core Concerns는 예금입출금, 계좌간이체, 이자계산, 대출처리 등으로 구분할 수 있습니다. 이는 전체 어플리케이션의 핵심 요구 사항과 기능들을 구분해서 모듈화할 수 있고 OOP에서라면 클래스와 컴포넌트 형태로 구성이 가능합니다. 하지만 현실은 그렇지 못합니다. 실제로 개발되어 돌아가는 각 모듈에는 해당 업무를 처리하기 위한 로직만 존재해서는 불완전할 수밖에 없습니다. 일단 각 업무를 처리하는 클래스와 구현된 메소드에는 향후 시스템을 분석하거나 추적을 위해 로그를 작성해야 하며, 인증받은 사용자가 접근하는지를 체크하고 권한 여부를 따지는 보안 기능이 필요합니다. 또한 내부에서 사용하는 Persistence 처리를 위해 Transaction을 시작하고, 또 필요에 따라서 그것을 Commit 또는 Rollback하는 부분도 추가되어야 합니다. 예외 상황이나 문제가 발생했을 때는 그것을 기록에 남기는 부분도 있어야 하고, 필요하면 관리자에게 이메일을 발송해야 합니다.


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

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

  • 중복되는 코드 : 복사-붙이기에 의해 만들어진 여러 모듈에서 중복되는 코드의 문제점은 이미 잘 알려져 있습니다. 하지만 AOP를 사용하지 않은 대부분의 어플리케이션에서는 어떠한 추상화와 리팩토링을 통해서도 반복되는 코드를 피하기가 어렵습니다.
  • 지저분한 코드 : Crosscutting Concerns과 관련된 코드들이 핵심 기능 코드 사이 사이에 끼어들어가 있기 때문에 코드가 지저분해지고 이에 따라 가독성이 떨어지며 개발자들의 실수나 버그를 유발하고 후에 코드를 유지보수하는데 큰 어려움을 줍니다.
  • 생산성의 저하 : 어플리케이션 개발자들이 자주 등장하는 Crosscutting Concerns을 구현한 코드를 함께 작성해야 하기 때문에 개발의 집중력을 떨어뜨리고 결과적으로 전체 생산성의 저하를 가져옵니다. 또 모듈별로 개발자들을 구분하고 분산시키는 것에 한계가 있습니다.
  • 재활용성의 저하 : OOP의 장점인 재활용성이 매우 떨어집니다.
  • 변화의 어려움 : 새로운 요구사항으로 인해 전체적으로 많은 부분에 영향을 미치는 경우 쉽게 새로운 요구사항을 적용하기 힘들게 됩니다. 또 새로운 관심 영역의 등장이나 이의 적용을 매우 어렵게 합니다.

  • AOP가 Core Concerns 모듈의 코드를 직접 건드리지 않고 필요한 기능이 작동하도록 하는 데는 Weaving 또는 CrossCutting이라고 불리는 특수한 작업이 필요합니다. Core Concerns 모듈이 자신이 필요한 Crosscutting Concerns 모듈을 찾아 사용하는 대신에 AOP에서는 Weaving 작업을 통해 Core Concerns 모듈의 사이 사이에 필요한 Crosscutting Concerns 코드가 동작하도록 엮어지게 만듭니다. 이를 통해 AOP는 기존의 OOP로 작성된 코드들을 수정하지 않고도 필요한 Crosscutting Concerns 기능을 효과적으로 적용해 낼 수 있습니다.


    이런 작업은 기존의 자바 언어와 컴파일러에서는 쉽게 구현할 수 있는 방법이 아니며 본격적인 AOP 기술이 등장한 것은 1990년대 후반 제록스 PARC 연구소에서 그레거 킥제일(Gregor Kiczales)에 의해 AspectJ가 개발되면서라고 볼 수 있습니다. 그는 Asepct라는 용어와 함께 AOP라는 표현을 처음 사용하기 시작했고, 자바 VM과 호환되는 최초의 AOP 툴인 AspectJ를 구현해 냈습니다.
    AspectJ는 자바의 언어를 확장한 형태의 구조로 개발됐는데 자바의 클래스와 유사한 개념인 AOP의 Aspect를 작성하는 방법을 통해 AOP의 기능을 사용할 수 있도록 했습니다. 이렇게 만들어진 Aspect는 AspectJ의 특별한 컴파일러를 통해 자바 VM에서 사용될 수 있는 코드로 만들어집니다. 바로 이때 AOP의 Weaving 작업이 일어난다. Weaving 작업을 통해 Core Concerns 모듈의 사이 사이에 Aspect 형태로 만들어진 Crosscutting Concerns 코드들이 삽입되어 Aspect가 적용된 최종 바이너리가 만들어지는 것입니다. AOP를 이용하면 개발자들은 Crosscutting Concerns 모듈을 각각 독립된 모듈로 중복없이 작성하고 이를 Weaving을 통해 Core Concerns 모듈과 결합시키기 때문에 서로 독립성을 가진 다차원의 모듈을 작성할 수 있습니다.


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

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

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

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

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

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

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


    이 내용 말고도 더 많은 내용들이 있지만, 쉽게쉽게 하나씩 차근차근 진행해 나가면 좋을것 같습니다.

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

    저작자 표시 비영리 동일 조건 변경 허락
    신고
    Posted by dotnetpower
    TAG

    티스토리 툴바