模板模式是常用的一种行为型设计模式,主要思想是在模板中定义一套流程骨架代码,并且不实现骨架代码中使用的一些方法,这些方法留给子类去实现。假如我们业务开发中有一个场景,我们的业务系统需要从不同征信渠道查询征信报告,每家机构输出的内容不一样,但是都分为3个步骤,建立连接、获取报告原始内容、解析报告并入库。这样,我们定义一个模板类:
代码语言:javascript复制public abstract class AbstractReportTemplate {
protected Logger logger = LoggerFactory.getLogger(getClass());
public final void doTask(){
doConnect();
getReport();
parseRepot();
}
/**
* 建立连接
*/
public abstract void doConnect();
/**
* 获取报告
*/
public abstract void getReport();
/**
* 解析报告并落库
*/
public abstract void parseRepot();
}
假如我们现在要对接A征信机构,那我们只要继承这个模板类,实现上面的抽象方法就可以了,任务流程不变。
代码语言:javascript复制public class AReport extends AbstractReportTemplate {
public void doConnect() {
logger.info("do connect");
}
public void getReport() {
logger.info("get report");
}
public void parseRepot() {
logger.info("parseReport");
}
}
方法调用:
代码语言:javascript复制public static void main(String[] args){
AbstractReportTemplate aReport = new AReport();
aReport.doTask();
}
可见,模板模式实现起来非常简单。下面我介绍几个源码中的模板模式。
1.jdk中的InputStream类就是一个模板类,里面定义了抽象read方法
代码语言:javascript复制public int read(byte b[], int off, int len) throws IOException {
if (b == null) {
throw new NullPointerException();
} else if (off < 0 || len < 0 || len > b.length - off) {
throw new IndexOutOfBoundsException();
} else if (len == 0) {
return 0;
}
int c = read();
if (c == -1) {
return -1;
}
b[off] = (byte)c;
int i = 1;
try {
for (; i < len ; i ) {
c = read();
if (c == -1) {
break;
}
b[off i] = (byte)c;
}
} catch (IOException ee) {
}
return i;
}
public abstract int read() throws IOException;
实现类有好多,如下图:
下面是ByteArrayInputStream的实现:
代码语言:javascript复制public synchronized int read() {
return (pos < count) ? (buf[pos ] & 0xff) : -1;
}
2.jdbc中的AbstractDataSourceInitializer用来初始化数据源
代码语言:javascript复制@PostConstruct
protected void initialize() {
if (!isEnabled()) {
return;
}
ResourceDatabasePopulator populator = new ResourceDatabasePopulator();
String schemaLocation = getSchemaLocation();
if (schemaLocation.contains(PLATFORM_PLACEHOLDER)) {
String platform = getDatabaseName();
schemaLocation = schemaLocation.replace(PLATFORM_PLACEHOLDER, platform);
}
populator.addScript(this.resourceLoader.getResource(schemaLocation));
populator.setContinueOnError(true);
customize(populator);
DatabasePopulatorUtils.execute(populator, this.dataSource);
}
protected abstract DataSourceInitializationMode getMode();
protected abstract String getSchemaLocation();
BatchDataSourceInitializer中的实现
代码语言:javascript复制@Override
protected DataSourceInitializationMode getMode() {
return this.properties.getInitializeSchema();
}
@Override
protected String getSchemaLocation() {
return this.properties.getSchema();
}
文中源码:https://github.com/jinjunzhu/design-pattern.git