หลังจากลองบน Ruby ไปแล้ว คราวนี้มาถึงตาของ ActionScript บ้าง(ให้ตายเถอะ นานๆ จะได้มาเล่นอะไรบน Flash คิดถึงจริงๆ)
ฝั่ง Ruby ใช้ตัวช่วยคือ AspectR
ฝั่ง ActionScript 2.0 ใช้ตัวช่วยคือ As2lib
เล็กน้อย สำหรับ As2lib
As2lib เป็น open source framework ตัวนึงที่ถูกออกแบบมาให้ทำงานกับ Flash MX 2004+(หนักไปทาง ActionScript 2.0) โดยมันจะไปช่วยในเรื่อง event handling, error handling, logging, overloading and reflections และยังบรรจุ testing framework,input/output(io) framework, aspect-oriented programming (AOP) framework และ regular expression (RegExp) framework(เป็นอีกหนึ่งอย่างที่ผมจะลอง)
เริ่มต้นด้วยการ download As2lib มาติดตั้งกันก่อน
จากนั้น extract เอา src folder มาใช้ โดยการ copy ไปวางไว้ที่ path เดียวกับ file.fla ที่เราจะใช้งาน แล้วก็สร้าง file.fla มาเลย
แล้วไป set classpath ก่อน ไปที่ File > Publish Settings เลือก tab ที่เป็น Flash กดปุ่ม Settings (ข้างๆ ActionScript version dropdown)
จากนั้นปุ่ม + บนหน้าต่างที่เด้งขึ้นมา แล้วเพิ่ม ./src เข้าไปแล้วกด ok แล้ว save file นี้ไว้บน path เดียวกับ src folder
มาลง code กันบ้าง
เริ่มต้นจาก Product class
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| class Product{
private var price:Number;
public function Product(){
price = 0;
}
public function setPrice(p:Number):Number{
price = p;
return price;
}
public function getPrice():Number{
return price;
}
}
|
save เป็น Product.as ไว้ที่ path เดียวกับ file.fla ของเรา
มาดู Logger class บ้าง
1
2
3
4
5
6
7
8
9
| class Logger{
function Logger(){
}
public function writeLog(msg:String){
trace(msg);
}
}
|
save เป็น Logger.as ไว้ที่ path เดียวกับ file.fla ของเรา
จริงๆ แล้ว flash เขียนต่อ file ไม่ได้ แต่มันเป็นแค่ตัวอย่างครับ จะได้เหมือนกับของ Ruby
บน Product class ถ้าเอา comment ออก ก็จะทำงานได้ตามปกติ โดยไม่ต้องอาศัย aspect
ทีนี้ จะมาลองสร้าง aspect กันบ้าง
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
| import org.as2lib.aop.Aspect;
import org.as2lib.aop.aspect.AbstractAspect;
import org.as2lib.aop.advice.AbstractAdvice;
import org.as2lib.aop.JoinPoint;
class LoggingAspect extends AbstractAspect implements Aspect {
private var logger:Logger;
function LoggingAspect(){
logger = new Logger();
addAdvice(AbstractAdvice.BEFORE, getBeforeOperationsPointcut(), beforeOperationsAdvice);
}
private function getOperationsPointcut(Void):String {
return "execution(Product.setPrice())";
}
private function beforeOperationsAdvice(joinPoint:JoinPoint, args:FunctionArguments) {
logger.writeLog(Product(joinPoint.getThis()).getPrice() + " is changed to " + args);
}
private function aroundOperationsAdvice(joinPoint:JoinPoint, args:FunctionArguments) {
logger.writeLog(Product(joinPoint.getThis()).getPrice() + " is changed to " + args);
var result = joinPoint.proceed(args);
logger.writeLog(tick() + " " + joinPoint.getInfo().getDeclaringType().getName() + "#" + joinPoint.getInfo().getName() + ": returned " + result + " and exited");
return result;
}
private function tick():String{
return new Date().getFullYear() + "-" + new Date().getMonth() + "-" + new Date().getDate();
}
}
|
ที่ comment ใน beforeOperationsAdvice ไว้ จะเป็นวิธีการเอาข้อมูลออกมาใช้งาน ไม่ว่าจะเป็น classname, method name หรือว่า arguments ต่างๆ ที่รับเข้ามา
เริ่มต้นที่การ import class ต่างๆ เข้ามาใช้งาน
ใน constructor
1
| addAdvice(AbstractAdvice.BEFORE, getOperationsPointcut(), beforeOperationsAdvice);
|
อันนี้เป็นการ set pointcut โดยการใส่ advice และ join point เข้าไป
ที่เหลือก็เป็นการประกาศการทำงาน
จากนั้นมาดูการ weave กันบ้าง
1
2
3
4
5
6
7
8
9
10
11
12
| import org.as2lib.aop.Aspect;
import org.as2lib.aop.Weaver;
import org.as2lib.aop.weaver.SimpleWeaver;
var logging_aspect = new LoggingAspect();
var weaver:SimpleWeaver = new SimpleWeaver();
weaver.addAspect(logging_aspect, [Product]);
weaver.weave();
var product:Product = new Product();
product.setPrice(7);
product.setPrice(5);
|
code ตรงนี้ ก็ import library ต่างๆ ที่จำเป็น
แล้วมาประกาศการ weave (ถ้ามีหลาย class ให้เพิ่มตรง addAspect เอา เป็น [Product, AnyClass] เป็นต้น)
แล้วค่อยมาเป็นการประกาศการทำงานบน class ของเรา
ซึ่งจะคล้ายๆ กับของ Ruby แต่จริงๆ ผมชอบแบบ AspectJ มากกว่า ที่ไป weave กันตอน compile เอา(บน Ruby เด๋วมีแบบนี้เหมือนกัน ใจเย็นพี่น้อง)
มาดูผลที่ได้

มาลอง Around บ้าง ก็สลับ comment เป็น
1
2
|
addAdvice(AbstractAdvice.AROUND, getOperationsPointcut(), aroundOperationsAdvice);
|
มาดูผลที่ได้

ข้อมูลจาก
www.simonwacker.com (as2lib version ใหม่มันมีปัญหา ถ้าลองตามใน site ของ simon wacker จะรันไม่ออก ลองตามของไอ่เหน่งดีกว่า modify ให้แล้ว)