设计模式--------模版模式
介绍模版模式的四大问题
- 现在的写法有什么问题吗?
- 为什么要用模版模式?
- 什么是模版模式?
- 模版模式有什么好处?
使用一个例子进行问题的说明
- 假如要制作各种形状的面包,制作面包有很多的步骤
StartBread
public class StarBread {
public void water() {
System.out.println("准备水");
}
public void flour() {
System.out.println("准备面粉");
}
public void rub() {
System.out.println("揉成面团");
}
public void shape() {
System.out.println("揉成星形");
}
public void bake() {
System.out.println("烤面包");
}
}
HeartBread
public class HeartBread {
public void water() {
System.out.println("准备水");
}
public void flour() {
System.out.println("准备面粉");
}
public void rub() {
System.out.println("揉成面团");
}
public void shape() {
System.out.println("揉成心形");
}
public void bake() {
System.out.println("烤面包");
}
}
Main
public class Main {
public static void main(String[] args) {
StarBread bread = new StarBread();
bread.water();
bread.flour();
bread.rub();
bread.shape();
bread.bake();
HeartBread bread = new HeartBread();
bread.water();
bread.flour();
bread.rub();
bread.shape();
bread.bake();
}
}
有什么问题?
- 有很多重复的部分没有进行封装
进一步修改
- 使用一个抽象类将公共部分封装
Bread
public abstract class Bread {
public void water() {
System.out.println("准备水");
}
public void flour() {
System.out.println("准备面粉");
}
public void rub() {
System.out.println("揉成面团");
}
public abstract void shape();
public void bake() {
System.out.println("烤面包");
}
}
StarBread
public class StarBread extends Bread {
@Override
public void shape() {
System.out.println("揉成星形");
}
}
HeartBread
public class HeartBread extends Bread {
@Override
public void shape() {
System.out.println("揉成心形");
}
}
Main
public static void main(String[] args) {
Bread bread = new StarBread();
bread.water();
bread.flour();
bread.rub();
bread.shape();
bread.bake();
Bread bread = new HeartBread();
bread.water();
bread.flour();
bread.rub();
bread.shape();
bread.bake();
}
}
有什么问题?
- 制作的过程一样,重复代码
什么是模版模式?
- 在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中,模版方法使子类可以在不改变算法结构的情况下,重新定义算法的某些步骤
使用模版模式重构代码
Bread
public abstract class Bread {
public final void make() {
water();
flour();
rub();
shape();
bake();
}
public void water() {
System.out.println("准备水");
}
public void flour() {
System.out.println("准备面粉");
}
public void rub() {
System.out.println("揉成面团");
}
public abstract void shape();
public void bake() {
System.out.println("烤面包");
}
}
Main
public class Main {
public static void main(String[] args) {
Bread heartBread = new HeartBread();
Bread starBread = new StarBread();
heartBread.make();
starBread.make();
}
}
模版模式有什么好处?
- 减少重复代码
- 在不改变结构的情况下,可以调整
模版模式中的钩子
- 钩子就是通过一个方法来进行微调
Bread
public abstract class Bread {
public final void make() {
water();
flour();
if (moreWater()) {
water();
}
rub();
shape();
bake();
}
public void water() {
System.out.println("准备水");
}
public void flour() {
System.out.println("准备面粉");
}
public void rub() {
System.out.println("揉成面团");
}
public abstract void shape();
public void bake() {
System.out.println("烤面包");
}
public boolean moreWater() {
return false;
}
}
StarBread
public class StarBread extends Bread {
@Override
public void shape() {
System.out.println("揉成星形");
}
@Override
public boolean moreWater() {
return true;
}
}
设计原则
- 好莱坞原则:低层组件不要调用高层组件,等高层组件调用低层组件
END
不慕招式,勤修内功