模板方法模式示例
模板方法模式的本质是通过在一个方法中定义算法的骨架,将某些步骤延迟到子类中实现。笔者将通过一个 Java 示例来展示如何使用模板方法模式管理登录过程,并在其他方法中调用该过程,从而实现代码的复用和结构的优化。
模式原则
对修改代码进行封闭,对扩展代码进行开放
源代码
笔者首先提供了一个未使用模板方法模式的UserController类,该类包含多个需要登录验证的方法。每个方法中都重复了登录逻辑,导致代码冗余。
package com.DesignPattern.template_method;
import java.util.Scanner;
public class UserController {
    private String userName;
    private String password;
    private final Scanner scanner = new Scanner(System.in);
    public UserController () {
    }
    private boolean loginAction () {
        System.out.println("请输入用户名:");
        this.userName = scanner.next();
        System.out.println("请输入密码:");
        this.password = scanner.next();
        return this.userName.equals("admin") && this.password.equals("123456");
    }
    public void getUserInfo () {
        if (loginAction()) {
            System.out.println("获取用户信息 success");
        } else {
            getUserInfo();
        }
    }
    public void getUserLikes () {
        if (loginAction()) {
            System.out.println("获取用户喜欢 success");
        } else {
            getUserLikes();
        }
    }
    public void getUserFollowing () {
        if (loginAction()) {
            System.out.println("获取用户关注 success");
        } else {
            getUserFollowing();
        }
    }
}
模板优化后
为了消除重复的登录逻辑,笔者应用了模板方法模式,创建了一个抽象类APIManager,将登录过程封装在accessAPI方法中。具体的 API 调用由子类实现。
package com.DesignPattern.template_method;
/*
 * 模板方法
 * */
abstract class APIManager {
    public void accessAPI (String apiName) {
        if (!loginAction()) {
            accessAPI(apiName);
            return;
        }
        callAPI(apiName);
    }
    protected abstract boolean loginAction ();
    protected abstract void callAPI (String apiName);
}
实现具体的 API 管理类
笔者创建了AdminController类继承自APIManager,并实现了具体的登录逻辑和 API 调用方法。
package com.DesignPattern.template_method;
import java.util.Scanner;
public class AdminController extends APIManager {
    private String userName;
    private String password;
    private final Scanner scanner = new Scanner(System.in);
    public AdminController () {
    }
    @Override
    protected boolean loginAction () {
        System.out.println("请输入用户名:");
        this.userName = scanner.next();
        System.out.println("请输入密码:");
        this.password = scanner.next();
        return this.userName.equals("admin") && this.password.equals("123456");
    }
    @Override
    protected void callAPI (String apiName) {
        switch (apiName) {
            case "getUserInfo" -> getUserInfo();
            case "getUserLikes" -> getUserLikes();
            case "getUserFollowing" -> getUserFollowing();
            default -> System.out.println("apiName 不存在");
        }
    }
    private void getUserInfo () {
        System.out.println("获取用户信息 success");
    }
    private void getUserLikes () {
        System.out.println("获取用户喜欢 success");
    }
    private void getUserFollowing () {
        System.out.println("获取用户关注 success");
    }
}
使用模板方法
在主类中,笔者展示了如何通过AdminController调用不同的 API 方法,统一管理登录过程。
package com.DesignPattern.template_method;
public class Main {
    public static void main(String[] args) {
        AdminController adminController = new AdminController();
        adminController.accessAPI("getUserInfo");
        adminController.accessAPI("getUserLikes");
        adminController.accessAPI("getUserFollowing");
    }
}
代码仓库
完整代码可访问以下链接:Java-Learning/src/com/DesignPattern/template_method at main · sumingcheng/Java-Learning