读书人

回调使复建更加简单

发布时间: 2012-12-25 16:18:29 作者: rapoo

回调使重构更加简单
前一段时间在重构公司产品中的一个功能模块,这个模块的大致功能就是对文件或文件夹的一些操作(例如删除,复制,粘贴等等),在这些功能操作之前要进行权限判断,然后在操作的同时还要进行订阅、日志处理、与该操作的一些附加操作等等。

这篇文章主要是将回调,所以我会着重讲回调,对于其他重构的一些细节我就略过不说了。首先看一段重构前的代码。

public class CopyOfOperateAction extends BaseAction {   private void delete() throws Exception { //现在已经改变为,单选和多选统一操作了 int size = id.length; for( int i = 0; i < size; i++ ){   if(StringUtils.isNotBlank(id[i])){     //进行文件与文件夹对象的区别     BaseObj obj=getFileOrDir(id[i],isfile[i]);     new ShareUserOperateAuthority(new       BaseObjOperateAuthority(new BaseOperateAuthority()),this.getHttpServletRequest().getRemoteAddr()).authority(obj, getCurUser(), FileConstants.action_delete);  if(obj instanceof File){//文件的删除File file = (File)obj;Directory oldDir = file.getDirectory();advice(file,oldDir);fileManager.removeFile(file, this.getCurUser());    setFileAction(FileConstants.action_delete, true, file, oldDir, null);  }else{//文件夹的删除Directory directory = (Directory)obj;//定义文件夹所属原文件夹Directory oldDir = directory.getDirectory();callBackAnswer(directory);advice(directory,oldDir);fileManager.removeDire(directory, getCurUser());setFileAction(FileConstants.action_delete, true, directory, oldDir, null);    }}   }      }}


实在不是好排版,就这还是我修改过一次的结果,原来的更掺不忍睹。我大概说一下这段代码的意思,for循环是因为可能是批量操作。Authority就是进行权限的判断,如果没有权限我这里直接就抛出异常,省掉了判断的操作。然后就是根据是文件还是文件做出相应的操作。这里主要关注setFileAction方法。写日志操作。

这个方法是在父类BaseAction中定义的。
public class BaseAction extends ActionSupport implements ServletRequestAware,ServletResponseAware, RequestAware, CookiesAware, ParameterAware,SessionAware, ApplicationAware {    public void setFileAction(String action, boolean success,BaseObj actionObj, Directory sourceFather, Directory target) {List<BaseObj> actionObjs = new ArrayList();actionObjs.add(actionObj);setFileAction(action, success, actionObjs,     sourceFather, target);}}


其实说到这里跟回调还一点关系没有。我们在回过头去看delete方法,其他操作都是类似这段代码,例如for循环、文件还是文件夹的判断等等。于是我就想到了用模板方法模式。

于是我就抽象出一个操作类。
public abstract class AbstractOperateManager implements OperateActionManager {     @Override     public void operate(OperateLogManager operateLogManager) throws Exception { for(int i=0;i<operate.getSize();i++){     if(StringUtils.isNotBlank(operate.getId()[i])){     BaseObj  obj=getFileOrDir(operate.getId()[i],operate.getIsfile()[i]);     operateAuthority(obj,operate.getUser());     if(obj instanceof File){     File f = (File)obj;  fileOperate(f,operate.getUser(),operateLogManager);     }else if(obj instanceof Directory){     Directory dir = (Directory)obj;  dirOperate(dir,operate.getUser(),operateLogManager);}}}}protected abstract void operateAuthority(BaseObj obj,User user);protected abstract void fileOperate(File f,User user,OperateLogManager operateLogManager) throws Exception;protected abstract void dirOperate(Directory dir,User user,OperateLogManager operateLogManager)throws Exception;}


对于上面这段代码也没有什么好解释的,就是使用了模板方法模式,把对文件和文件夹的操作以及权限的判断放在了子类中。

下面就是删除操作的类了,这个类要继承上面那个抽象类。
不好排版,我直接截图算了


这里我们看到注释掉的那段代码了吧,对于日志操作,我们不能直接掉用setFileAction方法,因为这个方法是在BaseAction中定义的。

于是我就想到了回调,首先是定义了一个日志操作的接口,然后定一个类,这个类用来执行调用日志操作的方法。


最后就是我们的客户端,就是我们的action了


在这里就是真正的写日志操作。由于我重构中还有一些其他的操作,例如统一异常捕获操作,所以这个方法只是一个方法,还不是真正的action方法。写到这里,就已经结束了,当然我的重构并没有结束,希望能够给您带来收获,也欢迎大家来拍砖。
好,很好,有见解。

读书人网 >编程

热点推荐