模板方法模式是一种高效的编程策略,它的优点包括:封装了不变的部分,扩展可变部分;在父类中封装了公共部分的代码,提高了代码的复用性。缺点是对每个不同的实现都需要定义一个子类,导致类的数量增加;父类抽象方法由子类实现,子类的结果会影响父类的结果,提高了代码阅读的难度 。
在软件开发中,我们经常会遇到各种复杂的问题,需要解决的问题往往涉及到多个步骤,这时,我们可以使用模板方法模式来简化问题的解决过程,模板方法模式是一种行为设计模式,它定义了一个操作中的算法的骨架,将一些步骤延迟到子类中实现,使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。
模板方法模式的主要角色有三个:抽象类(Template)、具体类(Concrete)和子类(Subclass)。
1、抽象类(Template):这是模板方法模式的核心部分,它定义了算法的骨架,包括一个模板方法(也称为框架方法)和一系列的具体方法,模板方法是抽象类中唯一被声明为抽象的方法,它是算法的主体部分,其他具体方法都是对模板方法的补充。
2、具体类(Concrete):这是实现了抽象类接口的具体类,它实现了抽象类中的抽象方法和具体方法,具体类可以根据需要选择性地覆盖模板方法中的某些步骤。
3、子类(Subclass):这是继承自抽象类的具体子类,它可以重写模板方法中的某些步骤,以实现自己的功能。
模板方法模式的优点主要有以下几点:
1、提高了代码的可复用性:通过将算法的骨架定义在抽象类中,可以在多个具体类中重复使用,从而提高了代码的可复用性。
2、降低了代码的耦合度:由于具体的算法实现由子类负责,所以抽象类和具体类之间的耦合度降低,有利于后期的维护和扩展。
3、便于修改和扩展:如果需要修改或扩展算法的某个步骤,只需要创建一个新的子类即可,无需修改抽象类和具体类的代码。
下面是一个简单的模板方法模式的例子:
假设我们需要实现一个计算圆的面积的功能,我们可以将计算圆的面积的过程抽象为一个算法骨架,然后通过模板方法模式来实现具体的计算过程。
我们定义一个抽象类Circle
,其中包含一个模板方法calculateArea()
和两个具体方法getRadius()
和getArea()
:
public abstract class Circle { // 模板方法 public final double calculateArea() { getRadius(); // 获取半径 return Math.PI * getRadius() * getRadius(); // 根据半径计算面积 } // 具体方法:获取半径 protected abstract double getRadius(); // 具体方法:获取面积 protected abstract double getArea(); }
我们可以创建两个具体的子类CircleA
和CircleB
,分别表示不同的圆形对象:
public class CircleA extends Circle { @Override protected double getRadius() { return 5; // A型圆的半径为5 } @Override protected double getArea() { return Math.PIgetRadius() * getRadius(); // A型圆的面积公式为π*r^2 } } public class CircleB extends Circle { @Override protected double getRadius() { return 10; // B型圆的半径为10 } @Override protected double getArea() { return Math.PIgetRadius() * getRadius(); // B型圆的面积公式为π*r^2 } }
我们可以在客户端代码中使用这些具体的圆形对象来计算圆的面积:
public class Main { public static void main(String[] args) { Circle circleA = new CircleA(); // 创建一个A型圆对象 System.out.println("A型圆的面积为:" + circleA.calculateArea()); // 输出A型圆的面积 Circle circleB = new CircleB(); // 创建一个B型圆对象 System.out.println("B型圆的面积为:" + circleB.calculateArea()); // 输出B型圆的面积 } }