本文介绍使用AspectJ实现设计模式之迭代子模式,文章以一个购买商品的例子实现AspectJ版本的内禀迭代子。
由于迭代子模式应用广泛,文章在此不再赘述模式的具体内容了,我使用具体的例子说明如何使用AspectJ来完成模式所述的功能。此例子参考了<<Java与模式>>书中关于迭代子模式的示例。
图1 ——例子系统UML图
例子系统首先定义一个抽象的购物筐类Purchase,以便给出所有的具体购物筐的行为和需要实现的方法。购物筐PurchaseOfCopA和PurchaseOfCopB继承自Purchase,它们分别创建一个前向迭代ForwardIterator和一个后向迭代子BackawrdIterator用于元素的遍历。系统包含一个抽象方面IteratorAspect,它使用Inter-type声明了Purchase类的方法createIterator用来创建迭代子以及适配器类PurchaseIterator,它实现接口java.util.Iterator,同时还定义了一个抽象的pointcut
iterator供子方面使用。子方面ForwardIteratorAspect和BackwardIteratorAspect分别定义各自的iterator
pointcut捕捉对应的Purchase子类的createIterator方法调用并提供Advice around实现createIterator方法返回对应类别的迭代子。最重要的是这两个子方面中的内部类ForwardIterator和BackwardIterator,它们实现了前向迭代和后向迭代的逻辑。
抽象类Purchase.java
import java.util.*;
public abstract class Purchase {
private Collection elements=new ArrayList();
public void append(Object obj){//添家元素
elements.add(obj);
}
public void remove(Object obj){//删除元素
elements.remove(obj);
}
public Object currentItem(int index){//当前元素
return ((ArrayList)elements).get(index);
}
public int count(){//元素总数
return elements.size();
}
}
具体类PurchaseOfCopA和PurchaseOfCopB
public class PurchaseOfCopA {}
public class PurchaseOfCopB{}
适配器类PurchaseIterator.java
public class PurchaseIterator {}
抽象方面IteratorAspect.java
import java.util.Iterator;
public abstract aspect IteratorAspect {
public Iterator Purchase.createIterator(){ return
null; }
abstract pointcut iterator(Purchase purchase);
//PurchaseIterator实现Iterator,作为适配器类,供子方面使用
declare parents : PurchaseIterator implements
Iterator;
int PurchaseIterator.current=0;
Purchase PurchaseIterator.purchase;
//Iterator接口方法的缺省实现
public boolean PurchaseIterator.hasNext(){ return
false;}
public Object PurchaseIterator.next(){ return
null;}
public void PurchaseIterator.remove(){}
public void PurchaseIterator.append(Object obj){}
}
具体方面ForwardIteratorAspect.java
import java.util.Iterator;
public aspect ForwardIteratorAspect extends IteratorAspect{
declare parents : PurchaseOfCopA extends Purchase;
pointcut iterator(Purchase purchase) : target(purchase)
&& call(Iterator createIterator())
&& if(purchase instanceof PurchaseOfCopA);
//捕捉前向迭代子的创建方法调用
Iterator around(Purchase purchase) : iterator(purchase){//创建方法执行逻辑,构造前向迭代器
return new ForwardIterator(purchase);
}
private static class ForwardIterator extends PurchaseIterator{//前向迭代子内部类
public ForwardIterator(Purchase purchase){
super();
this.purchase=purchase;
current=0; //当前游标为第一个元素
}
public boolean hasNext(){
return (current<=purchase.count()-1);
}
public Object next(){
if(!hasNext()){
throw new ArrayIndexOutOfBoundsException("Iterator
out of Bounds");
}
return purchase.currentItem(current++);
}
}
}
具体方面BackwardIteratorAspect.java
import java.util.Iterator;
public aspect BackwardIteratorAspect extends IteratorAspect{
declare parents : PurchaseOfCopB extends Purchase;
pointcut iterator(Purchase purchase) : target(purchase)
&& call(Iterator createIterator())
&& if(purchase instanceof PurchaseOfCopB);//捕捉后向迭代子的创建方法调用
Iterator around(Purchase purchase) : iterator(purchase){//创建方法执行逻辑,构造后向迭代器
return new BackwardIterator(purchase);
}
private static class BackardIterator extends PurchaseIterator{//后向迭代子内部类
public BackwardIterator(Purchase purchase){
super();
this.purchase=purchase;
current=purchase.count()-1;//当前游标为最后元素
}
public boolean hasNext(){
return (current>=0);
}
public Object next(){
if (!hasNext()) {
throw new ArrayIndexOutOfBoundsException("Iterator
out of Bounds");
} else {
return purchase.currentItem(current--);
}
}
}
}
示例代码Demo.java
public class Demo {
public static void main(String [] args)throws
Exception{
Purchase purchaseA=new PurchaseOfCopA();
Purchase purchaseB=new PurchaseOfCopB();
purchaseA.append("Dish Washer");
purchaseA.append("Hair Dresser");
purchaseA.append("Microwave");
System.out.println(“Creating forward iterator for
purchase A”);
printItems(purchaseA);
purchaseB.append("Hair Dresser");
purchaseB.append("Diskman");
purchaseB.append("Digital Camera");
purchaseB.append("PC");
purchaseB.append("Dish Washer");
System.out.println(“Creating backward iterator
for purchase B”);
printItems(purchaseB);
}
private static void printItems(Purchase purchase){//格式化输出元素
int index=1;
if(isBackforward(purchase)){
index=purchase.count();
}
Iterator it=purchase.createIterator();
while(it.hasNext()){
System.out.println("Item :No "+index+":"+it.next().toString());
if(isBackforward(purchase)){
index--;
}
else{
index++;
}
}
}
private static boolean isBackforward(Purchase
purchase){//是后向迭代吗?
if(purchase instanceof PurchaseOfCopB){
return true;
}
return false;
}
}
输出结果如下
Creating forward iterator for purchase A
Item No.1 : Dish Washer
Item No.2 : Hair Dresser
Item No.3 : Microwave
Creating backward iterator for purchase B
Item No.5 : Dish Washer
Item No.4 : PC
Item No.3 : Digital Camera
Item No.2 : Discman
Item No.1 : Hair Dresser
至此,我已经使用AspectJ实现了一个使用内禀迭代子的例子,有兴趣的读者可以尝试实现使用外禀迭代子的相同例子。另因为下个月本人要参加重要的考试,所以本系列的其余文章可能会推出的慢一点,还请各位读者见谅。同时由于许多读者不知道AspectJ语法,所以我将会在另一系列中详细介绍AspectJ的语法、配置和使用范例,希望能提高大家对AspectJ以及AOP面向方面编程的兴趣。
|