설치
-
nodejs
$ npm install crosscutting
-
browser
<script type="text/javascript" src="/path/to/crosscutting.min.js"></script>
사용법
Basic
crosscutting.weave
객체와 관심을 특정 대상과 시점에 묶는 메서드입니다. 인자를 4개 받습니다.
crosscutting.weave([aopTarget], [pointcut], [adviceType], [advice])
-
aopTarget - Object, Array[Object]
aop를 적용할 객체입니다. 빌트인 (Built-In) 타입의 프로토타입은 AOP를 적용할 수 없으며 적용하려고 하면 TypeError 가 던져집니다.
여러 객체에 일괄 적용하고 싶다면 배열로 줄 수도 있습니다.적용 불가능한 객체들
- String.prototype
- Number.prototype
- Boolean.prototype
- Date.prototype
- Array.prototype
- Date.prototype
- RegExp.prototype
- Function.prototype
-
pointcut - RegExp, function(boolean 반환 필요)
aopTarget 에 적용될 메서드를 구별해내는 인자입니다.
정규표현식, 함수, Boolean 값이 될 수 있습니다. 함수를 사용한다면 인자를 받는데, 다음과 같습니다. 포인트컷 함수는 반드시 boolean 값을 반환해야 합니다.
Boolean 값을 줄 경우 true면 모든 메서드에 대해 적용하게 됩니다.fnPointcut([Method Name]):boolean
- Method Name - String
- 객체의 메서드 이름입니다. 이것으로 AOP 적용 여부를 판단하는 함수 몸체를 만들면 됩니다.
-
adviceType - crosscutting.Aspect
어드바이스 타이밍입니다. 4종류가 있습니다. (crosscutting.Aspect.(BEFORE|AFTER|EXCEPTION|AROUND))
- crosscutting.Aspect.BEFORE
- 객체의 메소드가 실행되기 전 어드바이스가 실행됩니다.
- crosscutting.Aspect.AFTER
- 객체의 메소드가 실행된 뒤 어드바이스가 실행됩니다.
- crosscutting.Aspect.EXCEPTION
- 객체의 메소드가 무언가를 throw 하게 되면 실행됩니다. 당신은 어드바이스 함수에 전달되는 인자객체의 "exception" 속성을 사용하여 던져진 객체에 접근할 수 있습니다.
- crosscutting.Aspect.AROUND
- 객체의 메소드가 실행되지 않고 어드바이스가 실행됩니다. 대신 객체의 메소드는 어드바이스 함수의 첫번째 인자로 전달됩니다. 일반적인 인자 객체는 두번째 인자로 전달됩니다.
-
advice - function
어드바이스 함수입니다.
어드바이스 함수는 일반적으로 인자 객체를 인자로 전달 받습니다. 다만 어드바이스 타이밍이 AROUND 일 경우 첫번째 인자로 객체 메소드가 오므로 인자 객체는 두번째 인자가 됩니다.
인자 객체의 속성은 다음과 같습니다.- args
- 객체 메서드에 전달되는 Arguments 객체입니다. 이 값을 조작하면 실제 객체 메서드의 인자도 바뀝니다. Arguments 객체에 대해서는
MDN 문서를 참고하세요
// Simple arguments control Example var obj = { // return argument received echo: function(value) { return value; } }; crosscutting.weave( obj, true, crosscutting.Aspect.AdviceType.BEFORE, function(options) { // change first arguments. options.args[0] = "yaho!"; } ); // same result. "yaho!". console.log(obj.echo("ok?")); // "yaho!"; console.log(obj.echo("hello?")); // "yaho!";
- target - Object
- AOP가 적용되는 객체입니다. 어드바이스는 이 객체를 컨텍스트(this)로 하여 실행됩니다.
- todo - function
- 실제 수행될 메서드입니다
- advice - function
- weave 시 인자로 준 어드바이스 함수입니다.
- type - crosscutting.Aspect
- weave 시 인자로 준 어드바이스 타이밍입니다.
- method - String
- pointcut에 의해 join 된 메서드의 이름입니다.
- exception - Error
- 어드바이스 타입이 EXCEPTION이고 객체 메서드가 객체를 throw할 경우 객체 메서드에서 던져진 객체를 가지고 있습니다.
단축 메서드들
AdviceType을 따로 인자로 주지 않고 축약한 단축 메서드로 쓸 수 있습니다
// same action
crosscutting.before(
{ hello: function() {} },
/hello/,
function(){}
);
crosscutting.waeve(
{ hello: function() {} },
/hello/,
crosscutting.Aspect.BEFORE,
function(){}
);
- crosscutting.before
- crosscutting.Aspect.BEFORE 동작과 같습니다
- crosscutting.after
- crosscutting.Aspect.AFTER 동작과 같습니다
- crosscutting.around
- crosscutting.Aspect.AROUND 동작과 같습니다
- crosscutting.exception
- crosscutting.Aspect.EXCEPTION 동작과 같습니다
Example Codes
예제에서 사용할 AOP를 적용할 객체입니다. 간단한 덧셈 뺄셈 프로그램입니다.
// Simple Calculator
var calculator = {
plus: function(a, b) {
return a + b;
},
minus: function(a, b) {
return a - b;
}
};
전달된 인자가 모두 숫자형인지 검사하는 AOP 적용(BEFORE 어드바이스) 예제
숫자형이 아닐 경우 TypeError를 Throw 하도록 했습니다.
// Validator Advice
var argumentCheck = function(options) {
var args = options.args;
for(var i = 0, len = args.length; i < len; i++) {
if(typeof args[i] !== 'number') {
throw new TypeError("all arguments must be number type");
}
}
};
crosscutting.before(calculator, true, argumentCheck);
// maybe throw TypeError.
calculator.plus("one", "two");
객체의 메서드가 실행될 때 로그를 찍는 BEFORE 어드바이스 예제
메서드 실행 전 메서드의 이름과 함께 로그가 찍힐 것입니다.
var logAdvice = function(options) {
console.log("method " + options.method + " execute");
};
// plus method aop apply, type BEFORE
crosscutting.weave(
calculator,
function(name) {
return name === "plus";
},
crosscutting.Aspect.AdviceType.BEFORE
logAdvice
);
// console.log("method plus execute")
var result = calculator.plus(1, 1);
AROUND 어드바이스 예제
타겟 메서드의 실행을 제어할 수 있고 결과의 조작도 할 수 있습니다. 이 예제에서는 calculator의 결과를 문자열로 변환하여 반환하겠습니다.
var stringify = function(todo, options) {
var result = todo();
return result + ""; // toString
};
crosscutting.around(calculator, true, logAdvice);
// print console "string"
console.log(typeof calculator.plus(1, 1));
EXCEPTION 어드바이스 예제
위에 나왔던 인자가 숫자인지 검증하는 AOP를 적용 했다고 가정합니다. 이 예제에서는 일부러 오류를 내고 있습니다.
var throwHandler = function(options) {
var exception = options.exception;
console.log("Error! " + exception.name + ". cause : " + exception.message);
if(exception.stack) console.log(exception.stack);
};
// aop apply, type EXCEPTION
crosscutting.exception(calculator, /^plus/, throwHandler);
// string arguments
var result = calculator.plus("one", "two");
/*
Error: arguments must be number type
at Object.calculator.plus ( ... )
at ... some stacktrace ...
*/
Contributer
- Mail: javarouka@gmail.com
- Github: https://github.com/javarouka
- Facebook: https://www.facebook.com/hanghui.i
- Twitter: @YiHanghee