AspectJ實現設計模式(三)——工廠方法模式 (轉)

gugu99發表於2007-08-15
AspectJ實現設計模式(三)——工廠方法模式 (轉)[@more@]

 本文將繼續介紹使用ectJ實現設計之工廠方法模式,文章以農場園丁管理水果(讀過與模式的讀者會很熟悉它)例子的形式描述了工廠方法模式AspectJ版本的參考實現。:namespace prefix = o ns = "urn:schemas--com::office" />

 工廠方法模式根據產品的等級結構使用對應的工廠來建立特定的產品,它一般包括抽象工廠、具體工廠和抽象產品、具體產品,每一個特定工廠用於建立一個對應的產品。模式的簡易UML圖例如下

下面是使用AspectJ實現的工廠方法模式UML圖

抽象方面FactoryMethodProtocol很簡單隻定義了抽象pointcut createMethod用於捕捉特定應用的建立方法(也可以省略)。

FactoryMethodProtocol抽象方面

public abstract aspect FactoryMethodProtocol {
abstract pointcut createMethod();}

FactoryMethodImpl.java

public aspect FactoryMethodImpl extends FactroyMethodProtocol{

  public Fruit FruitGardener.factory(){//為建立介面定義工廠方法

  return null;

  }

  //Inter-type宣告具體建立類並實現建立介面

  declare parents : AppleGardener implements FruitGardener;

  declare parents : GrapeGardener implements FruitGardener;

  //指定createMethod捕捉FruitGardener及其子類的建立方法

  pointcut createMethod() : call(Fruit FruitGardener+.factory());

  Fruit around(FruitGardener gardener) : target(gardener) && createMethod(){

  return chooseGardener(gardener);//工廠方法返回抽象產品。

  }

  private Fruit chooseGardener(FruitGardener gardener){

  if(gardener instanceof AppleGardener){

  return new Apple();

  }

  else if(gardener instanceof GrapeGardener){

  return new Grape();

  }

  else{

  throw new RuntimeException("No such kind of fruit");

  }

  }

  //宣告編譯時錯誤:當客戶直接使用new建立具體產品時發生。

  //目的:強制完全按照工廠方法的形式建立產品。

  //可選為宣告警告  declare warning : [pointcut] : [warn msg]

  declare error : !(within(FruitGardener+) && !createMethod())

  &&!within(FactoryMethodImpl) && call(Fruit+.new(..))

: "You can only create fruits through the method factory provd by FruitGardener and its subclass";
  }

三個空的建立宣告,其建立邏輯在FactoryMethodImpl方面中定義

public interface FruitGardener {}

public class GrapeGardener {}

public class AppleGardener {}

Fruit.java抽象產品類

public abstract class Fruit {

  public abstract void grow();

  public abstract void harvest();

  public abstract void plant();

}

Apple.java產品類

public class Apple extends Fruit{

  public void grow(){

  System.out.println("Apple is growing...");

  }

  public void harvest(){

  System.out.println("Apple has been harvested");

  }

  public void plant(){

  System.out.println("Apple has been planted");

  }

}

Grape.java產品類

public class Grape extends Fruit{

  public void grow(){

  System.out.println("Grape is growing...");

  }

  public void harvest(){

  System.out.println("Grape has been harvested");

  }

  public void plant(){

  System.out.println("Grape has been planted");

  }

}

Demo.java測試程式碼

public class Demo {
  public static void main(String[] args) {
  FruitGardener gardener=new AppleGardener();

  Fruit fruit=gardener.factory();//建立Apple

  fruit.grow();

  fruit.harvest();

  fruit.plant();

  gardener=new GrapeGardener();

  fruit=gardener.factory();//建立Grape

  fruit.grow();

  fruit.harvest();

fruit.plant();

//new Apple();new Grape();//產生編譯錯誤,不能直接生成產品

}
}

測試程式碼使用蘋果和葡萄園丁分別建立了蘋果和葡萄,其執行結果如下

有一點值得注意,如果在Demo中加入new Apple()或new Grape()等直接建立產品的語句,則ajc會根據在FactoryMethodImpl方面中宣告的錯誤而無法編譯成功,並會得到如下輸出:

D:JavaDevjbuiderAOPFactoryMethodsrcaopfactorymethodDemo.java 26 You can only create fruits through the method factory provided by FruitGardener and its subclass  1 error.

至此,我已經使用AspectJ完全實現了一個使用工廠方法模式設計的農場園丁的例子。本系列之四將介紹如何用AspectJ實現抽象工廠模式。

 

參考資料

1.<>  閻宏著  電子工業出版社

2.

宣告

本文由starchu1981保留版權,如果需要轉貼請寫明作者和出處。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10748419/viewspace-959327/,如需轉載,請註明出處,否則將追究法律責任。

相關文章