设计模式详解(十一):模板方法——Template Method

Template Method 设计模式

1. 概述

Template Method 是一种行为设计模式,它定义了一个算法的框架,并允许子类在不改变算法结构的前提下重新定义算法中的某些步骤。

Template Method 模式中:

  • 父类(抽象类)定义了算法的骨架(模板方法),包括一系列步骤。
  • 子类可以覆盖其中的某些步骤,而不改变整体的流程。

Template Method 的定义

Template Method 模式是一种将算法的步骤结构固定下来的设计模式,通过一个模板方法(Template Method)定义算法的执行顺序,同时将部分步骤的实现延迟到子类中去完成。通俗来说,就是定义一个通用的流程框架,并允许子类根据需要填充其中的具体步骤。

模式的好处

  1. 代码复用:将通用的算法框架抽取到父类中,减少代码重复。
  2. 易于扩展:子类可以覆盖父类中的某些步骤,满足不同的业务需求,而不影响整体流程。
  3. 符合开闭原则:对扩展开放,对修改关闭,算法的整体结构不会轻易被改变。

适用场景

  1. 当多个子类之间存在相同的操作流程,但部分步骤的实现不同。
  2. 需要将算法的具体实现延迟到子类中,同时保持整体的逻辑结构一致。
  3. 需要复用算法的骨架,同时允许子类进行定制化操作。

UML 类图

AbstractClass
+templateMethod()
-step1()
-step2()
+optionalStep()
ConcreteClass
+step1()
+step2()

解释

  • AbstractClass 是抽象类,定义了 templateMethod,它调用了一系列步骤(step1, step2 等)。
  • ConcreteClass 是子类,实现了抽象类中定义的具体步骤。

2. 代码示例

2.1 基本示例

以下是一个简单的 Template Method 示例:

// 抽象类
abstract class TemplateMethod {
    // 模板方法
    public final void execute() {
        step1();
        step2();
        optionalStep();
    }

    // 基本步骤,由子类实现
    abstract void step1();
    abstract void step2();

    // 可选步骤,提供默认实现
    void optionalStep() {
        System.out.println("执行可选步骤");
    }
}

// 具体实现类
class ConcreteClassA extends TemplateMethod {
    @Override
    void step1() {
        System.out.println("ConcreteClassA: 执行步骤1");
    }

    @Override
    void step2() {
        System.out.println("ConcreteClassA: 执行步骤2");
    }
}

class ConcreteClassB extends TemplateMethod {
    @Override
    void step1() {
        System.out.println("ConcreteClassB: 执行步骤1");
    }

    @Override
    void step2() {
        System.out.println("ConcreteClassB: 执行步骤2");
    }

    @Override
    void optionalStep() {
        System.out.println("ConcreteClassB: 重写了可选步骤");
    }
}

// 客户端代码
public class TemplateMethodDemo {
    public static void main(String[] args) {
        TemplateMethod templateA = new ConcreteClassA();
        TemplateMethod templateB = new ConcreteClassB();

        System.out.println("执行 ConcreteClassA:");
        templateA.execute();

        System.out.println("\n执行 ConcreteClassB:");
        templateB.execute();
    }
}

输出结果

执行 ConcreteClassA:
ConcreteClassA: 执行步骤1
ConcreteClassA: 执行步骤2
执行可选步骤

执行 ConcreteClassB:
ConcreteClassB: 执行步骤1
ConcreteClassB: 执行步骤2
ConcreteClassB: 重写了可选步骤

3. Android 中的应用

3.1 RecyclerView.Adapter

RecyclerView.Adapter 是一个典型的 Template Method 设计模式的应用。

  • onCreateViewHolder():创建 ViewHolder。
  • onBindViewHolder():绑定数据到 ViewHolder。
  • getItemCount():返回数据项数量。

Adapter 定义了完整的数据绑定流程,但子类负责实现各个具体步骤。

代码示例
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
    private List<String> data;

    public MyAdapter(List<String> data) {
        this.data = data;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext())
                .inflate(android.R.layout.simple_list_item_1, parent, false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        holder.textView.setText(data.get(position));
    }

    @Override
    public int getItemCount() {
        return data.size();
    }

    // ViewHolder 内部类
    public static class ViewHolder extends RecyclerView.ViewHolder {
        TextView textView;

        public ViewHolder(View itemView) {
            super(itemView);
            textView = itemView.findViewById(android.R.id.text1);
        }
    }
}

3.2 Activity 生命周期

Android 中 Activity 的生命周期回调函数也是 Template Method 模式的体现。

  • onCreate():Activity 被创建时调用。
  • onStart():Activity 即将可见时调用。
  • onResume():Activity 变为可交互状态时调用。

开发者在这些生命周期方法中实现具体逻辑,而 Activity 类则定义了整个流程。

3.3 Fragment 生命周期

Fragment 的生命周期同样是一个典型的 Template Method 模式的应用。

  • onAttach():Fragment 与 Activity 绑定时调用。
  • onCreateView():创建 Fragment 视图时调用。
  • onDestroyView():销毁视图时调用。

通过覆写这些方法,开发者可以根据需求自定义 Fragment 的行为。


4. 小结

Template Method 模式在 Android 中十分常见,通过它可以:

  • 把算法的结构封装在父类中,保持代码复用性。
  • 允许子类根据具体需求实现不同的步骤,增强灵活性。

关键点

  1. 定义模板方法(templateMethod),确保算法的整体流程。
  2. 将具体的步骤延迟到子类实现。

通过本文的示例,我们了解了 Template Method 设计模式在 Android 中的实际应用,如 RecyclerView.AdapterActivity 生命周期Fragment 生命周期。这种模式有助于代码的扩展和维护,符合开闭原则(对扩展开放,对修改关闭)。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/938626.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

AI工具如何深刻改变我们的工作与生活

在当今这个科技日新月异的时代&#xff0c;人工智能&#xff08;AI&#xff09;已经从科幻小说中的概念变成了我们日常生活中不可或缺的一部分。从智能家居到自动驾驶汽车&#xff0c;从医疗诊断到金融服务&#xff0c;AI正以惊人的速度重塑着我们的世界。 一、工作方式的革新…

压力测试Jmeter简介

前提条件&#xff1a;要安装JDK 若不需要了解&#xff0c;请直接定位到左侧目录的安装环节。 1.引言 在现代软件开发中&#xff0c;性能和稳定性是衡量系统质量的重要指标。为了确保应用程序在高负载情况下仍能正常运行&#xff0c;压力测试变得尤为重要。Apache JMeter 是一…

手眼标定工具操作文档

1.手眼标定原理介绍 术语介绍 手眼标定&#xff1a;为了获取相机与机器人坐标系之间得位姿转换关系&#xff0c;需要对相机和机器人坐标系进行标定&#xff0c;该标定过程成为手眼标定&#xff0c;用于存储这一组转换关系的文件称为手眼标定文件。 ETH&#xff1a;即Eye To …

vue 自定义组件image 和 input

本章主要是介绍自定义的组件&#xff1a;WInput&#xff1a;这是一个验证码输入框&#xff0c;自动校验&#xff0c;输入完成回调等&#xff1b;WImage&#xff1a;这是一个图片展示组件&#xff0c;集成了缩放&#xff0c;移动等操作。 目录 一、安装 二、引入组件 三、使用…

CTFHUB-web(SSRF)

内网访问 点击进入环境&#xff0c;输入 http://127.0.0.1/flag.php 伪协议读取文件 /?urlfile:///var/www/html/flag.php 右击查看页面源代码 端口扫描 1.根据题目提示我们知道端口号在8000-9000之间,使用bp抓包并进行爆破 POST请求 点击环境&#xff0c;访问flag.php 查看页…

Mysql 深度分页查询优化

Mysql 分页优化 1. 问题根源 问题&#xff1a; mysql在数据量大的时候&#xff0c;深度分页数据偏移量会增大&#xff0c;导致查询效率越来越低。 问题根源&#xff1a; 当使用 LIMIT 和 OFFSET 进行分页时&#xff0c;MySQL 必须扫描 OFFSET LIMIT 行&#xff0c;然后丢弃前…

[LeetCode-Python版]21. 合并两个有序链表(迭代+递归两种解法)

题目 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例 1&#xff1a; 输入&#xff1a;l1 [1,2,4], l2 [1,3,4] 输出&#xff1a;[1,1,2,3,4,4] 示例 2&#xff1a; 输入&#xff1a;l1 [], l2 [] 输出&#x…

Git 安装教程

Git 是一个分布式版本控制系统&#xff0c;用于跟踪源代码的变化。它允许多个开发者协作开发同一个项目&#xff0c;能够有效管理项目的版本历史&#xff0c;便于协作与代码回溯。 Git官网 官网提供各种操作系统的安装程序。 step1.点击"Download for Windows"按钮&a…

Spring学习笔记-基础

前言&#xff1a;我是在哔哩哔哩上黑马程序员上找的课程。-----2024-12-16 官网Spring | Homehttps://spring.io/ Sping全家桶中重要三个&#xff1a; Spring Framework底层框架&#xff0c;在整个全家通中&#xff0c;所有的技术依赖它执行。 Spring Boot简化开发加速开发…

CNAS-AL06《实验室认可领域分类》修订,软件测试领域整体修订

为了不断适应行业发展的需要&#xff0c;进一步完善认可评审管理工作&#xff0c;进一步提高认可评审工作质量&#xff0c;CNAS认可委针对CNAS-AL06《实验室认可领域分类》进行了修订&#xff0c;并于近日正式发布。 原文件CNAS-AL06:20220101有25项一级代码&#xff0c;其中0…

单片机原理及应用笔记:单片机中断系统原理与项目实践

高金鹏&#xff1a;男&#xff0c;银川科技学院计算机与人工智能学院&#xff0c;2022级别计算机科学与技术本科生&#xff0c;单片机原理及应用课程第六组。 指导教师&#xff1a;王兴泽 电子邮件&#xff1a;高金鹏3535558665qq.com 个人CSDN:暴躁的海绵宝宝 暴躁的海绵宝…

【win10+RAGFlow+Ollama】搭建本地大模型助手(教程+源码)

一、RAGFlow简介 RAGFlow是一个基于对文档深入理解的开源RAG&#xff08;Retrieval-augmented Generation&#xff0c;检索增强生成&#xff09;引擎。 主要作用&#xff1a; 让用户创建自有知识库&#xff0c;根据设定的参数对知识库中的文件进行切块处理&#xff0c;用户向大…

在 Ubuntu 上部署 Terraform 管理平台:实现云基础设施的集中管理

简介 Terraform 是一款开源基础架构自动化工具&#xff0c;可让您通过命令行界面部署和管理数百台服务器。使用 Terraform&#xff0c;你可以通过在一个人类可读的文件中定义配置来构建、更改和管理你的基础架构。它支持许多云提供商&#xff0c;如 AWS、Azure、GCP 和阿里巴巴…

概率论得学习和整理25:EXCEL 关于直方图/ 频度图 /hist图的细节,2种做hist图的方法

目录 1 hist图的特点 2 hist的设置技巧&#xff1a;直接生成的hist图往往很奇怪不好用&#xff1a;因为横轴的分组不对 3 如何修改分组 4 设置开放边界&#xff0c;把长尾合并&#xff0c;得到hist图1 5 用原始表得到频数表 6 用上面的频数图做柱状图&#xff0c;再修改&…

RabbitMQ的核心组件有哪些?

大家好&#xff0c;我是锋哥。今天分享关于【RabbitMQ的核心组件有哪些&#xff1f;】面试题。希望对大家有帮助&#xff1b; RabbitMQ的核心组件有哪些&#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 RabbitMQ是一个开源的消息代理&#xff08;Messag…

桥接模式的理解和实践

桥接模式&#xff08;Bridge Pattern&#xff09;&#xff0c;又称桥梁模式&#xff0c;是一种结构型设计模式。它的核心思想是将抽象部分与实现部分分离&#xff0c;使它们可以独立地进行变化&#xff0c;从而提高系统的灵活性和可扩展性。本文将详细介绍桥接模式的概念、原理…

【原创教程】西门子1500TCP_UDP通信说明大全(下篇)

2.3.3 TRCV故障说明 通讯无法正常连接时,ERROR引脚和STATUS引脚得状态有助于我们判断错误得原因,根据下表得提示,快速排除问题。 2.3.4 TRCV使用 点击TRCV指令得右上角蓝色图标,打开开始组态画面,按照控制要求填写 EN_R:用于激活接收的控制参数,及何时使用TRCV的接收功…

Grafana配置告警规则推送企微机器人服务器资源告警

前提 已经部署Grafana&#xff0c;并且dashboard接入数据 大屏编号地址&#xff1a;Node Exporter Full | Grafana Labs 创建企微机器人 备注&#xff1a;群里若有第三方外部人员不能创建 机器人创建完成&#xff0c;记录下来Webhook地址 Grafana配置告警消息模板 {{ define &…

RabbitMQ如何构建集群?

大家好&#xff0c;我是锋哥。今天分享关于【RabbitMQ如何构建集群&#xff1f;】面试题。希望对大家有帮助&#xff1b; RabbitMQ如何构建集群&#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 在RabbitMQ中&#xff0c;集群&#xff08;Cluster&#x…

JDK以及JRE

目录 1.常用的快捷键操作2.重要的dos命令3.Jre&#xff08;java Runtime environment&#xff09;4.Jdk&#xff08;java development kit&#xff09;5.安装JDK6.JDK的目录7.Jdk的环境变量配置8.写第一个java程序8.1 安装UE软件8.2 写第一个HelloWorld 9.java运行机制 1.常用的…