前言
什么是抽象工厂模式?
抽象工厂模式相比于工厂方法模式是为了提高产品分级的扩展性。根据前面的学习,知道在简单工厂模式和工厂方法模式是为了创建对象而建立,这两个模式容易添加产品,但是不容易实现产品分级。比如Car这个产品,我们很容易扩展BMWCar,BenzCar,HavalCar。但是组装一个车,左前门和右前门是不一样的,当需要进行细化产品的时候,就引出了抽象工厂模式。
一、模板方法模式
什么是模板方法模式?
Define the skeleton of an algorithm in an operation,deferring some steps to subclasses.Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm’s structure.
翻译:
定义一个操作中的算法框架,延迟到子类实现。模板方法可以让子类在不改变算法框架的情况下重新实现某些步骤。
二、代码示例
1.模板方法模式示例
假如现在有一个悍马的模型,需要使车模能跑动,能停止,能够鸣笛,引擎轰鸣等流程方法。public abstract class HummerModel {
/**
* 汽车启动
*/
public abstract void start();
/**
* 汽车停止
*/
public abstract void stop();
/**
* 鸣笛
*/
public abstract void alarm();
/**
* 引擎轰鸣
*/
public abstract void engineBoom();
/**
* 模板方法,汽车跑,鸣笛,引擎轰鸣,汽车停止
*/
public void run(){
this.start();
this.alarm();
this.engineBoom();
this.stop();
}
}
上面的run()方法就是模板方法。
//汽车模型1
public class HummerH1Model extends HummerModel {
@Override
public void start() {
System.out.println("汽车启动");
}
@Override
public void stop() {
System.out.println("汽车到目的地停止");
}
@Override
public void alarm() {
System.out.println("遇到障碍,鸣笛,滴滴滴");
}
@Override
public void engineBoom() {
System.out.println("引擎轰鸣法拉利");
}
}
//汽车模型2
public class HummerH2Model extends HummerModel {
@Override
public void start() {
System.out.println("汽车开始h2");
}
@Override
public void stop() {
System.out.println("汽车停止h2");
}
@Override
public void alarm() {
System.out.println("遇到障碍,鸣笛,叭叭叭");
}
@Override
public void engineBoom() {
System.out.println("引擎轰鸣,迈凯伦");
}
}
//场景类
public class Client {
public static void main(String[] args) {
HummerModel h1 = new HummerH1Model();
HummerModel h2 = new HummerH2Model();
h1.run();
h2.run();
}
}
从代码示例,可以看到,模板方法模式很简单,就是定义了一个模板方法,调用其他方法来实现业务逻辑。
2.通用代码
模板方法模式的结构
1.基本方法,实现该操作的单独逻辑单元,叫基本方法,是一个抽象方法,这些方法都放在子类中实现
2.模板方法:调用其他基本方法的方法,模板方法事实上就是一个框架,定义调用的顺序,完成的是固定的逻辑
模板方法模式的注意事项:
1.模板方法一般为了防止恶意串改,会使用final定义
2.基本方法一般使用protected定义
public abstract class HummerModel2 {
/**
* 汽车启动
*/
protected abstract void start();
/**
* 汽车停止
*/
protected abstract void stop();
/**
* 鸣笛
*/
protected abstract void alarm();
/**
* 引擎轰鸣
*/
protected abstract void engineBoom();
/**
* 模板方法,汽车跑,鸣笛,引擎轰鸣,汽车停止
*/
public final void run(){
this.start();
if(isAlarm()){
this.alarm();
}
this.engineBoom();
this.stop();
}
protected boolean isAlarm(){
return true;
}
}
可以设置一个"钩子方法",来控制是否调用某个基本方法。也就是说在实现模板方法的逻辑的时候,这样是模板方法模式更加灵活。
public class HummerH1Model extends HummerModel2 {
private boolean isAlarm = true;
@Override
public void start() {
System.out.println("汽车启动");
}
@Override
public void stop() {
System.out.println("汽车到目的地停止");
}
@Override
public void alarm() {
System.out.println("遇到障碍,鸣笛,滴滴滴");
}
@Override
public void engineBoom() {
System.out.println("引擎轰鸣法拉利");
}
@Override
protected boolean isAlarm() {
return this.isAlarm;
}
/**
* 喇叭要不要响,由客户决定
* @param isAlarm
*/
public void setAlarm(boolean isAlarm) {
this.isAlarm = isAlarm;
}
}
public class HummerH2Model extends HummerModel2 {
@Override
public void start() {
System.out.println("汽车开始h2");
}
@Override
public void stop() {
System.out.println("汽车停止h2");
}
@Override
public void alarm() {
System.out.println("遇到障碍,鸣笛,叭叭叭");
}
@Override
public void engineBoom() {
System.out.println("引擎轰鸣,迈凯伦");
}
@Override
protected boolean isAlarm() {
return false;
}
}