浅析Java设计模式【3.6】——模板方法

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
简介: Java常用设计模式,模板模式

1. 目录

temple

2. 概念

定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。使得子类可以不改变一个算法的结构,即可重定义该算法的某些特定步骤。

可以理解为 用抽象类存放相同逻辑,再声明一些抽象方法来胁迫子类实现剩余的逻辑。不同的子类实现不同抽象方法,即不同的剩余逻辑。

综述,它是一种自上而下的模式,类似于企业决策,决策者制定相关流程,执行层负责具体实现。

3. 应用场景

局部场景下,实现相同,但在个别细节上略有差异。

4. 优缺点

4.1. 优点

  • 实现代码复用率高
  • 局部实现带来的调整,对整体影响小

4.2. 缺点

  • 模板和子类的耦合性高,如要对模板中的算法骨架进行变更,会影响子类变化

5. 实现

这里用一个登录后的校验密码这个场景来举例。


public class UserService {

    public final boolean verifyPassWord(String userId,String password) {
        String userPassWord = getById(userId);
        return userPassWord.equalsIgnoreCase(password);
    }

    private String getById(String userId) {
        // TODO: 从数据库读取
        return null;
    }
}

因为数据库读取用户信息比较频繁而且属于IO操作,比较影响效率,我们很多时候把热点数据放到缓存,减少跟数据库的之间的IO操作。那用什么缓存实现?不同的场景有不同的选型,所以此处,我们只写出要缓存的定义,具体实现交由子类。

5.1. 抽象类


public abstract class UserService {

    /** 校验密码
     * @author <a href="https://github.com/rothschil">Sam</a>
     * @date 2022/8/5-12:58
     * @param userId
     * @param password
     * @return boolean
     **/
    public final boolean verifyPassWord(String userId,String password) {
        String userPassWord = getById(userId);
        return userPassWord.equalsIgnoreCase(password);
    }

    private String getById(String userId) {
        //  1、getByCache
        String userPassWord = getCache(userId);
        //  2、缓存没有,从数据库中获取
        if(StringUtils.isEmpty(userPassWord)){
            userPassWord =readDb(userId);
        }
        //  3、写入缓存
        if(StringUtils.isEmpty(userPassWord)){
            putCache(userId,userPassWord);
        }
        return userPassWord;
    }

    protected abstract String getCache(String userId) ;

    protected abstract String putCache(String userId,String userPassWord) ;

    private String readDb(String userId) {
        return "";
    }
}

小结:因为声明抽象方法,所以整个类也必须声明为抽象类。 重点在 getCache(String userId)putCache(String userId,String userPassWord) ,具体实现交由子类,子类具体如何实现,就由子类根据实际情况完善。

5.2. 子类实现

5.2.1. Redis实现


public class RedisService extends UserService {
    private RedisClient client = RedisClient.create("redis://localhost:6379");

    protected String getCache(String key) {
        try (StatefulRedisConnection<String, String> connection = client.connect()) {
            RedisCommands<String, String> commands = connection.sync();
            return commands.get(key);
        }
    }

    protected void putCache(String key, String value) {
        try (StatefulRedisConnection<String, String> connection = client.connect()) {
            RedisCommands<String, String> commands = connection.sync();
            commands.set(key, value);
        }
    }
}

5.2.2. SpringCache站点实现


public class SpringCacheService extends UserService {
    

    @Cacheable(key = "'key'")
    protected String getCache(String key) {

    }

    @CachePut(key = "'key'",value = "'value'",)
    protected void putCache(String key, String value) {
        
    }
}

6. 综述

模板设计模式核心思想是:父类定义骨架,子类实现某些细节。

在某些场景下为了防止子类重写父类的骨架方法,可以在父类中对骨架方法使用 final 。对于需要子类实现的抽象方法,一般声明为 protected ,使得这些方法对外部客户端不可见。

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
18天前
|
Java
java发送微信公众号模板消息
java发送微信公众号模板消息
|
16天前
|
Java
Java中ReentrantLock中tryLock()方法加锁分析
Java中ReentrantLock中tryLock()方法加锁分析
13 0
|
5天前
|
Java 关系型数据库 MySQL
Elasticsearch【问题记录 01】启动服务&停止服务的2类方法【及 java.nio.file.AccessDeniedException: xx/pid 问题解决】(含shell脚本文件)
【4月更文挑战第12天】Elasticsearch【问题记录 01】启动服务&停止服务的2类方法【及 java.nio.file.AccessDeniedException: xx/pid 问题解决】(含shell脚本文件)
33 3
|
2天前
|
Java
Java 与垃圾回收有关的方法
Java 与垃圾回收有关的方法
|
3天前
|
设计模式 算法 Java
[设计模式Java实现附plantuml源码~行为型]定义算法的框架——模板方法模式
[设计模式Java实现附plantuml源码~行为型]定义算法的框架——模板方法模式
|
3天前
|
设计模式 JavaScript Java
[设计模式Java实现附plantuml源码~行为型] 对象状态及其转换——状态模式
[设计模式Java实现附plantuml源码~行为型] 对象状态及其转换——状态模式
|
3天前
|
设计模式 存储 JavaScript
[设计模式Java实现附plantuml源码~创建型] 多态工厂的实现——工厂方法模式
[设计模式Java实现附plantuml源码~创建型] 多态工厂的实现——工厂方法模式
|
3天前
|
设计模式 Java Go
[设计模式Java实现附plantuml源码~创建型] 集中式工厂的实现~简单工厂模式
[设计模式Java实现附plantuml源码~创建型] 集中式工厂的实现~简单工厂模式
|
3天前
|
设计模式 存储 前端开发
Java从入门到精通:2.2.1学习Java Web开发,了解Servlet和JSP技术,掌握MVC设计模式
Java从入门到精通:2.2.1学习Java Web开发,了解Servlet和JSP技术,掌握MVC设计模式
|
3天前
|
存储 Java 测试技术
一文搞清楚Java中的方法、常量、变量、参数
在JVM的运转中,承载的是数据,而数据的一种变现形式就是“量”,量分为:**常量与变量**,我们在数学和物理学中已经接触过变量的概念了,在Java中的变量就是在程序运行过程中可以改变其值的量。
14 0