asato <asato@ncfreak.com>
最終更新日 : 2004/3/1 (2002/9/26 より)
テスト環境
Abstract Factory
考慮点
AspectJ を使った Abstract Factory に関するテクニックの種類
Abstract Factory の導入
適用可能性:
結果:
保持されるもの:
サンプルコード:
package dp.af;
public class ProductA {
public void method() {
System.out.println("ProductA");
}
}
package dp.af;
public class ProductB {
public void method() {
System.out.println("ProductB");
}
}
package dp.af;
public class SomeClass {
public void method() {
ProductA productA = new ProductA();
ProductB productB = new ProductB();
productA.method();
productB.method();
}
}
package dp.af;
public interface AbstractFactory {
public ProductA createProductA();
public ProductB createProductB();
}
package dp.af;
public class ConcreteFactory implements AbstractFactory {
public ProductA createProductA() {
return new SubProductA();
}
public ProductB createProductB() {
return new SubProductB();
}
}
package dp.af;
public class SubProductA extends ProductA {
public void method() {
System.out.println("SubProductA");
}
}
package dp.af;
public class SubProductB extends ProductB {
public void method() {
System.out.println("SubProductB");
}
}
package dp;
import dp.af.*;
public class Client {
public static void main(String[] args) {
AbstractFactory fact = new ConcreteFactory();
new SomeClass().method(fact);
}
}
package dp.af;
public aspect AbstractFactoryAspect {
public void SomeClass.method(AbstractFactory fact) {
method();
}
pointcut clientMethod(AbstractFactory fact) :
args(fact) && call( void SomeClass.method(AbstractFactory) );
pointcut newProductA(AbstractFactory fact) :
call( ProductA.new() ) && cflow( clientMethod(fact) );
pointcut newProductB(AbstractFactory fact) :
call( ProductB.new() ) && cflow( clientMethod(fact) );
ProductA around (AbstractFactory fact) : newProductA(fact) {
return fact.createProductA();
}
ProductB around (AbstractFactory fact) : newProductB(fact) {
return fact.createProductB();
}
}
SubProductA SubProductB
Introduction 使用による新たな種類の部品の追加
意図: Introduction を使って新たな種類の部品を生成するメソッドを実装する。
サンプルコード:
package dp.af;
public interface ProductA {
public void method();
}
package dp.af;
public class ConcreteProductA1 implements ProductA {
public void method() {
System.out.println("ConcreteProductA1");
}
}
package dp.af;
public class ConcreteProductA2 implements ProductA {
public void method() {
System.out.println("ConcreteProductA2");
}
}
package dp.af;
public interface ProductB {
public void method();
}
package dp.af;
public class ConcreteProductB1 implements ProductB {
public void method() {
System.out.println("ConcreteProductB1");
}
}
package dp.af;
public class ConcreteProductB2 implements ProductB {
public void method() {
System.out.println("ConcreteProductB2");
}
}
package dp.af;
public interface AbstractFactory {
public ProductA createProductA();
public ProductB createProductB();
}
package dp.af;
public class ConcreteFactory1 implements AbstractFactory {
public ProductA createProductA() {
return new ConcreteProductA1();
}
public ProductB createProductB() {
return new ConcreteProductB1();
}
}
package dp.af;
public class ConcreteFactory2 implements AbstractFactory {
public ProductA createProductA() {
return new ConcreteProductA2();
}
public ProductB createProductB() {
return new ConcreteProductB2();
}
}
package dp;
import dp.af.*;
public class Client {
public static void main(String[] args) {
AbstractFactory fact = new ConcreteFactory1();
ProductA productA = fact.createProductA();
ProductB productB = fact.createProductB();
ProductC productC = fact.createProductC();
productA.method();
productB.method();
productC.method();
}
}
package dp.af;
public interface ProductC {
public void method();
}
package dp.af;
public class ConcreteProductC1 {
public void method() {
System.out.println("ConcreteProductC1");
}
}
package dp.af;
public class ConcreteProductC2 {
public void method() {
System.out.println("ConcreteProductC2");
}
}
package dp.af;
public aspect AbstractFactoryAspect {
declare parents: ConcreteProductC1 implements ProductC;
declare parents: ConcreteProductC2 implements ProductC;
public abstract ProductC AbstractFactory.createProductC();
public ProductC ConcreteFactory1.createProductC() {
return new ConcreteProductC1();
}
public ProductC ConcreteFactory2.createProductC() {
return new ConcreteProductC2();
}
}
ConcreteProductA1 ConcreteProductB1
積極的な Introduction の使用による Abstract Factory の実装
package dp.af;
public interface ProductA {
public void method();
}
package dp.af;
public class ConcreteProductA1 {
public void method() {
System.out.println("ConcreteProductA1");
}
}
package dp.af;
public class ConcreteProductA2 {
public void method() {
System.out.println("ConcreteProductA2");
}
}
package dp.af;
public interface ProductB {
public void method();
}
package dp.af;
public class ConcreteProductB1 {
public void method() {
System.out.println("ConcreteProductB1");
}
}
package dp.af;
public class ConcreteProductB2 {
public void method() {
System.out.println("ConcreteProductB2");
}
}
package dp.af;
public interface AbstractFactory { }
package dp.af;
public class ConcreteFactory1 { }
package dp.af;
public class ConcreteFactory2 { }
package dp;
import dp.af.*;
public class Client {
public static void main(String[] args) {
AbstractFactory fact = new ConcreteFactory1();
ProductA productA = fact.createProductA();
ProductB productB = fact.createProductB();
productA.method();
productB.method();
}
}
package dp.af;
public aspect AbstractFactoryAspect {
declare parents: ConcreteFactory1 implements AbstractFactory;
declare parents: ConcreteFactory2 implements AbstractFactory;
declare parents: ConcreteProductA1 implements ProductA;
declare parents: ConcreteProductA2 implements ProductA;
declare parents: ConcreteProductB1 implements ProductB;
declare parents: ConcreteProductB2 implements ProductB;
public abstract ProductA AbstractFactory.createProductA();
public abstract ProductB AbstractFactory.createProductB();
public ProductA ConcreteFactory1.createProductA() {
return new ConcreteProductA1();
}
public ProductB ConcreteFactory1.createProductB() {
return new ConcreteProductB1();
}
public ProductA ConcreteFactory2.createProductA() {
return new ConcreteProductA2();
}
public ProductB ConcreteFactory2.createProductB() {
return new ConcreteProductB2();
}
}
ConcreteProductA1 ConcreteProductB1
実装:
package dp.af;
import java.util.Map;
import java.util.HashMap;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.reflect.MethodSignature;
public aspect AbstractFactoryAspect {
declare parents: ConcreteFactory1 implements AbstractFactory;
declare parents: ConcreteFactory2 implements AbstractFactory;
declare parents: ConcreteProductA1 implements ProductA;
declare parents: ConcreteProductA2 implements ProductA;
declare parents: ConcreteProductB1 implements ProductB;
declare parents: ConcreteProductB2 implements ProductB;
private static Map productMap = new HashMap();
private static Map productAMap = new HashMap();
private static Map productBMap = new HashMap();
static {
productMap.put(ProductA.class, productAMap);
productMap.put(ProductB.class, productBMap);
productAMap.put(ConcreteFactory1.class, ConcreteProductA1.class);
productAMap.put(ConcreteFactory2.class, ConcreteProductA2.class);
productBMap.put(ConcreteFactory1.class, ConcreteProductB1.class);
productBMap.put(ConcreteFactory2.class, ConcreteProductB2.class);
}
pointcut createProduct() :
call( * AbstractFactory.createProduct*() );
Object around() : createProduct() {
return createProduct( thisJoinPoint );
}
public ProductA AbstractFactory.createProductA() { return null; }
public ProductB AbstractFactory.createProductB() { return null; }
private static Object createProduct(JoinPoint joinPoint) {
try {
Class retType =
( (MethodSignature)joinPoint.getSignature() ).getReturnType();
Map map = (Map)productMap.get( retType );
Class clazz = (Class)map.get( joinPoint.getTarget().getClass() );
return clazz.newInstance();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
実装 - その 4
4.新たな種類の部品に対応することが困難である。 新たな種類の部品に対応できるように Abstract Factory パターンを拡張することは容易ではない。なぜならば、AbstractFactory クラスのインタフェースは生成される部品の集合を固定しているからである。新たな種類の部品への対応は、インタフェースの修正が必要になるために、AbstractFactory クラスだけでなくそのすべてのサブクラスを修正しなければならなくなる。
サンプルコード
package dp.lib;
public interface ProductA { }
package dp.lib;
public interface ProductB { }
package dp.lib;
public class ConcreteProductA implements ProductA { }
package dp.lib;
public class ConcreteProductB implements ProductB { }
package dp.lib;
public interface AbstractFactory {
public ProductA createProductA();
public ProductB createProductB();
}
package dp.lib;
public class ConcreteFactory implements AbstractFactory {
public ProductA createProductA() {
return new ConcreteProductA();
}
public ProductB createProductB() {
return new ConcreteProductB();
}
}
package dp.lib;
public class Main { // 単に動作確認用
public static void main(String[] args) {
AbstractFactory fact = new ConcreteFactory();
System.out.println( fact.createProductA() );
System.out.println( fact.createProductB() );
}
}
実行結果:
dp.lib.ConcreteProductA@360be0 dp.lib.ConcreteProductB@192d342アプリケーション側 (dp.app パッケージ):
package dp.app;
public interface ProductC { }
package dp.app;
public class ConcreteProductC implements ProductC { }
package dp.app;
import dp.lib.AbstractFactory;
import dp.lib.ConcreteFactory;
public aspect AbstractFactoryAspect {
public abstract ProductC AbstractFactory.createProductC();
public ProductC ConcreteFactory.createProductC() {
return new ConcreteProductC();
}
}
package dp.app;
import dp.lib.AbstractFactory;
import dp.lib.ConcreteFactory;
public class Main {
public static void main(String[] args) {
AbstractFactory fact = new ConcreteFactory();
System.out.println( fact.createProductA() );
System.out.println( fact.createProductB() );
System.out.println( fact.createProductC() );
}
}
実行結果:
dp.lib.ConcreteProductA@1ddebc3 dp.lib.ConcreteProductB@194ca6c dp.app.ConcreteProductC@9931f5
実装 - その 5
public interface ProductA { }
public interface ProductB { }
public class ConcreteProductA implements ProductA { }
public class ConcreteProductB implements ProductB { }
public class MyConcreteProductA implements ProductA { }
public class MyConcreteProductB implements ProductB { }
public class AbstractFactory {
public ProductA createProductA() {
return new ConcreteProductA();
}
public ProductB createProductB() {
return new ConcreteProductB();
}
}
public aspect MyAbstractFactoryAspect {
private boolean isActive;
public static void activate() {
MyAbstractFactoryAspect.aspectOf().isActive = true;
}
private pointcut isActive() :
if (MyAbstractFactoryAspect.aspectOf().isActive);
ProductA around() :
call(ProductA AbstractFactory.createProductA() ) && isActive()
{
return new MyConcreteProductA();
}
ProductB around() :
call(ProductB AbstractFactory.createProductB() ) && isActive()
{
return new MyConcreteProductB();
}
}
public class Client {
public static void main(String[] args) {
AbstractFactory fact = new AbstractFactory();
System.out.println( fact.createProductA() );
System.out.println( fact.createProductB() );
MyAbstractFactoryAspect.activate();
System.out.println( fact.createProductA() );
System.out.println( fact.createProductB() );
}
}
実行結果:
dp.af.ConcreteProductA@1f33675 dp.af.ConcreteProductB@1690726 dp.af.MyConcreteProductA@9931f5 dp.af.MyConcreteProductB@1f1fba0
新しい ConcreteFactory (or AbstractFactoryAspect) が増えた場合は?
public class YourConcreteProductA implements ProductA { }
public class YourConcreteProductB implements ProductB { }
public aspect YourAbstractFactoryAspect {
private boolean isActive;
public static void activate() {
YourAbstractFactoryAspect.aspectOf().isActive = true;
}
private pointcut isActive() :
if (YourAbstractFactoryAspect.aspectOf().isActive);
ProductA around() :
call(ProductA AbstractFactory.createProductA() ) && isActive()
{
return new YourConcreteProductA();
}
ProductB around() :
call(ProductB AbstractFactory.createProductB() ) && isActive()
{
return new YourConcreteProductB();
}
}
privileged public aspect AbstractFactoryAspectManager {
after() : call( void YourAbstractFactoryAspect.activate() ) {
MyAbstractFactoryAspect.aspectOf().isActive = false;
}
after() : call( void MyAbstractFactoryAspect.activate() ) {
YourAbstractFactoryAspect.aspectOf().isActive = false;
}
}
public class Client {
public static void main(String[] args) {
AbstractFactory fact = new AbstractFactory();
System.out.println( fact.createProductA() );
System.out.println( fact.createProductB() );
MyAbstractFactoryAspect.activate();
System.out.println( fact.createProductA() );
System.out.println( fact.createProductB() );
YourAbstractFactoryAspect.activate();
System.out.println( fact.createProductA() );
System.out.println( fact.createProductB() );
MyAbstractFactoryAspect.activate();
System.out.println( fact.createProductA() );
System.out.println( fact.createProductB() );
}
}
実行結果:
dp.af.ConcreteProductA@7c6768 dp.af.ConcreteProductB@5483cd dp.af.MyConcreteProductA@1f1fba0 dp.af.MyConcreteProductB@13c5982 dp.af.YourConcreteProductA@14b7453 dp.af.YourConcreteProductB@1d5550d dp.af.MyConcreteProductA@c2ea3f dp.af.MyConcreteProductB@a0dcd9
実装 - その 6
public interface ProductA { }
public interface ProductB { }
public class ConcreteProductA implements ProductA { }
public class ConcreteProductB implements ProductB { }
public class AbstractFactory {
public ProductA createProductA() {
return new ConcreteProductA();
}
public ProductB createProductB() {
return new ConcreteProductB();
}
}
public aspect AbstractFactoryAspect pertarget( target(AbstractFactory) ) {
private boolean isActive;
public void activate() {
this.isActive = true;
}
public void deactivate() {
this.isActive = false;
}
ProductA around() : call( ProductA AbstractFactory.createProductA() ) {
if (isActive) {
return new MyConcreteProductA();
} else {
return proceed();
}
}
ProductB around() : call( ProductB AbstractFactory.createProductB() ) {
if (isActive) {
return new MyConcreteProductB();
} else {
return proceed();
}
}
private static class MyConcreteProductA implements ProductA { }
private static class MyConcreteProductB implements ProductB { }
}
public class Client {
public static void main(String[] args) {
AbstractFactory fact = new AbstractFactory();
System.out.println( fact.createProductA() );
System.out.println( fact.createProductB() );
AbstractFactoryAspect.aspectOf(fact).activate();
System.out.println( fact.createProductA() );
System.out.println( fact.createProductB() );
AbstractFactoryAspect.aspectOf(fact).deactivate();
System.out.println( fact.createProductA() );
System.out.println( fact.createProductB() );
}
}
実行結果:
dp.af.ConcreteProductA@7c6768 dp.af.ConcreteProductB@5483cd dp.af.AbstractFactoryAspect$MyConcreteProductA@19ee1ac dp.af.AbstractFactoryAspect$MyConcreteProductB@1befab0 dp.af.ConcreteProductA@13c5982 dp.af.ConcreteProductB@1186fab
実装 - その 7
public interface ProductA { }
public interface ProductB { }
public class AbstractFactory {
public ProductA createProductA() {
return new DefaultProductA();
}
public ProductB createProductB() {
return new DefaultProductB();
}
private static class DefaultProductA implements ProductA { }
private static class DefaultProductB implements ProductB { }
}
public interface Deployable {
public static aspect Impl {
private boolean Deployable.isActive;
public void Deployable.activate() {
this.isActive = true;
}
public void Deployable.deactivate() {
this.isActive = false;
}
public boolean Deployable.isActive() {
return isActive;
}
}
}
public interface Deployer {
public void deploy(Deployable deployable);
public static aspect Impl {
void around(Deployable deployable) :
args(deployable) &&
call(void Deployer.deploy(Deployable)) &&
if (deployable != null)
{
deployable.activate();
proceed(deployable);
deployable.deactivate();
}
}
}
public aspect AbstractFactoryAspect implements Deployable {
private pointcut isActive() :
if ( AbstractFactoryAspect.aspectOf().isActive() );
private static aspect Impl percflow( execution(void Deployer.deploy(Deployable)) && isActive() ) {
ProductA around() : call( ProductA AbstractFactory.createProductA() ) {
return new ConcreteProductA();
}
ProductB around() : call( ProductB AbstractFactory.createProductB() ) {
return new ConcreteProductB();
}
}
private static class ConcreteProductA implements ProductA { }
private static class ConcreteProductB implements ProductB { }
}
public class Client {
public static void main(String[] args) {
final AbstractFactory fact = new AbstractFactory();
System.out.println( fact.createProductA() );
System.out.println( fact.createProductB() );
Deployer deployer = new Deployer() {
public void deploy(Deployable deployable) {
System.out.println( fact.createProductA() );
System.out.println( fact.createProductB() );
}
};
deployer.deploy( AbstractFactoryAspect.aspectOf() );
}
}
実行結果:
dp.af.AbstractFactory$DefaultProductA@9931f5 dp.af.AbstractFactory$DefaultProductB@1f1fba0 dp.af.AbstractFactoryAspect$ConcreteProductA@c2ea3f dp.af.AbstractFactoryAspect$ConcreteProductB@1034bb5
使用例 - その 1
public interface Monster { } // ProductA
public interface Soldier { } // ProductB
public class EnemyFactory { // AbstractFactory
public Monster createMonster() {
return new DefaultMonster();
}
public Soldier createSoldier() {
return new DefaultSoldier();
}
private static class DefaultMonster implements Monster {}
private static class DefaultSoldier implements Soldier {}
}
public interface Deployable {
public static aspect Impl {
private boolean Deployable.isActive;
public void Deployable.activate() {
this.isActive = true;
}
public void Deployable.deactivate() {
this.isActive = false;
}
public boolean Deployable.isActive() {
return isActive;
}
}
}
public interface Deployer {
public void deploy(Deployable deployable);
public static aspect Impl {
void around(Deployable deployable) :
args(deployable) &&
call(void Deployer.deploy(Deployable)) &&
if (deployable != null)
{
deployable.activate();
proceed(deployable);
deployable.deactivate();
}
}
}
public aspect EasyModeAspect implements Deployable {
private pointcut isActive() : if ( EasyModeAspect.aspectOf().isActive() );
private static aspect Impl percflow( execution(void Deployer.deploy(Deployable)) && isActive() ) {
Monster around() : call( Monster EnemyFactory.createMonster() ) {
return new EasyModeMonster();
}
Soldier around() : call( Soldier EnemyFactory.createSoldier() ) {
return new EasyModeSoldier();
}
}
private static class EasyModeMonster implements Monster {}
private static class EasyModeSoldier implements Soldier {}
}
public aspect HardModeAspect implements Deployable {
private pointcut isActive() : if ( HardModeAspect.aspectOf().isActive() );
private static aspect Impl percflow( execution(void Deployer.deploy(Deployable)) && isActive() ) {
Monster around() : call( Monster EnemyFactory.createMonster() ) {
return new HardModeMonster();
}
Soldier around() : call( Soldier EnemyFactory.createSoldier() ) {
return new HardModeSoldier();
}
}
private static class HardModeMonster implements Monster {}
private static class HardModeSoldier implements Soldier {}
}
public class Client {
public static void main(String[] args) {
Deployer deployer = new Deployer() {
public void deploy(Deployable deployable) {
gameMain();
}
};
deployer.deploy( getGameModeAspect("easy") );
deployer.deploy( getGameModeAspect("hard") );
deployer.deploy( getGameModeAspect(null) );
}
public static void gameMain() {
EnemyFactory fact = new EnemyFactory();
System.out.println( fact.createMonster() );
System.out.println( fact.createSoldier() );
}
public static Deployable getGameModeAspect(String mode) {
if (mode == null) return null;
if ( mode.equals("easy") ) {
return EasyModeAspect.aspectOf();
}
if ( mode.equals("hard") ) {
return HardModeAspect.aspectOf();
}
return null;
}
}
実行結果:
dp.af.EasyModeAspect$EasyModeMonster@187aeca dp.af.EasyModeAspect$EasyModeSoldier@12dacd1 dp.af.HardModeAspect$HardModeMonster@42719c dp.af.HardModeAspect$HardModeSoldier@119298d dp.af.EnemyFactory$DefaultMonster@1e5e2c3 dp.af.EnemyFactory$DefaultSoldier@1fc4bec
使用例 - その 2
public interface Monster { } // ProductA
public interface Soldier { } // ProductB
public class EnemyFactory { // AbstractFactory
public Monster createMonster() {
return new DefaultMonster();
}
public Soldier createSoldier() {
return new DefaultSoldier();
}
private static class DefaultMonster implements Monster {}
private static class DefaultSoldier implements Soldier {}
}
public interface Deployable {
public static aspect Impl {
private boolean Deployable.isActive;
public void Deployable.activate() {
this.isActive = true;
}
public void Deployable.deactivate() {
this.isActive = false;
}
public boolean Deployable.isActive() {
return isActive;
}
}
}
public interface Deployer {
public void deploy(Deployable deployable);
public static aspect Impl {
void around(Deployable deployable) :
args(deployable) &&
call(void Deployer.deploy(Deployable)) &&
if (deployable != null)
{
deployable.activate();
proceed(deployable);
deployable.deactivate();
}
}
}
public aspect EasyModeAspect implements Deployable {
private pointcut isActive() : if ( EasyModeAspect.aspectOf().isActive() );
private static aspect Impl percflow( execution(void Deployer.deploy(Deployable)) && isActive() ) {
Monster around() : call( Monster EnemyFactory.createMonster() ) {
return new EasyModeMonster();
}
Soldier around() : call( Soldier EnemyFactory.createSoldier() ) {
return new EasyModeSoldier();
}
}
private static class EasyModeMonster implements Monster {}
private static class EasyModeSoldier implements Soldier {}
}
public aspect HardModeAspect implements Deployable {
private pointcut isActive() : if ( HardModeAspect.aspectOf().isActive() );
private static aspect Impl percflow( execution(void Deployer.deploy(Deployable)) && isActive() ) {
Monster around() : call( Monster EnemyFactory.createMonster() ) {
return new HardModeMonster();
}
Soldier around() : call( Soldier EnemyFactory.createSoldier() ) {
return new HardModeSoldier();
}
}
private static class HardModeMonster implements Monster {}
private static class HardModeSoldier implements Soldier {}
}
public aspect GameModeAspectDeployment {
void around(final String mode) : args(mode) && call(void Client.gameMain(String) ) {
Deployer deployer = new Deployer() {
public void deploy(Deployable deployable) {
proceed(mode);
}
};
deployer.deploy( getGameModeAspect(mode) );
}
private Deployable getGameModeAspect(String mode) {
if (mode == null) return null;
if ( mode.equals("easy") ) {
return EasyModeAspect.aspectOf();
}
if ( mode.equals("hard") ) {
return HardModeAspect.aspectOf();
}
return null;
}
}
public class Client {
public static void main(String[] args) {
gameMain("easy");
gameMain("hard");
gameMain(null);
}
public static void gameMain(String mode) {
EnemyFactory fact = new EnemyFactory();
System.out.println( fact.createMonster() );
System.out.println( fact.createSoldier() );
}
}
実行結果:
dp.af.EasyModeAspect$EasyModeMonster@187aeca dp.af.EasyModeAspect$EasyModeSoldier@12dacd1 dp.af.HardModeAspect$HardModeMonster@42719c dp.af.HardModeAspect$HardModeSoldier@119298d dp.af.EnemyFactory$DefaultMonster@1e5e2c3 dp.af.EnemyFactory$DefaultSoldier@1fc4bec
使用例 - その 3 : フレームワーク
public interface Monster { }
public interface Soldier { }
public class EnemyFactory {
public Monster createMonster() {
return new DefaultMonster();
}
public Soldier createSoldier() {
return new DefaultSoldier();
}
private static class DefaultMonster implements Monster {}
private static class DefaultSoldier implements Soldier {}
}
public class Main {
public static void main(String[] args) {
if (args.length == 0) {
gameMain(null);
} else {
gameMain(args[0]);
}
}
public static void gameMain(String mode) {
EnemyFactory fact = new EnemyFactory();
System.out.println( fact.createMonster() );
System.out.println( fact.createSoldier() );
}
}
実行結果:
>java -cp fw.jar;C:\aspectj1.1\lib\aspectjrt.jar; fw.Main fw.EnemyFactory$DefaultMonster@26e431 fw.EnemyFactory$DefaultSoldier@1ddebc3fw-aspect.jar (fw_aspect パッケージ):
public interface Deployable {
public static aspect Impl {
private boolean Deployable.isActive;
public void Deployable.activate() {
this.isActive = true;
}
public void Deployable.deactivate() {
this.isActive = false;
}
public boolean Deployable.isActive() {
return isActive;
}
}
}
public interface Deployer {
public void deploy(Deployable deployable);
public static aspect Impl {
void around(Deployable deployable) :
args(deployable) &&
call(void Deployer.deploy(Deployable)) &&
if (deployable != null)
{
deployable.activate();
proceed(deployable);
deployable.deactivate();
}
}
}
public interface Proceeder {
public void proceed();
}
import fw.Main;
public abstract aspect AbstractGameModeAspectDeployment {
void around(final String mode) : args(mode) && call(void Main.gameMain(String) ) {
Proceeder proceeder = new Proceeder() {
public void proceed() {
proceed(mode);
}
};
createDeployer(proceeder).deploy( getGameModeAspect(mode) );
}
protected abstract Deployable getGameModeAspect(String mode);
protected abstract Deployer createDeployer(Proceeder proceeder);
}
fw-ex.jar (fw_ex パッケージ):
import fw.Monster;
import fw.Soldier;
import fw.EnemyFactory;
import fw_aspect.Deployer;
import fw_aspect.Deployable;
public aspect MyGameModeAspect implements Deployable {
private pointcut isActive() : if ( MyGameModeAspect.aspectOf().isActive() );
private static aspect Impl percflow( execution(void Deployer.deploy(Deployable)) && isActive() ) {
Monster around() : call( Monster EnemyFactory.createMonster() ) {
return new MyGameModeMonster();
}
Soldier around() : call( Soldier EnemyFactory.createSoldier() ) {
return new MyGameModeSoldier();
}
}
private static class MyGameModeMonster implements Monster {}
private static class MyGameModeSoldier implements Soldier {}
}
import fw_aspect.Proceeder;
import fw_aspect.Deployer;
import fw_aspect.Deployable;
import fw_aspect.AbstractGameModeAspectDeployment;
public aspect MyGameModeAspectDeployment extends AbstractGameModeAspectDeployment {
protected Deployer createDeployer(Proceeder proceeder) {
return new DeployerImpl(proceeder);
}
private static class DeployerImpl implements Deployer {
private Proceeder proceeder;
public DeployerImpl(Proceeder proceeder) {
this.proceeder = proceeder;
}
public void deploy(Deployable deployable) {
proceeder.proceed();
}
}
protected Deployable getGameModeAspect(String mode) {
if (mode == null) return null;
if ( mode.equals("my") )
return MyGameModeAspect.aspectOf();
return null;
}
}
実行結果:
>java -cp fw-ex.jar;fw-aspect.jar;C:\aspectj1.1\lib\aspectjrt.jar; fw.Main my fw_ex.MyGameModeAspect$MyGameModeMonster@a0dcd9 fw_ex.MyGameModeAspect$MyGameModeSoldier@15f5897
参考文献とリソース
更新履歴
todo
public MyAbstractFactory {
AbstractFactory;
}