这是我参与11月更文挑战的第15天,活动详情查看:2021最后一次更文挑战
前言
假设我们需要建造一座房子,需要的步骤有:建地基->砌墙->盖房顶。
我们的需求是需要建水泥房,还要建木头房,那么对应的步骤可能需要处理的逻辑不同,但是执行步骤是固定的,那么固定执行的步骤可以作为方法模板定义。
模板方法定义
模板方法是一种行为设计模式。模板方法设计模式用于创建方法执行模板,并将一些实现步骤推迟到子类。
模板方法定义了方法执行的步骤,它可以提供所有或部分子类通用的默认实现。
模板方法超类
我们来完成最前面的例子,建房子需要做的步骤有:建地基、砌墙和盖房顶。重要的一点是,我们不能改变执行顺序,因为我们不能在建地基之前盖房顶嘛。在这种情况下,我们可以创建一个模板方法,使用不同的方法来构建房子。
现在,盖房子的地基对于所有类型的房子都是一样的,无论是木房子还是水泥房子。我们可以提供基本实现,如果子类想重写这个方法也可以,但是多数情况下它对所有类型的房子都是通用的。
/**
* @author 小黑说Java
* @ClassName HouseBuildTemplate
* @Description 修建房屋模板
* @date 2021/11/14
**/
public abstract class HouseTemplate {
// 建房子的模板
public final void buildHouse() {
// 1.建地基
buildFoundation();
// 2.砌墙
buildWalls();
// 3.盖房顶
buildRoof();
System.out.println("房子修建完毕。");
}
private void buildFoundation() {
System.out.println("建地基~");
}
protected abstract void buildWalls();
protected abstract void buildRoof() ;
}
为了确保子类不会重写模板方法,应该将buildHouse()
其设置为final
的。
模板方法实现类
由于我们需要建木头房子和水泥房子,一些方法是需要由子类实现,所以必须将基类设置为抽象类。
木头房
public class WoodHouse extends HouseTemplate {
@Override
protected void buildWalls() {
System.out.println("用木头砌墙");
}
@Override
protected void buildRoof() {
System.out.println("盖木头房顶");
}
}
水泥房
/**
* @author 小黑说Java
* @ClassName CementHouse
* @Description 水泥房
* @date 2021/11/14
**/
public class CementHouse extends HouseTemplate {
@Override
protected void buildWalls() {
System.out.println("修水泥墙~");
}
@Override
protected void buildRoof() {
System.out.println("盖水泥房顶");
}
}
模板方法客户端
让我们用一个测试程序来测试模板方法模式示例。
/**
* @author 小黑说Java
* @ClassName TemplateMethodTest
* @date 2021/11/14
**/
public class TemplateMethodTest {
public static void main(String[] args) {
// 使用模板方法
WoodHouse woodHouse = new WoodHouse();
woodHouse.buildHouse();
System.out.println("-----------------");
CementHouse cementHouse = new CementHouse();
cementHouse.buildHouse();
}
}
注意,客户端正在调用基类的模板方法,根据不同步骤的实现,它使用了来自基类的一些方法和来自子类的一些方法。
运行结果:
模板方法类图
JDK中的模板方法模式
- java.io.InputStream,java.io.OutputStream,java.io.Reader,java.io.Writer中的非抽象方法。
- java.util.AbstractList,java.util.AbstractSet,java.util.AbstractMap中的非抽象方法。
模板方法设计模式要点
- 模板方法由固定的步骤组成,模板方法应该是final的,对于某些步骤,基类和子类的实现可以是不同的;
- 大多数时候,子类调用父类中的方法,但在模板方法模式中,超类模板方法调用子类中的方法;
- 基类的默认实现方法称为hooks,他们是为了被子类覆盖,如果你想要一些不覆盖的方法,可以将方法修饰为final。
以上就是模板方法模式的全部内容,如果对你有帮助,点个赞吧!