관점 지향 프로그래밍

컴퓨팅에서 관점 지향 프로그래밍(aspect-oriented programming, AOP)은 횡단 관심사(cross-cutting concern)의 분리를 허용함으로써 모듈성을 증가시키는 것이 목적인 프로그래밍 패러다임이다. 코드 그 자체를 수정하지 않는 대신 기존의 코드에 추가 동작(어드바이스)을 추가함으로써 수행하며, "함수의 이름이 'set'으로 시작하면 모든 함수 호출을 기록한다"와 같이 어느 코드가 포인트컷(pointcut) 사양을 통해 수정되는지를 따로 지정한다. 이를 통해 기능의 코드 핵심부를 어수선하게 채우지 않고도 비즈니스 로직에 핵심적이지 않은 동작들을 프로그램에 추가할 수 있게 한다. 관점 지향 프로그래밍은 관점 지향 소프트웨어 개발의 토대를 형성한다. 관점 지향 소프트웨어 개발은 온전한 엔지니어링 분야를 가리키는 반면에 관점 지향 프로그래밍은 소스 코드 레벨에서 관심사들의 모듈화를 지원하는 프로그래밍 메서드들과 도구들을 포함하고 있다. 관심 지향 프로그래밍은 프로그램 로직을 명확한 부분들(이른바 "관심사")로 나누는 것을 수반한다. 거의 모든 프로그래밍 패러다임들은 관심사들을 별도의 독립적인 엔티티로 그룹화하고 캡슐화하는 것을 어느 정도는 지원하며, 이는 이러한 관심사들을 구현, 추상화, 합성하기 위해 사용할 수 있는 추상화(예: 함수, 프로시저, 모듈, 클래스, 메서드)를 제공함으로써 수행된다. 일부 관심사들은 프로그램 내의 여러 추상적 개념들에 영향을 미치며 이러한 형태의 구현체를 거역한다. 이러한 관심사들을 크러스 커팅 관심사(cross-cutting concerns)라고 부른다. 횡단 관심사의 전형적인 예로 로깅을 들 수 있는데 로깅 전략이 필연적으로 시스템 상에서 로그되는 모든 부분에 영향을 미치기 때문이다. 그러므로 로깅은 로그가 되는 모든 클래스들과 메서드들을 횡단한다. 모든 AOP 구현체들은 각각의 관심사를 한 자리에 캡슐화하는 횡단 표현식들을 일부 보유하고 있다. 구현체들 간의 차이점은 제공되는 생성자들의 권한, 보안, 사용성에 기인한다. AOP에는 여러 선행자 A1, A2가 있다: 반영, 메타오브젝트 프로토콜, 주체 지향 프로그래밍, 컴포지션 필터(Composition Filters), 적응형 프로그래밍(Adaptive Programming). 제록스 PARC의 Gregor Kiczales와 동료들은 명시적 개념의 AOP를 개발하였으며 AspectJ AOP 확장 기능을 자바로 가져왔다. IBM의 연구팀은 언어 설계 접근으로 도구 접근을 추구하였으며 2001년에 Hyper/J와 관심 조작 환경(Concern Manipulation Environment)을 제안하였으나 널리 사용되지는 않았다. 마이크로소프트 트랜잭션 서버가 최초의 주요 AOP 애플리케이션으로(이후에는 엔터프라이즈 자바빈즈) 간주된다. 일반적으로 애스펙트(aspect)는 코드로서 분산되거나 얽혀있으며 이해하고 유지보수하기를 어렵게 만든다. 잠재적으로 서로 완전히 관련이 없는 시스템, 각기 다른 원본 언어 등에서 수많은 비관련 함수들에 로깅과 같은 함수가 분산된다. 즉, 로깅을 바꿀 경우 영향을 받는 모든 모듈의 수정이 필요하다. 애스펙트는 표현이 되는 시스템의 핵심 기능에만 얽혀있는 것이 아니라 서로에게도 얽혀있다. 이를테면, 개념적으로 매우 단순한 메소드가 있는 은행업 애플리케이션을 생각해 보자. 아래는 하나의 계정에서 다른 계정으로 송금하는 것이다: void transfer(Account fromAcc, Account toAcc, int amount) throws Exception { if (fromAcc.getBalance() < amount) throw new InsufficientFundsException(); fromAcc.withdraw(amount); toAcc.deposit(amount); } 그러나 이러한 송금 방식은 디플로이된 애플리케이션이 다음을 필요할 것만 고려하고 있다: 현재 사용자가 이 작업을 수행하기 위한 권한이 있는지를 검사하는 보안 검사 기능이 없다. 데이터베이스 트랜잭션은 우연한 데이터 손실을 예방하기 위해 작업을 캡슐화하는 것이 좋겠다. 진단을 위해 이 작업은 시스템 로그에 기록하는 것이 좋겠다. 등등... 이러한 새로운 관심사들의 버전은 이를테면 다음과 같이 보일 수 있다: void transfer(Account fromAcc, Account toAcc, int amount, User user, Logger logger, Database database) throws Exception { logger.info("Transferring money..."); if (!isUserAuthorised(user, fromAcc)) { logger.info("User has no permission."); throw new UnauthorisedUserException(); } if (fromAcc.getBalance() < amount) { logger.info("Insufficient funds."); throw new InsufficientFundsException(); } fromAcc.withdraw(amount); toAcc.deposit(amount); database.commitChanges(); // Atomic operation. logger.info("Transaction successful."); } 이 예에서 다른 관심사들은 기초적인 기능(비즈니스 로직 관심사)과 함께 뒤얽혀있다. 트랜잭션, 보안, 로깅은 모두 횡단 관심사를 가리킨다. 이를테면 우리가 갑자기 애플리케이션에 대한 보안 고려사항을 변경해야 한다면 일어나는 일에 대해서 생각해 보자. 프로그램의 현재 버전에서 보안 관련 기능들은 수많은 메소드를 가로질러 분산되어 있는 것으로 나타나며 이러한 변경은 상당한 노력이 요구된다. AOP는 프로그래머가 횡단 관심사를 애스펙트라는 독립적인 모듈로 표현할 수 있게 함으로써 이 문제의 해결을 시도한다. 애스펙트는 어드바이스(프로그램 내의 특정 포인트와 결합되는 코드)와 인터타입 선언(다른 클래스에 추가되는 구조적인 멤버)을 포함할 수 있다. 이를테면 보안 모듈에는 은행 계좌에 접근하기 전에 보안 검사를 수행하는 어드바이스를 포함할 수 있다. 포인트컷은 누군가가 은행 계정에 접근하는 시점(조인 포인트)을 정의하며 어드바이스 몸체 내의 코드는 어떻게 보안 검사를 구현하는지를 정의한다. 이러한 방식으로 검사와 장소를 한 자리에서 유지보수할 수 있게 된다. 게다가 양호한 포인트컷은 나중의 프로그램 변경을 예측할 수 있으므로 다른 개발자가 은행 계정에 접근하기 위한 새로운 메소드를 만든다면 어드바이스는 실행 시 새로운 메소드에 적용이 가능하다. 그러므로 위의 예제에 애스펙트에 로깅을 구현하면 다음과 같이 된다: aspect Logger { void Bank.transfer(Account fromAcc, Account toAcc, int amount, User user, Logger logger) { logger.info("Transferring money..."); } void Bank.getMoneyBack(User user, int transactionId, Logger logger) { logger.info("User requested money back."); } // Other crosscutting code. } AOP를 디버깅 도구나 사용자 수준의 도구로 생각하는 사람이 있을 수 있다. 어드바이스는 함수 변경을 취할 수 없는 경우에 대비하여 (사용자 레벨), 또 운영 모드(디버깅)에서 함수를 변경하고 싶지 않을 때 예비해 두는 것이 좋다. 다음의 프로그래밍 언어들은 언어 자체적으로, 또는 외부 라이브러리를 통해 AOP를 구현하고 있다: 닷넷 프레임워크 언어 (C# / VB.NET) PostSharp는 상용 AOP 구현체이다. 유니티: API를 제공. 액션스크립트 에이다 오토핫키 C / C++ 코볼 코코아 오브젝티브-C 프레임워크 어도비 콜드퓨전 커먼 리스프 델파이 옥시즌 e (IEEE 1647) Emacs Lisp 그루비 하스켈 자바 AspectJ 자바스크립트 로그토크 루아 make MATLAB ML 펄 PHP 프롤로그 (프로그래밍 언어) 파이썬 래킷 루비 스퀵 스몰토크 UML 2.0 XML 프로그래밍 패러다임 데코레이터 패턴 Kiczales, G.; Lamping, J.; Mendhekar, A.; Maeda, C.; Lopes, C.; Loingtier, J. M.; Irwin, J. (1997). 《Aspect-oriented programming》 (PDF). ECOOP'97. 《Proceedings of the 11th European Conference on Object-Oriented Programming》. LNCS 1241. 220–242쪽. CiteSeerX 10.1.1.115.8660. doi:10.1007/BFb0053381. ISBN 3-540-63089-9.  "Adaptive Object Oriented Programming: The Demeter Approach with Propagation Patterns" Karl Liebherr 1996 ISBN 0-534-94602-X presents a well-worked version of essentially the same thing (Lieberherr subsequently recognized this and reframed his approach). Don Box; Chris Sells (2002년 11월 4일). 《Essential.NET: The common language runtime》. Addison-Wesley Professional. 206쪽. ISBN 978-0-201-73411-9. 2011년 10월 4일에 확인함.  Roman, Ed; Sriganesh, Rima Patel; Brose, Gerald (2005년 1월 1일). 《Mastering Enterprise JavaBeans》. John Wiley and Sons. 285쪽. ISBN 978-0-7645-8492-3. 2011년 10월 4일에 확인함.  Note: The examples in this article appear in a syntax that resembles that of the 자바 language. Emacs documentation Numerous: Afterthought, LOOM.NET, Enterprise Library 3.0 Policy Injection Application Block, AspectDNG, DynamicProxy, Compose*, PostSharp, Seasar.NET, DotSpect (.SPECT) Archived 2006년 3월 31일 - 웨이백 머신, Spring.NET (as part of its functionality), Wicca and Phx.Morph, SetPoint Archived 2008년 10월 7일 - 웨이백 머신 “as3-commons-bytecode”. 2014년 10월 3일에 원본 문서에서 보존된 문서. 2017년 7월 22일에 확인함.  Ada2012 Rationale Function Hooks{{ 보관됨 2013-01-17 - archive.today Several: AspectC++, FeatureC++, AspectC, AspeCt-oriented C Archived 2008년 11월 20일 - 웨이백 머신, Aspicere{{ 보관됨 2012-07-21 - archive.today Cobble[깨진 링크(과거 내용 찾기)] “AspectCocoa”. 2007년 10월 26일에 원본 문서에서 보존된 문서. 2018년 5월 5일에 확인함.  ColdSpring{{ 보관됨 2012-08-03 - archive.today “Closer Project: AspectL.”. 2015년 8월 11일에 확인함.  “infra - Frameworks Integrados para Delphi - Google Project Hosting”. 2015년 8월 11일에 확인함.  “meaop - MeSDK: MeObjects, MeRTTI, MeAOP - Delphi AOP(Aspect Oriented Programming), MeRemote, MeService... - Google Project Hosting”. 2015년 8월 11일에 확인함.  “Google Project Hosting”. 2015년 8월 11일에 확인함.  “RemObjects Cirrus”. 2012년 1월 23일에 원본 문서에서 보존된 문서. 2018년 5월 5일에 확인함.  Emacs Advice Functions monad (functional programming) (“Monads As a theoretical basis for AOP”. CiteSeerX 10.1.1.25.8262. ) and Aspect-oriented programming with type classes. A Typed Monadic Embedding of Aspects Numerous others: CaesarJ Archived 2008년 12월 19일 - 웨이백 머신, Compose*, Dynaop Archived 2007년 7월 24일 - 웨이백 머신, JAC Archived 2004년 6월 19일 - 웨이백 머신, Google Guice (as part of its functionality), Javassist Archived 2004년 9월 1일 - 웨이백 머신, JAsCo (and AWED), JAML Archived 2005년 4월 15일 - 웨이백 머신, JBoss AOP Archived 2006년 10월 17일 - 웨이백 머신, LogicAJ Archived 2006년 5월 4일 - 웨이백 머신, Object Teams, PROSE, The AspectBench Compiler for AspectJ (abc) Archived 2014년 12월 16일 - 웨이백 머신, 스프링 프레임워크 (as part of its functionality), Seasar, The JMangler Project Archived 2005년 10월 28일 - 웨이백 머신, InjectJ, GluonJ Archived 2007년 2월 6일 - 웨이백 머신, Steamloom Archived 2007년 8월 18일 - 웨이백 머신 Many: Advisable Archived 2008년 7월 4일 - 웨이백 머신, Ajaxpect, jQuery AOP Plugin Archived 2008년 1월 13일 - 웨이백 머신, Aspectes Archived 2006년 5월 5일 - 웨이백 머신, AspectJS, Cerny.js Archived 2007년 6월 27일 - 웨이백 머신, Dojo Toolkit, Humax Web Framework, Joose, 프로토타입 - Prototype Function#wrap, YUI 3 (Y.Do) Archived 2011년 1월 25일 - 웨이백 머신 Using built-in support for categories (which allows the encapsulation of aspect code) and event-driven programming (which allows the definition of before and after event handlers). “AspectLua”. 2015년 7월 17일에 원본 문서에서 보존된 문서. 2015년 8월 11일에 확인함.  “MAKAO, re(verse)-engineering build systems”. 2012년 7월 24일에 원본 문서에서 보존된 문서. 2015년 8월 11일에 확인함.  “McLab”. 2015년 8월 11일에 확인함.  “AspectML - Aspect-oriented Functional Programming Language Research”. 2015년 8월 11일에 확인함.  Adam Kennedy. “Aspect - Aspect-Oriented Programming (AOP) for Perl - metacpan.org”. 2015년 8월 11일에 확인함.  Several: PHP-AOP (AOP.io) Archived 2014년 8월 19일 - 웨이백 머신, Go! AOP framework, PHPaspect, Seasar.PHP, PHP-AOP{{ 보관됨 2012-07-12 - archive.today, TYPO3 Flow Archived 2017년 7월 17일 - 웨이백 머신, AOP PECL Extension “"Whirl"”. 2016년 4월 20일에 원본 문서에서 보존된 문서. 2017년 7월 22일에 확인함.  Several: PEAK Archived 2005년 4월 9일 - 웨이백 머신, Aspyct AOP{{ Archived 2011년 6월 9일 - 웨이백 머신, Lightweight Python AOP Archived 2004년 10월 9일 - 웨이백 머신, Logilab's aspect module Archived 2005년 3월 9일 - 웨이백 머신, Pythius, Spring Python's AOP module Archived 2016년 3월 4일 - 웨이백 머신, Pytilities' AOP module Archived 2011년 8월 25일 - 웨이백 머신, aspectlib “PLaneT Package Repository : PLaneT > dutchyn > aspectscheme.plt”. 2015년 8월 11일에 확인함.  “AspectR - Simple aspect-oriented programming in Ruby”. 2015년 8월 11일에 확인함.  Dean Wampler. “Home”. 2007년 10월 26일에 원본 문서에서 보존된 문서. 2015년 8월 11일에 확인함.  “gcao/aspector”. 《GitHub》. 2015년 8월 11일에 확인함.  “AspectS”. 2006년 1월 6일에 원본 문서에서 보존된 문서. 2018년 5월 5일에 확인함.  “MetaclassTalk: Reflection and Meta-Programming in Smalltalk”. 2015년 7월 29일에 원본 문서에서 보존된 문서. 2015년 8월 11일에 확인함.  WEAVR “aspectxml - An Aspect-Oriented XML Weaving Engine (AXLE) - Google Project Hosting”. 2015년 8월 11일에 확인함.