【设计模式】行为模式——模板方法模式

行为模式——模板方法模式

一、定义

模板方法模式是一种行为设计模式, 它在超类中定义了一个算法的框架, 允许子类在不修改结构的情况下重写算法的特定步骤。

二、问题

假设现在你要做一个登录系统,每个角色(普通用户、管理员、超级管理员)的登录功能相似但又有所差别,那么我们会如何设计这个系统呢?

三、解决方案

我们可以设计一个抽象的模板方法,它实现一些每个具体类重复的代码(比如从数据库中查询用户名和密码),每个具体类中再实现各自不同的功能(比如 不同角色密码的加密方式不同)

四、代码实现

1、抽象类 (Abstract­Class) 会声明作为算法步骤的方法, 以及依次调用它们的实际模板方法。 算法步骤可以被声明为 抽象类型, 也可以提供一些默认实现

 package com.atmae.templateMethod;

import java.util.Objects;

/**
 * @Author: Mae
 * @Date: 2022/4/14
 * @Time: 8:08
 * @Description:
 */
public abstract class Login {
    
    

    protected String username;
    protected String password;

    /**
     * 登录接口
     *
     * @return true/false
     */
    public abstract boolean login(String username, String password);

    /**
     * 从数据库中根据用户名查询密码判断是否匹配 (模拟)
     * @param username 用户名
     * @param password 密码
     */
    public boolean getPasswordByDatabase(String username, String password) {
    
    
        //数据库中先查询有无此用户名
        String sql = "select username,password from sys_user where username=?";
        //模拟执行sql语句
        //映射成user对象
        User user = excute(sql,username);
        if (Objects.isNull(user)) {
    
    
            return false;
        } else {
    
    
            return user.passowrd.equals(password);
        }
    }
}

2、
管理员

package com.atmae.templateMethod;

/**
 * @Author: Mae
 * @Date: 2022/4/14
 * @Time: 8:08
 * @Description: 管理员
 */
public class AdminLogin extends Login {
    
    

    @Override
    public boolean login(String username, String password) {
    
    
        //根据用户名去数据库中查询密码是否匹配
        //判断是否可以登录
        //普通管理员密码进行JWT加密
        String newPassword=parseJWT(password);
        return getPasswordByDatabase(username,newPassword);
    }

    public String parseJWT(String password){
    
    
        return JWT.parse(password);
    }
}

超级管理员

package com.atmae.templateMethod;

import java.util.Objects;

/**
 * @Author: Mae
 * @Date: 2022/4/14
 * @Time: 8:10
 * @Description: 超级管理员
 */
public class SuperAdminLogin extends Login{
    
    
    @Override
    public boolean login(String username, String password) {
    
    
        //超级管理员的密码使用对称加密算法加密(模拟)
        String newPassword=parseDES(password);
        return getPasswordByDatabase(username,newPassword);
    }

    public  String parseDES(String password){
    
    
        return DES.parse(password);
    }

}

普通用户

package com.atmae.templateMethod;

import sun.security.provider.MD5;

import java.util.Objects;

/**
 * @Author: Mae
 * @Date: 2022/4/14
 * @Time: 8:11
 * @Description:
 */
public class UserLogin extends Login {
    
    
    @Override
    public boolean login(String username, String password) {
    
    
        //根据用户名去数据库中查询密码是否匹配
        //判断是否可以登录
        //普通用户密码MD5盐值 加密(模拟)
        String newPassword= parseMD5(password);
        return getPasswordByDatabase(username,newPassword);
    }

    public String parseMD5(String password){
    
    
        return MD5.parse(password);
    }
}

3、客户端

package com.atmae.templateMethod;

/**
 * @Author: Mae
 * @Date: 2022/4/14
 * @Time: 9:01
 * @Description:
 */
public class Client {
    
    
    public static void main(String[] args) {
    
    
        //超级管理员登录
        Login user=new SuperAdminLogin();
        user.login("1122","454545");
    }
}

五、UML图

在这里插入图片描述

六、模板方法模式使用场景

  • 只希望客户端扩展某个特定算法步骤, 而不是整个算法或其结构时, 可使用模板方法模式。
  • 当多个类的算法除一些细微不同之外几乎完全一样时, 你可使用该模式。 但其后果就是, 只要算法发生变化, 你就可能需要修改所有的类。

七、总结

优点

  • 允许客户端重写一个大型算法中的特定部分, 使得算法其他部分修改对其所造成的影响减小。
  • 可将重复代码提取到一个超类中

缺点

  • 模板方法中的步骤越多, 其维护工作就可能会越困难。
  • 违反里氏替换原则,(父类拥有的性质 子类不一定成立了)

八、与其他模式的关系

  • 工厂方法模式是模板方法模式的一种特殊形式。 同时, 工厂方法可以作为一个大型模板方法中的一个步骤
  • 模板方法基于继承机制: 它允许你通过扩展子类中的部分内容来改变部分算法。
    策略模式基于组合机制: 你可以通过对相应行为提供不同的策略来改变对象的部分行为。
    模板方法在类层次上运作, 因此它是静态的。
    策略在对象层次上运作, 因此允许在运行时切换行为。

猜你喜欢

转载自blog.csdn.net/weixin_51799151/article/details/124163239