1 简介
- 模板模式即程序按照固定模式(流程)运行,倒叙的方式设计程序;
- 将完整的流程拆分为独立的模块,多个模块组合出完整的功能;
- 模块化编程;
- 模板模式实现方式有两种:
(1)抽象类;
(2)接口类; - 其中,抽象类是严格的1:1重写方法,设计方式刻板,不易扩展;
- 接口类使用default关键字可以重写部分方法,设计方式灵活,适配多种场景,易扩展;
- 推荐使用面向接口的方式设计模板;
- 以洗衣机工作过程讲解模板模式。
2 洗衣机工作模板(流程)
洗衣机运行模板如图2.1所示:
3 抽象类Abstract实现模板模式
3.1 抽象类模板
package designpattern.template;
/**
* @description 模板模式:洗衣机
* @author xindaqi
* @since 2021-02-12 14:54:45
*/
public abstract class BaseWashingMachine {
/**
* description: 开机
* @since 2021-02-12 15:06:26
* @param
* @return
*/
abstract void powerOn();
/**
* description: 运行
* @since 2021-02-12 15:06:42
* @param
* @return
*/
abstract void work();
/**
* description: 关机
* @since 2021-02-12 15:06:57
* @param
* @return
*/
abstract void powerOff();
/**
* description: 模板
* @since 2021-02-12 15:07:16
* @param
* @return
*/
public void operation() {
powerOn();
work();
powerOff();
}
}
3.2 模板1-标准洗涤
package designpattern.template;
import java.util.logging.Logger;
/**
* @description 模板模式:标准洗涤
* @author xindaqi
* @since 2021-02-12 15:09:42
*/
public class StandardsWashing extends BaseWashingMachine {
private static final Logger logger = Logger.getLogger("StandardsWashing");
@Override
void powerOn() {
logger.info("洗衣机:开机");
}
@Override
void work() {
logger.info("洗衣机:标准洗涤");
}
@Override
void powerOff() {
logger.info("洗衣机:关机");
}
}
3.3 模板2-脱水
package designpattern.template;
import java.util.logging.Logger;
/**
* @description 模板模式:脱水
* @author xindaqi
* @since 2021-02-12 15:14:29
*/
public class Dehydration extends BaseWashingMachine {
private static final Logger logger = Logger.getLogger("Dehydration");
@Override
void powerOn() {
logger.info("洗衣机:开机");
}
@Override
void work() {
logger.info("洗衣机:脱水");
}
@Override
void powerOff() {
logger.info("洗衣机:关机");
}
}
3.4 测试
package designpattern.template;
import java.util.logging.Logger;
/**
* @description 模板模式:测试样例
* @author xindaqi
* @since 2021-02-12 15:17:59
*/
public class TemplateTest {
private static final Logger logger = Logger.getLogger("TemplateTest");
public static void main(String[] args) {
BaseWashingMachine washingMachine = new StandardsWashing();
washingMachine.operation();
logger.info("==============");
washingMachine = new Dehydration();
washingMachine.operation();
}
}
4 接口Interface实现模板模式
4.1 接口模板
package designpattern.template.interface_use;
/**
* 洗衣机接口模板.
*
* @author xindaqi
* @date 2021-08-11 10:45
*/
public interface IWashingMachine {
/**
* 开机.
*
* @param useFlag 使用标识:true:使用,false:不使用
* @return 开机标识:true:开机,false:关机
*/
boolean powerOn(boolean useFlag);
/**
* 运行.
*
* @param powerOnFlag 开机标识:true:开机,false:关机
* @return 运行标识:true:正常运行,false:故障
*/
boolean work(boolean powerOnFlag);
/**
* 关机.
*
* @param workFlag 运行标识,true:正常运行,false:故障
* @return 关机标识,true:关机,false:开机
*/
boolean powerOff(boolean workFlag);
/**
* 洗衣机完整工作过程.
*
* @param useFlag 使用标识
* @return 关机标识:true:关机,false:开机
*/
default boolean operation(boolean useFlag) {
boolean powerOnFlag = powerOn(useFlag);
boolean workFlag = work(powerOnFlag);
return powerOff(workFlag);
}
}
4.2 模板1-标准洗涤
package designpattern.template.interface_use.impl;
import common.constant.BooleanConstant;
import designpattern.template.interface_use.IWashingMachine;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
/**
* 标准洗涤.
*
* @author xindaqi
* @date 2021-08-11 10:47
*/
public class StandardWashingImpl implements IWashingMachine {
private static final Logger logger = LogManager.getLogger(StandardWashingImpl.class);
@Override
public boolean powerOn(boolean useFlag) {
logger.info("洗衣机:开机");
if(useFlag) {
return BooleanConstant.TRUE;
}
return BooleanConstant.FALSE;
}
@Override
public boolean work(boolean powerOnFlag) {
logger.info("洗衣机:标准洗涤");
if(powerOnFlag) {
return BooleanConstant.TRUE;
}
return BooleanConstant.FALSE;
}
@Override
public boolean powerOff(boolean workFlag) {
logger.info("洗衣机:关机");
if(workFlag) {
return BooleanConstant.TRUE;
}
return BooleanConstant.FALSE;
}
}
4.3 测试
package functiontest;
import common.constant.BooleanConstant;
import designpattern.template.interface_use.IWashingMachine;
import designpattern.template.interface_use.impl.StandardWashingImpl;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Interface 模板测试.
*
* @author xindaqi
* @date 2021-08-11 10:50
*/
public class InterfaceTemplateTest {
private static final Logger logger = LoggerFactory.getLogger(InterfaceTemplateTest.class);
@Test
public void standardWashing() {
IWashingMachine standardWashing = new StandardWashingImpl();
boolean useFlag = standardWashing.operation(BooleanConstant.TRUE);
logger.info("Standard washing:{}", useFlag);
boolean noUseFlag = standardWashing.operation(BooleanConstant.FALSE);
logger.info("Standard washing:{}", noUseFlag);
}
}
- 运行结果
14:24:03.703 [main] INFO designpattern.template.interface_use.impl.StandardWashingImpl - 洗衣机:开机
14:24:03.705 [main] INFO designpattern.template.interface_use.impl.StandardWashingImpl - 洗衣机:标准洗涤
14:24:03.706 [main] INFO designpattern.template.interface_use.impl.StandardWashingImpl - 洗衣机:关机
14:24:03.708 [main] INFO functiontest.InterfaceTemplateTest - Standard washing:true
14:24:03.708 [main] INFO designpattern.template.interface_use.impl.StandardWashingImpl - 洗衣机:开机
14:24:03.708 [main] INFO designpattern.template.interface_use.impl.StandardWashingImpl - 洗衣机:标准洗涤
14:24:03.708 [main] INFO designpattern.template.interface_use.impl.StandardWashingImpl - 洗衣机:关机
14:24:03.708 [main] INFO functiontest.InterfaceTemplateTest - Standard washing:false
5 小结
- 模板模式实现方式有两种:
(1)抽象类;
(2)接口类; - 其中,抽象类是严格的1:1重写方法,设计方式刻板,不易扩展;
- 接口类使用default关键字可以重写部分方法,设计方式灵活,适配多种场景,易扩展;
- 推荐使用面向接口的方式设计模板。