锁定老帖子 主题:求一种合适的设计模式解决这个问题
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2007-03-12
public String onDelete(Object obj) { // TODO Auto-generated method stub String result="JOBTITLE_DELETE_SUCC"; log.info("**********deleting*************"); try { Object vo=clientDataMap.get("DELETE_OBJECT"); if(!BACKUP.equals("1")) { SpringDao.delete(vo); } else { SpringBakDao.delete(vo, new String[]{user,actionType,projectUtils.getVOId(vo)}); } } catch(Exception ex) { ex.printStackTrace(); result="JOBTITLE_DELETE_FAIL"; } return result; } public String onInsert(Object obj) { String result=module+"_INSERT_SUCC";; try { Object vo=clientDataMap.get("VO"); if(!BACKUP.equals("1")) SpringDao.insert(vo); else SpringBakDao.insert(vo, new String[]{"Terry",actionType}); } catch(Exception ex) { ex.printStackTrace(); result=module+"_INSERT_FAIL"; } log.info("GeneralPersistBO...INSERT()...result:"+result); return result; } 这是一个进行持久化事务的类,这里有两个DAO分属于不同类型,SpringDao只往一个数据库中存数据,SpringBakDao会往备份数据库中存数据,BACKUP常量控制是哪种持久化方式,问题是,每次crud操作时, 都对BACKUP判断一次, 实在是有冗余代码,不是一个良好的设计,我想到几个方案: 1 使 SpringDao和SpringBakDao都实现一个IDAO接口,但问题是,这两个DAO的crud方法,都是需传入不同的参数个数的,如果想统一起来,可以写一个Adapter,然后实现所有接口方法,再每个Dao继承这个Adapter并重载相关的方法,但是,由于要传入的参数个数不同, 始终要判断BACKUP的值 2 用proxy或interceptor, 都存在一个难点,不同DAO的相同的crud方法的参数都不一样的,就算同一个DAO类型的crud四个方法的参数个数也不一致,例如 SpringBakDao.delete(vo,new String[]{String id}),SpringBak.insert(vo,new String[]{String id,String newId}); 如果我用proxy模式,岂不是要传入最多的参数个数入这个proxy类里面,才能应付所有情况? 两种方案都不是理想的,所以想听听大家的意见,有什么更好的模式可以解决这个问题.谢谢 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2007-03-12
这种场景比较适合用AOP.
|
|
返回顶楼 | |
发表时间:2007-03-12
AOP和proxy是同样的道理, 不方便的地方,我上面提过了.
|
|
返回顶楼 | |
发表时间:2007-03-12
引用 2 用proxy或interceptor, 都存在一个难点,不同DAO的相同的crud方法的参数都不一样的,就算同一个DAO类型的crud四个方法的参数个数也不一致,例如
SpringBakDao.delete(vo,new String[]{String id}),SpringBak.insert(vo,new String[]{String id,String newId}); 如果我用proxy模式,岂不是要传入最多的参数个数入这个proxy类里面,才能应付所有情况? 诚然,你自己已经知道问题的所在了!这个是个不可调和的问题! 你不封装参数提供统一接口就不能利用Aop去解决问题! 其实这就是个取舍! 不清楚你的这些操作到底有多少,但是理想设计上考虑应该包起来。不过到底有没有这个必要你自己要酌情考虑 但是写Adapter到这个地步是不是太晚了,不能再在Dao上做文章了,只能动Proxy! |
|
返回顶楼 | |
发表时间:2007-03-12
springdao extends basedao
onDelete(do your work) oninsert(do your work) datasource:real system datasource backdao extends basedao onDelete(do your work) oninsert(do your work) datasource:baackup system datasource daoHelper: getDao() due to your system; client: daoHelper.getDao.oninsert(...); |
|
返回顶楼 | |
发表时间:2007-03-12
两个方法的重复代码结构都一样 如下
if(!BACKUP.equals("1")) { SpringDao.delete(vo); } else { SpringBakDao.delete(vo, new String[]{user,actionType,projectUtils.getVOId(vo)}); } 很明显这是一种多态。 解决方法: interface Dao { onDelete(...); onInsert(...); } SpringDao implements Dao SpringBakDao implements Dao 在Dao的上层去确定要调用SpringDao 或 SpringBakDao 这个问题是典型的用多态代替状态码的重构 |
|
返回顶楼 | |
发表时间:2007-03-12
多态可以解决它的问题吗?好像只会增加复杂度!
接口不定啊!如果用多态,要写很多child! |
|
返回顶楼 | |
发表时间:2007-03-12
使用Template Method java 代码
|
|
返回顶楼 | |
发表时间:2007-03-12
badqiu 写道: 使用Template Method java 代码
if(!BACKUP.equals("1")) 是不是很白痴 而且如果需求有改变,需要加一个else if ,难道要修改这10个方法吗? |
|
返回顶楼 | |
发表时间:2007-03-12
Class
DeleteData // data to del BakDeleteData //extends DeleteData to del as bak data DataOperator //to operate data fuction/action DeleteImpInterface //interface to perform delete action DeleteBak //implements DeleteImpInterface to del bakeup database's data DeleteNormally //implements DeleteImpInterface to del normal database's data Test to test the function; public class DeleteData { protected Object vo; public DeleteData(Object obj) { this.vo = obj; } public Object getVo() { return vo; } public void setVo(Object vo) { this.vo = vo; } } { private String[] extParams; public BakDeleteData(Object obj){ super(obj); } public void setExtParams(String[] extParams) { this.extParams = extParams; } public String[] getExtParams() { return extParams; } } public class DataOperator { private static Logger log = Logger.getLogger("data/operator"); private DeleteImpInterface deletor; public DataOperator( ) { } public DataOperator(DeleteImpInterface deletor) { this.deletor = deletor; } public void setDeletor(DeleteImpInterface deletor) { this.deletor = deletor; } public DeleteImpInterface getDeletor() { return deletor; } public String onDelete(DeleteData obj) { // TODO Auto-generated method stub String result = "JOBTITLE_DELETE_SUCC"; log.info("**********deleting*************"); try { // Object vo=clientDataMap.get("DELETE_OBJECT"); // deldata=new DeleteData(obj); deletor.delete(obj); // SpringBakDao.delete(vo, new String[]{user,actionType,projectUtils.getVOId(vo)}); } catch (Exception ex) { ex.printStackTrace(); result = "JOBTITLE_DELETE_FAIL"; } return result; } } public interface DeleteImpInterface { public void delete(DeleteData d) throws Exception; } public class DeleteBak implements DeleteImpInterface { public void delete(BakDeleteData d) { SpringDao.delete(d.getVo(), d.getExtParams());//use SpringDao to imp,you must define this first. } public class DeleteNormally implements DeleteImpInterface { public void delete(DeleteData d) { SpringDao.delete(d.getVo());());//use SpringDao to imp,you must define this first. } } } public class Test { public static void main(String[] args) { //get po Object vo1 = new Object();//or get po by vo; use SpringDao.getPo(vo) or someone else; Object vo2 = new Object();//or get po by vo; use SpringDao.getPo(vo) or someone else; //get deleted data DeleteData delData1 = new DeleteData(vo1); BakDeleteData delData2 = new BakDeleteData(vo2); delData2.setExtParams(new String[]{"sss", "ddddd"}); DataOperator operator = new DataOperator(); //del normal database's data operator.setDeletor(new DeleteNormally()); operator.onDelete(delData1); //del bakeup database's data operator.setDeletor(new DeleteBak()); operator.onDelete(delData2); //http://www.iteye.com/topic/59239 } } of course it is not perfect one for our purpose, but yoou know ,there is no perfect one but the best! try for it,perhaps it is not very well!just try it. firstly I just want to say that don't use too much params to pass to methods,encapsulate the for the best;we can modify them easily when params increased or decreased secondly, use strategy or bridge.but you must know that,strategy is not the perfect one.maybe someone else thirdly, use polymorphism to avoid if/else, that is an effective way. have fun! |
|
返回顶楼 | |