该帖已经被评为精华帖
|
|
---|---|
作者 | 正文 |
发表时间:2005-08-31
我的方法是把DAO的查询方法通过AOP注射成为domain object的static方法,这样domain object的代码中完全看不到对DAO的显式调用,本来这种查询操作就应该是一种static调用,和domain object的instance无关;至于save,则横切domain object的构造函数操作,new一个实例即调用save,update则本来就不用显式调用什么DAO,最后在事务结束后hibernate会flush,感觉比较清爽
|
|
返回顶楼 | |
发表时间:2005-08-31
我也有类似的想法,但是我的方案是使用“Extension Object/Extension Interface”模式,就像Eclipse中的IAdaptable接口扩展机制(可以参见《Contributing to Eclipse》第31章)。这样保证了OOA,并且拥有更松散的耦合,在swing+EJB的架构中能够更灵活。
|
|
返回顶楼 | |
发表时间:2005-08-31
发现我的想法远非original,有人用aspectWerkz也实现过啦:
http://www.digizenstudio.com/blog/2005/06/07/inject-into-domain-objects/ 不过有点简单,他没有用reflection,只能inject指定的object,这样会使配置变得很麻烦 |
|
返回顶楼 | |
发表时间:2005-08-31
drliujia myace 两位,
我对你们的实现方法有点好奇, 能不能讲得具体点? 是不是采用 AOP的introduction实现mixin? |
|
返回顶楼 | |
发表时间:2005-09-01
已经调试通过,LZ相当精彩的构思,如果粒度不是很细的话,性能也不会有什么问题,期待另两位也能详细说明一下做法,大家研究一下,再次谢谢LZ
|
|
返回顶楼 | |
发表时间: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进行注入还有些价值。 |
|
返回顶楼 | |
发表时间: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 |
|
返回顶楼 | |
发表时间:2005-09-01
drliujia 写道 其实本质上都差不多的,aspectj也就是让代码好看点,把我们不愿意看到的对domain object增强的部分给分离到了aspect里面,编译后的class不还是乱成一团?
是的,如果domain object能够有一个共同的基类的话,完全没有必要使用AspectJ。 |
|
返回顶楼 | |
发表时间: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的生命周期管理能够单点维护,有什么理由不这样干呢? |
|
返回顶楼 | |
发表时间: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 |
|
返回顶楼 | |