在代码结构上:
1 一个抽象类:不是接口 因为里面有个实现方法,多个抽象方法
2 这个抽象类里有一个主方法:cook(),
3 主方法里面包含几个共性的固定的抽象方法(getRice(),fry(),getOut()),并且顺序一定的。
4 用户访问类DanChaoFanCooker里面依赖关联这个抽象类。
这边引用:https://www.cnblogs.com/08shiyan/p/4989203.html 和策略模式的比较
模板方法的意图:定义一个算法流程,将一些特定步骤的具体实现、延迟到子类。使得可以在不改变算法流程的情况下,通过不同的子类、来实现“定制”流程中的特定的步骤。
策略模式的意图:使不同的算法可以被相互替换,而不影响客户端的使用。
在意图上看,模板方法更加强调:
1)定义一条线(算法流程),线上的多个点是可以变化的(具体实现在子类中完成),线上的多个点一定是会被执行的,并且一定是按照特定流程被执行的。
2)算法流程只有唯一的入口,对于点的访问是受限的【通常用受保护的虚函数来定义可变点】。
策略模式更注重于: 一个“策略”是一个整体的(完整的)算法,算法是可以被整体替换的。而模板方法只能被替换其中的特定点,算法流程是固定不可变的。
在这样的细节上看来,模板方法 和 一组策略模式 是不可以划等号的。
谢霆锋的风味,有一期是去扬州比赛蛋炒饭。米-不同的组米可以不同,炒,怎么炒用什么锅不关心,
炒好了用什么盛饭不关心,用户是只要选择那组然后就等着吃蛋炒饭。
下面代码代码实现:
/**
* 里面方法的定义 有参 无参无限制, 看实际业务需求。
*
* @author flynn
* @datetime 2018-08-20 11:15
*/
public abstract class DanChaoFan {
String rice;
String fire;
//获取大米。。。其他辅材
abstract String getRice();
//炒
abstract void fry();
//盛出来
abstract FriedRice getOut();
// 蛋炒饭的工序 一般固定下来就不变了,否则各个子类都要修改
public FriedRice cook() {
getRice();
fry();
return getOut();
}
}
用户用户访问类即用户选择的对象。
/**
* 炒饭师傅
*/
public class DanChaoFanCooker {
//依赖注入蛋炒饭对象
private DanChaoFan danChaoFan;
public DanChaoFanCooker(DanChaoFan danChaoFan) {
this.danChaoFan = danChaoFan;
}
public FriedRice getDanChaoFan() {
return danChaoFan.cook();
}
//客户换个口味的蛋炒饭
void changeDanChaoFan(DanChaoFan danChaoFan) {
this.danChaoFan = danChaoFan;
}
}
zile谢大厨的蛋炒饭-子类是实现具体的业务
public class XieCookerDanChaoFan extends DanChaoFan {
@Override
String getRice() {
rice = "谢大厨用的五常大米";
return rice;
}
@Override
void fry() {
fire = "谢大厨用的山木的火,大铁锹还有加入了香肠、美女帮忙...";
}
@Override
FriedRice getOut() {
FriedRice friedRice = new FriedRice();
friedRice.setResult(fire + rice);
return friedRice;
}
}
子类-扬州大厨的蛋炒饭
public class YangCookerDanChaoFan extends DanChaoFan {
@Override
String getRice() {
rice = "扬州大厨用的自己种的大米";
return rice;
}
@Override
void fry() {
fire = "扬州大厨用的天然气,大铁锹还有加入了梅干菜...";
}
@Override
FriedRice getOut() {
return new FriedRice(fire + rice);
}
}
测试:顾客选择不同组的厨师选择不同的蛋炒饭来吃
public class MainTest {
public static void main(String[] args) {
DanChaoFanCooker cooker = new DanChaoFanCooker(new YangCookerDanChaoFan());
// DanChaoFanCooker xieCooker = new DanChaoFanCooker(new XieCookerDanChaoFan());
FriedRice friedRice = cooker.getDanChaoFan();
System.out.println("先尝尝扬州炒饭之神的蛋炒饭:" + friedRice);
cooker.changeDanChaoFan(new XieCookerDanChaoFan());
friedRice = cooker.getDanChaoFan();
System.out.println("换个口味,尝尝谢大厨的蛋炒饭:" + friedRice);
}
}
结果:
案例。当时做app的首页,各个楼层的实现就是模板方法。(每个楼层里面的布局几乎都不一样,主要是嵌套太深,简单地使用listview或者recycleview性能很不好。当然后面才优化)
模式缺点
需要为每一个基本方法的不同实现提供一个子类,如果父类中可变的基本方法太多,将会导致类的个数增加,系统更加庞大,设计也更加抽象,此时,可结合桥接模式来进行设计