定义一个操作中的算法骨架,而将算法的一些步骤延迟到子类中实现,使得子类可以不改变该算法结构的情况下重定义该算法的某些特定步骤。它是一种类行为型模式,模版模式又名模版方法模式。
通俗一点讲:在现实生活中,我们把规定了流程或者格式的实例定义为模版,允许使用者在使用的时候,根据自己个人的需求来去更新它。具体实例如下↓ ↓ ↓
①程序员在设计一个系统时,通过分析知道了算法所需的关键步骤,而且确定了这些步骤的执行顺序,但某些步骤的具体实现还未知,或者说某些步骤的实现与具体的环境相关,所以可以将这些步骤移交给子类,让子类来自己实现它的功能。
②我们去银行办理业务,一般都需要经过以下4个流程:取号、排队、办理具体业务、对工作人员进行评分等,其中取号、排队和对银行工作人员进行评分的业务对每个客户是一样的,可以在父类中实现,但是办理具体业务却因人而异,它可能是存款、取款或者转账等,可以延迟到子类中实现。
③我们每天都要经历起床、洗漱、吃饭、工作、睡觉等事情,但是我们每个人在每天的工作都有可能不同,但是起床、洗漱、吃饭、睡觉这些事情都是一样子的。所以我们可以把人类的一天定义为一个模版,而具体的工作一项,可以去放到子类中,根据自己的需求来决定。
④现实生活中,还有很多形形色色的模版,诸如:简历模板、论文模板、Word模板等等。
优点:
①它封装了不变的部分,扩展可变部分。它把认为是不变部分封装到父类实现,而把可变部分由子类继承实现,便于子类继续扩展。
②它在父类中提取了公共的部分代码,便于代码复用。
③部分方法是由子类实现的,因此子类可以通过扩展方式增加相应的功能,符合开闭原则。
缺点:
①对每个不同的实现都需要定义一个子类,这会导致类的个数增加,系统更加庞大,设计也更加抽象。
②父类中的抽象方法由子类实现,子类执行的结果会影响父类的结果,这导致一种反向的控制结构,它提高了代码阅读的难度。
十一黄金周旅行,一般都要经过如下几个步骤:①挑选目的地 ②订飞机票 ③开启旅行 ④选择入住酒店 ⑤坐汽车去景区 ⑥在景区游玩 ⑦行程结束回家 等,有些步骤对于每个人来说都是一样子的,但是有一些步骤则因人而异了。
具体场景:A家庭和B家庭商量决定一起去塞班岛旅行,不同点是:①A家庭决定入住A酒店,B家庭决定入住B酒店 ②A家庭决定去A景区玩,B家庭决定去B景区玩。于是乎他们决定一起出行。
1.定义一个旅游模板类TravelTemplate
/**
* 定义一个旅行模版
*/
public abstract class TravelTemplate {
/**
* 定义一个方法,开启我的旅行
* 因为myTravel()方法是一个旅行基本的模版,模版是不允许被修改的,所以此处使用final来修饰,切记!!!
*/
public final void myTravel(){
//1.选择目的地
chooseDestination();
//2.订飞机票
orderAirPlaneTicket();
//3.开启旅行
startTravel();
//4.选择入住酒店(抽象方法);
chooseHotel();
//5.坐汽车景区(抽象方法)
toJingQu();
//6.在景区游玩
travelInJingQu();
//7.行程结束回家
goHome();
}
//1.选择目的地
public void chooseDestination(){
System.out.println("我们都选择去塞班岛旅行");
}
//2.订飞机票
public void orderAirPlaneTicket(){
System.out.println("我们预订了2019年10月1日,16:50由北京飞往塞班岛的MU763航班");
}
//3.开启旅行
public void startTravel(){
System.out.println("现在是10.1,终于可以愉快开启旅行了");
}
//4.选择入住酒店(因为该场景选择酒店不同,所以该方法定义为抽象方法,有子类来继承实现)
public abstract void chooseHotel();
//5.坐汽车去景区(因为A家庭和B家庭分别要去A景区和B景区,所以该方法也定义为抽象方法,由子类来继承实现)
public abstract void toJingQu();
//6.在景区游玩
public void travelInJingQu(){
System.out.println("在景区里面游来游去好好玩耍");
}
//7.行程结束回家
public void goHome(){
System.out.println("假期好快,又要结束回家工作了,┭┮﹏┭┮");
}
}
2.定义A家庭HomeA
/**
* A家庭(继承自抽象类TravelTemplate,定义自己的实现方式)
*/
public class HomeA extends TravelTemplate {
/**
* A家庭选择入住的酒店
*/
@Override
public void chooseHotel() {
System.out.println("我们是A家庭,我们要入住A酒店");
}
/**
* A家庭选择要去的景区
*/
@Override
public void toJingQu() {
System.out.println("我们是A家庭,我们要去A景区游玩");
}
}
3.定义B家庭HomeB
/**
* B家庭(继承自抽象类TravelTemplate,定义自己的实现方式)
*/
public class HomeB extends TravelTemplate {
/**
* B家庭选择入住的酒店
*/
@Override
public void chooseHotel() {
System.out.println("我们是B家庭,我们要入住B酒店");
}
/**
* B家庭选择要去的景区
*/
@Override
public void toJingQu() {
System.out.println("我们是B家庭,我们要去B景区游玩");
}
}
4.测试类,开启愉快旅行
/**
* A家庭&B家庭,通过旅行模版开启旅行
*/
public class testTravel {
public static void main(String[] args) {
//A家庭
TravelTemplate A = new HomeA();
A.myTravel();
System.out.println("------------------------------------------------");
//B家庭
TravelTemplate B = new HomeB();
B.myTravel();
}
}
测试结果:
我们都选择去塞班岛旅行
我们预订了2019年10月1日,16:50由北京飞往塞班岛的MU763航班
现在是10.1,终于可以愉快开启旅行了
我们是A家庭,我们要入住A酒店
我们是A家庭,我们要去A景区游玩 ---A家庭扩展实现部分(其他为模版共用部分)
在景区里面游来游去好好玩耍
假期好快,又要结束回家工作了,┭┮﹏┭┮
------------------------------------------------
我们都选择去塞班岛旅行
我们预订了2019年10月1日,16:50由北京飞往塞班岛的MU763航班
现在是10.1,终于可以愉快开启旅行了
我们是B家庭,我们要入住B酒店
我们是B家庭,我们要去B景区游玩 ---B家庭扩展实现部分(其他为模版共用部分)
在景区里面游来游去好好玩耍
假期好快,又要结束回家工作了,┭┮﹏┭┮
SpringJDBC
---- 就是一个Java规范,各个数据厂商自己去实现即可
①加载驱动类DriverManager
②建立连接
③创建语句集(标准语句集、预处理语句集) ---->数据库产商MySQL、Oracle、SQLServer等的语句集都是不一样的
④执行语句集
⑤处理结果集ResultSet,返回List
⑥完成ORM映射操作 ---->每个数据厂商映射ORM操作也不同