论坛首页 Java企业应用论坛

Domain injection with AOP

浏览 31807 次
该帖已经被评为精华帖
作者 正文
   发表时间:2005-08-31  
我的方法是把DAO的查询方法通过AOP注射成为domain object的static方法,这样domain object的代码中完全看不到对DAO的显式调用,本来这种查询操作就应该是一种static调用,和domain object的instance无关;至于save,则横切domain object的构造函数操作,new一个实例即调用save,update则本来就不用显式调用什么DAO,最后在事务结束后hibernate会flush,感觉比较清爽
0 请登录后投票
   发表时间:2005-08-31  
我也有类似的想法,但是我的方案是使用“Extension Object/Extension Interface”模式,就像Eclipse中的IAdaptable接口扩展机制(可以参见《Contributing to Eclipse》第31章)。这样保证了OOA,并且拥有更松散的耦合,在swing+EJB的架构中能够更灵活。
0 请登录后投票
   发表时间:2005-08-31  
发现我的想法远非original,有人用aspectWerkz也实现过啦:
http://www.digizenstudio.com/blog/2005/06/07/inject-into-domain-objects/
不过有点简单,他没有用reflection,只能inject指定的object,这样会使配置变得很麻烦
0 请登录后投票
   发表时间:2005-08-31  
drliujia myace 两位,
我对你们的实现方法有点好奇, 能不能讲得具体点?
是不是采用 AOP的introduction实现mixin?
0 请登录后投票
   发表时间:2005-09-01  
已经调试通过,LZ相当精彩的构思,如果粒度不是很细的话,性能也不会有什么问题,期待另两位也能详细说明一下做法,大家研究一下,再次谢谢LZ
0 请登录后投票
   发表时间:2005-09-01  
xiecc 写道
drliujia myace 两位,
我对你们的实现方法有点好奇, 能不能讲得具体点?
是不是采用 AOP的introduction实现mixin?

“Extension Object/Extension Interface”的实现不在意是否使用AOP。
我们的目的是能够直接使用向customer.save()方法,但是这有引入
对DAO接口或实现的依赖。在xiecc的“Domain injection”方法中,实际上还是对DAO接口有依赖。最终的方法调用向这样“customer.getDAO().save()”。

使用“EO/EI”模式,可以摆脱对DAO接口的依赖,最终的调用方法如“((DA
O)customer.getAdapter(DAO.class)).save()”,如果使用JDK5的泛型的画就更好了,可以向这样调用“customer.getAdapter(DAO.class).save()”。

“EO/EI”模式具体有三个类:

/**
 * 可适配对象接口
 */
public interface IAdaptable {
	/**
	 * 返回一个适配器
	 */
	<T> T getAdapter(Class<T> adapter);;
}

/**
 * 适配器工厂
 */
public interface IAdapterFactory {
	/**
	 * 得到一个对象的适配器接口
	 */
	Object getAdapter(Object adaptableObject, Class adapterType);;

	/**
	 * 可以适配类型的列表
	 */
	Class[] getAdapterList();;
}
/**
 * 适配器管理器,注册适配器工厂,生成适配器。
 */
public interface IAdapterManager {

	Object getAdapter(Object adaptable, Class adapterType);;

	void registerAdapters(IAdapterFactory factory, Class adaptable);;

	void unregisterAdapters(IAdapterFactory factory);;

	void unregisterAdapters(IAdapterFactory factory, Class adaptable);;
}


Customer 实现 IAdaptable 接口 并在调用getAdapter方法时,委派到单例的AdapterManager 上,AdapterManager 查找注册的Customer类的DAO适配器工厂,并通过工厂创建DAO适配器,并返回结果。

这种模式需要一个域模型基类,在Eclipse中是PlatformObject,它实现了IAdaptable 接口。在这里我们可以使用AOP进行注入,或许使用AspectJ的AOP进行注入还有些价值。
0 请登录后投票
   发表时间:2005-09-01  
其实本质上都差不多的,aspectj也就是让代码好看点,把我们不愿意看到的对domain object增强的部分给分离到了aspect里面,编译后的class不还是乱成一团?
public aspect DomainObjectPersistenceAspect {	
	private PersistenceDAO ServiceFactory.persistenceDAO;
	
	public void ServiceFactory.setPersistenceDAO(PersistenceDAO dao); {
		this.persistenceDAO = dao;
	}

	public PersistenceDAO ServiceFactory.getPersistenceDAO();{
		return persistenceDAO;
	}
	pointcut domainObjectDefaultConstructor(); : call((AbstractDomainObject+);.new(..););;
		
	after(); returning(AbstractDomainObject instance); : domainObjectDefaultConstructor();{
		instance.persist();;
	}		
	
	public void AbstractDomainObject.persist();{
		ServiceFactory.getFactoryInstance();.getPersistenceDAO();.persist(this);;
	}
	
	public void AbstractDomainObject.delete();{
		ServiceFactory.getFactoryInstance();.getPersistenceDAO();.delete(this);;
	}
}

domain object都需要继承AbstractDomainObject
0 请登录后投票
   发表时间:2005-09-01  
drliujia 写道
其实本质上都差不多的,aspectj也就是让代码好看点,把我们不愿意看到的对domain object增强的部分给分离到了aspect里面,编译后的class不还是乱成一团?

是的,如果domain object能够有一个共同的基类的话,完全没有必要使用AspectJ。
0 请登录后投票
   发表时间:2005-09-01  
xiecc 写道

2、 定义pointcut
定义Domain Object的pointcut是比较难的事,因为我们无法控制domain object的生命周期,因此我们无法将pointcut定义在对象创建的时候。domain object除了Object外没有共同的父类,每个domain object又没有共同的方法,确实是一件头痛的事。

不太明白,为什么domain object不能有共同的父类?tell me why.
假如domain object因为都继承了父类DomainObject,而使得实现domain object的生命周期管理能够单点维护,有什么理由不这样干呢?
0 请登录后投票
   发表时间:2005-09-01  
myace 写道

“Extension Object/Extension Interface”的实现不在意是否使用AOP。
我们的目的是能够直接使用向customer.save()方法,但是这有引入
对DAO接口或实现的依赖。在xiecc的“Domain injection”方法中,实际上还是对DAO接口有依赖。最终的方法调用向这样“customer.getDAO().save()”。

drliujia 写道
其实本质上都差不多的,aspectj也就是让代码好看点,把我们不愿意看到的对domain object增强的部分给分离到了aspect里面,编译后的class不还是乱成一团?

如果你们知道UnitOfWork用法的话,就再也不想多看一眼DAO了。

下面的一个草案,虽说现在可以改进的更好,但思想还是可以使用的。
http://forum.iteye.com/viewtopic.php?t=13594
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics