PS:最近在恶补算法和设计模式,把这些东西mark下来,给大家一个参考。
定义
看看二十三种设计模式中的描述——定义一个操作中的算法的骨架,而将一些步骤延迟到子类中,模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。老实说,刚看到这个定义时,我不是很理解。看完例子之后,我才明白,其实这句话简单地说,就是将具体的实现方法放到子类中,超类提供使用抽象方法的接口。好像这样讲也是很抽象,下面看看实现。
实现
假设你现在有一批水果出售,你可以将它全部批发给别人,这样赚少一点,不过你很聪明,你想到可以将它用不同的礼品盒包装,分档次出售,来获取更多的利润。你将水果分成A、B、C、D档次,每个档次有不同的价格,分别是100,80,60,40。刚好你学过coding,于是你用程序来模拟这个过程,常见的做法就是定义一个转换类进行转换。
public class Pack{
public static int FRUIT_A = 0;
public static int FRUIT_B = 1;
public static int FRUIT_C = 2;
public static int FRUIT_D = 3;
public object packFruit(Fruit mFruit,int type){
if (type == FRUIT_A){
//包装A
return FruitA;
}else if(type == FRUIT_B){
//包装B
return FruitB;
}else if(type == FRUIT_C){
//包装C
return FruitC;
}else if(type == FRUIT_D){
//包装D
return FruitD;
}
}
}
写到这里,你可能觉得还不错,一个方法就完成。但是考虑到可维护性,这就有点坑了。如果你以后再分更多的等级,你就会发现你这个处理方法被if语句填充得满满的,看上去就有点晕。再考虑到你可能不是一个人维护这段代码,任何人都填塞几个类型后,这个类很快就变得很庞大。
用模版方法就可以令它变得很清爽。
public abstract class Pack{
public object packFruit(Fruit mFruit){
return packing(mFruit);
}
protect abstract object packing(Fruit mFruit);
}
然后每有一种等级,就新建一个类去继承Pack,实现packing方法。
public class PackA extends Pack{
@Override
protect object packing(Fruit mFruit){
//包装A
}
}
这样我们就用不断建新的类去代替了之前的不断增加if语句,虽然这样同样会导致整个工程变得庞大,但是维护起来变得更方便。每个人维护自己的类,不会干扰别人的代码。
总结
从上面例子可以看到,在模版方法中,子类负责具体的实现,超类只需提供执行抽象方法的对外方法就可以了。这个模式和我们平时做ppt类似,超类相当于ppt的模版,子类就是我们自己的内容。