稳固而知新 Template Method,Strategy

来源:互联网 发布:统计建模与r软件 数据 编辑:程序博客网 时间:2024/05/16 06:03
TEMPLATE METHOD
       该模式将通用的算法放在基类中,通过继承在不同的具体类中实现该通用算法,此模式的代价是派生类必定与基类绑定在一起。
在ipass项目中,有从文件导入的功能。首先打开文件,按照csv格式逐行处理,对于不合格的过滤掉,合格的保存起来,最后在界面上显示,再由用户决定是否执行导入功能。
public abstract class BaseImporter {
       List list = new ArrayList();
       public void openFile(String filename) throws Exception {
              BufferedReader br = new BufferedReader(new InputStreamReader(
                            new FileInputStream(filename)));
              String newline;
              while ((newline = br.readLine()) != null) {
                     Object o = valid(newline);
                     if (o != null) {
                            list.add(o);
                     }
              }
       }
       public Object[] getImportInfo(){
       return list.toArray();
}
       public abstract Object valid(String l   ine);
}
public class UserImporter extends BaseImporter {
       public Object valid(String line) {
              String[] info=CVSParser.parse(line);
              //invalid
              if(info.length!=2) {
                     return null;
              }
              return new UserImportInfo(info);
       }
}
 
每个导入页面生成自己需要的Importer,调用openFile方法,即可获取到合适的内容。
 
STRATEGY
该模式使用委托来实现算法的重用。将通用的算法放在具体类中,通用算法要调用的抽象方法定义在接口中,派生类实现此接口来实现具体的业务。
下图中,实现的是批量导入的功能,上例是导入到页面显示,本例为导入到后台。由于导入的元素个数太多,一次全导入无法实现,一次一个又太浪费资源,现在计划是一次导入300个。批量导入的算法在BatchImporter这个具体类中实现,它调用ImportHandler的importOperation()抽象方法实现具体的导入业务。UserImportPage和GroupImportPage分别是导入用户的页面和导入组的页面,它们都实现了ImportHandler接口,在importOperation方法中实现自己的导入操作的业务逻辑。同时它们自身也保留BatchImporter实例,当特定的事件激活时(如按下导入按钮),执行BatchImporter.doImport()进行导入操作。BatchImporter要做的具体工作都委托给ImportHandler的派生类去做。

public class BatchImporter {
       int sendTimes;//how many times needs
       int total; //total number of objects to import
       int skip=300; //import 300 objects each time
       ImportHandler hander;
       public BatchImporter(int total, ImportHandler handler) {
              this.hander = handler;
              this.total = total;
              sendTimes = total / skip;
              if (total % skip > 0) {
                     sendTimes++;
              }
       }
       public void doImport() {
              for (int i = 0; i < sendTimes; i++) {
                     //import sendNumber objects this time
                     int sendNumber = skip;
                     if (i == sendTimes - 1) {
                            skip = total - i * skip;
                     }
                     //import from the position skip, and import sendNumber objects
                     hander.importOperation(i * skip, sendNumber);
              }
       }
}
       Strategy允许每个具体实现都可以被不同的通用算法操纵,比Template Method具有更大的自由度,它减小了通用算法和具体细节之间的耦合。但是比继承要付出更多的运行时间和数据空间的开销。