当前位置: 首页 > article >正文

Android设计模式之模板方法模式

一、定义:

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

二、结构:

        AbstractClass抽象类:定义算法的骨架,包含模板方法和若干基本方法(抽象方法、具体方法、钩子方法)。

        ConcreteClass具体子类:实现抽象类中的抽象方法,覆盖某些具体方法或钩子方法以定制算法的步骤。

三、代码示例:

        1.抽象模板类

public abstract class DataExporter {

    // 模板方法(final禁止覆盖)
    public final void exportData(List<String> data, String filename) {
        if (validateData(data)) {
            String formattedData = formatData(data); // 抽象方法
            writeToFile(formattedData, filename);     // 抽象方法
            sendNotification();                      // 钩子方法
        }
    }

    // 抽象方法(子类必须实现)
    protected abstract String formatData(List<String> data);
    protected abstract void writeToFile(String content, String filename);

    // 具体方法(默认实现)
    protected boolean validateData(List<String> data) {
        return data != null && !data.isEmpty();
    }

    // 钩子方法(子类可选覆盖)
    protected void sendNotification() {
        // 默认不发送通知
    }
}
        2.具体子类

// 导出为 CSV 格式
public class CsvExporter extends DataExporter {
    @Override
    protected String formatData(List<String> data) {
        return String.join(",", data); // 转换为 CSV
    }

    @Override
    protected void writeToFile(String content, String filename) {
        try (FileWriter writer = new FileWriter(filename)) {
            writer.write(content);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // 覆盖钩子方法(导出后发送通知)
    @Override
    protected void sendNotification() {
        System.out.println("CSV文件导出完成!");
    }
}

// 导出为 JSON 格式
public class JsonExporter extends DataExporter {
    @Override
    protected String formatData(List<String> data) {
        return "{ \"data\": " + data.toString() + " }"; // 简化的JSON格式
    }

    @Override
    protected void writeToFile(String content, String filename) {
        try (FileWriter writer = new FileWriter(filename)) {
            writer.write(content);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
        3.使用模板方法

public class Main {
    public static void main(String[] args) {
        List<String> data = Arrays.asList("Apple", "Banana", "Cherry");

        // 导出为 CSV
        DataExporter csvExporter = new CsvExporter();
        csvExporter.exportData(data, "data.csv");

        // 导出为 JSON
        DataExporter jsonExporter = new JsonExporter();
        jsonExporter.exportData(data, "data.json");
    }
}
 

四、应用场景:

        1.多个子类有相同流程但部分步骤不同,如文件导出,网络请求。

        2.需要控制子类的扩展点,如钩子方法。

        3.框架设计,如Activity的生命周期,AsyncTask。

五、优缺点:

优点:

        1.代码复用,避免重复算法流程;

        2.扩展性强,子类只需关注差异步骤;

        3.封装不变部分,提升可维护性。

缺点:

        1.灵活性受限,算法流程固定;

        2.继承强耦合,违法合成复用原则

        3.父类修改影响子类

相关文章:

Android设计模式之模板方法模式

一、定义&#xff1a; 定义一个操作中的算法的框架&#xff0c;而将一些步骤延迟到子类中&#xff0c;使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。 二、结构&#xff1a; AbstractClass抽象类&#xff1a;定义算法的骨架&#xff0c;包含模板方法和若干…...

李宏毅机器学习笔记(1)—机器学习基本概念+深度学习基本概念

机器学习基本概念 1、获取模型 步骤 1.1、假定未知函数 带未知参数的函数 1.2、定义损失函数 真实值&#xff1a;label MAE MSE 几率分布&#xff0c;cross-entropy? 1.3、优化 单独考虑一个参数 让损失函数最小&#xff0c;找导数为零的点 单独考虑w&#xff0c;w…...

数字IC后端项目常见问题之streamOut layermap和innovus drc violation

Q1&#xff1a;我需要将Innovus设计GDS导出到Virtuoso&#xff0c;但发现写出GDS的过程会报如下所示的警告。这里写出GDS使用的是Virtuoso (DFII) streamOut mapping文件&#xff01; Clock Gen模块Routing DRC&#xff0c;Timing分析及解决 streamOut tease.gds2 -mapFile cd…...

短剧系统开发动漫短剧系统源码开发上线小程序app教程

一、市场规模与用户增长&#xff1a;突破677亿&#xff0c;Z世代成主力 整体扩张 2025年短剧市场预计同比增长15%&#xff0c;规模达677.9亿元&#xff0c;用户规模6.62亿&#xff08;占网民59.7%&#xff09;。动漫短剧作为细分领域&#xff0c;增速显著受益于二次元文化渗透&…...

太阳能高杆路灯:照亮未来的新光

在全球能源转型进程加速以及可持续发展理念日益深入人心的背景下&#xff0c;太阳能高杆路灯作为融合新能源技术、智能控制技术与多功能集成特性的创新产品&#xff0c;正逐步革新传统路灯的格局。其不仅有效解决了传统路灯对电网供电的依赖问题&#xff0c;更为城市及乡村的照…...

《C++Linux编程进阶:从0实现muduo 》-第8讲.C++面试如何高效获取线程ID

章节重点 在C面试时&#xff0c;经常被问到如果高效获取线程ID&#xff0c;但不少同学都不知道如何回答。 重点是通过__thread关键字。 重点内容 视频讲解&#xff1a;《CLinux编程进阶&#xff1a;从0实现muduo C网络框架系列》-第8讲. C面试如何高效获取线程ID 测试获取线…...

【Tauri2】011——菜单menu(2)

前言 前面简单地创建了菜单&#xff0c;接下来就来试试菜单中的action Rust中菜单项注册action AppHandle in tauri - Rusthttps://docs.rs/tauri/2.4.0/tauri/struct.AppHandle.html#method.on_menu_event这就需要用到App或者AppHandle中的方法on_menu_event #[must_use] …...

架构设计基础系列:面向对象设计的原则

引言 面向对象设计&#xff08;Object-Oriented Design&#xff0c;OOD&#xff09;是软件开发中的重要概念&#xff0c;其核心在于通过对象、类、继承、封装和多态等机制&#xff0c;实现对现实世界问题的抽象和建模。OOD不仅有助于提高代码的可重用性、可维护性和可扩展性&a…...

UE5学习笔记 FPS游戏制作35 使用.csv配置文件

文章目录 导入.csv要求首先创建一个结构体导入配置文件读取配置 导入 .csv要求 第一行必须包含标题 第一列的内容必须不能重复&#xff0c;因为第一列会被当成行的名字&#xff0c;在数据处理中发挥类似于字典的key的作用 当前的配置文件内容如下 首先创建一个结构体 结构…...

嵌入式单片机ADC数模转换的基本方法

第一:模数转换的概述 1:模数转换的概念 一般在电路中,信号分为两种,一种是模拟信号,一种是数字信号,绝大多数传感器采集的都是模拟信号,如温度、湿度、烟雾浓度、亮度.......,但是对于计算机需要处理的数字信号,那就需要利用电路把模拟信号转换为数字信号,这个转换的…...

Web数据挖掘及其在电子商务中的研究与应用

标题:Web数据挖掘及其在电子商务中的研究与应用 内容:1.摘要 随着互联网的飞速发展&#xff0c;Web数据呈现出爆炸式增长&#xff0c;电子商务领域更是积累了海量数据。在此背景下&#xff0c;对Web数据进行有效挖掘并应用于电子商务具有重要意义。本研究旨在探索Web数据挖掘技…...

01-Docker 安装

1、安装环境介绍 安装环境&#xff1a;Linux CentOS 7 本安装教程参考Docker官方文档&#xff0c;地址如下&#xff1a;https://docs.docker.com/engine/install/centos/ 2、卸载旧版docker 首先如果系统中已经存在旧的Docker&#xff0c;则先卸载&#xff1a; yum remove do…...

Redis 的缓存雪崩、击穿、穿透及其解决办法

文章目录 Redis 的缓存雪崩、击穿、穿透及其解决办法缓存雪崩解决办法 缓存击穿解决方案 缓存穿透解决方案 Redis 的缓存雪崩、击穿、穿透及其解决办法 本篇文章回顾 Redis 当中缓存崩溃、击穿、穿透现象以及相应的解决办法&#xff0c;主要的参考资料是&#xff1a;https://w…...

使用 Selenium 构建简单高效的网页爬虫

在当今数据驱动的世界中&#xff0c;网络爬虫已成为获取网络信息的重要工具。本文将介绍如何使用 Python 和 Selenium 构建一个简单而高效的网页爬虫&#xff0c;该爬虫能够处理现代网站的动态内容&#xff0c;支持代理设置和用户配置文件。 为什么选择 Selenium&#xff1f; …...

性能比拼: Pingora vs Nginx (My NEW Favorite Proxy)

本内容是对知名性能评测博主 Anton Putra Pingora vs Nginx Performance Benchmark: My NEW Favorite Proxy! 内容的翻译与整理, 有适当删减, 相关指标和结论以原作为准 介绍 在本视频中&#xff0c;我们将对比 Nginx 和 Pingora&#xff08;一个用于构建网络服务的 Rust 框架…...

Ranger一分钟

简介 Ranger Admin&#xff1a;Web UIPolicy Admin Tool&#xff1a;定义和管理策略的模块Ranger Plugins&#xff1a;HDFS、Hive、HBase、Kafka、Storm、YARNRanger UserSync&#xff1a; LDAP、Active DirectoryRanger KMS&#xff1a;管理和保护数据加密的密钥 加密密钥管理…...

STM32单片机入门学习——第5节: [3-1]GPIO输出

写这个文章是用来学习的,记录一下我的学习过程。希望我能一直坚持下去,我只是一个小白,只是想好好学习,我知道这会很难&#xff0c;但我还是想去做&#xff01; 本文写于&#xff1a;2025.04.01 STM32开发板学习——第5节&#xff1a; [3-1]GPIO输出 前言开发板说明引用解答和…...

Open GL ES ->模型矩阵、视图矩阵、投影矩阵等变换矩阵数学推导以及方法接口说明

Open GL ES 变换矩阵详解 一、坐标空间变换流程 局部空间 ->Model Matrix(模型矩阵)-> 世界空间 世界空间->View Matrix(视图矩阵)->观察空间 观察空间 ->Projection Matrix(投影矩阵)->裁剪空间 裁剪空间 ->ViewPort Transform(视口变换)>屏幕空间 …...

AI提示词:自然景区智能客服

提示描述 专为自然景区游客设计的智能客服系统&#xff0c;旨在通过人工智能技术提供实时、准确的景区信息、游览建议、安全提示和服务支持&#xff0c;提升游客的体验质量和满意度。 提示词 # Role: 自然景区智能客服## Profile: - Author: xxx - Version: 1.0 - Language: …...

c#的反射和特性

在 C# 中&#xff0c;反射&#xff08;Reflection&#xff09;和特性&#xff08;Attributes&#xff09;是两个强大的功能&#xff0c;它们在运行时提供元编程能力&#xff0c;广泛用于框架开发、对象映射和动态行为扩展。以下是对它们的详细介绍&#xff0c;包括定义、用法、…...

智能体项目实现AI对话流式返回效果

1、智能体项目里与AI大模型对话的时候&#xff0c;需要从后端的流式接口里取数据并实现打字机渲染效果。这里涉及到 Markdown 格式的渲染&#xff0c;所以需要配合 marked.js 实现&#xff0c;安装 marked.js &#xff1a; npm install marked 引用&#xff1a; import { ma…...

定时任务(python)

介绍 &#x1f9e9; 什么是“定时任务”&#xff1f; 定时任务&#xff0c;就是按照设定的时间间隔或时间点自动执行某些操作。比如&#xff1a; • 每天早上8点发通知 • 每隔10秒采集一次数据 • 每小时清理一次缓存相关使用 ✅ 最简单的方式&#xff1a;while True tim…...

Python学习第二十七天

yield关键字 yield关键字扮演着核心角色&#xff0c;主要用于处理异步数据流和请求调度。 主要作用 生成器函数&#xff1a;将方法转换为生成器&#xff0c;可以逐步产生结果而不需要一次性返回所有数据 异步处理&#xff1a;支持Scrapy的异步架构&#xff0c;提高爬取效率 …...

Docker Compose 启动jar包项目

参考文章安装Docker和Docker Compose 点击跳转 配置 创建一个文件夹存放项目例如mydata mkdir /mydata上传jar包 假设我的jar包名称为goudan.jar 编写dockerfile文件 vim app-dockerfile按键盘上的i进行编辑 # 使用jdk8 FROM openjdk:8-jre# 设置时区 上海 ENV TZAsia/Sh…...

pytorch中dataloader自定义数据集

前言 在深度学习中我们需要使用自己的数据集做训练&#xff0c;因此需要将自定义的数据和标签加载到pytorch里面的dataloader里&#xff0c;也就是自实现一个dataloader。 数据集处理 以花卉识别项目为例&#xff0c;我们分别做出图片的训练集和测试集&#xff0c;训练集的标…...

SQL Server:触发器

在 SQL Server Management Studio (SSMS) 中查看数据库触发器的方法如下&#xff1a; 方法一&#xff1a;通过对象资源管理器 连接到 SQL Server 打开 SSMS&#xff0c;连接到目标数据库所在的服务器。 定位到数据库 在左侧的 对象资源管理器 中&#xff0c;展开目标数据库&a…...

标题:利用 Rork 打造定制旅游计划应用程序:一步到位的指南

引言&#xff1a; 在数字化时代&#xff0c;旅游计划应用程序已经成为旅行者不可或缺的工具。但开发一个定制的旅游应用可能需要耗费大量时间与精力。好消息是&#xff0c;Rork 提供了一种快捷且智能的解决方案&#xff0c;让你能轻松实现创意。以下是使用 Rork 创建一个定制旅…...

WebSocket原理详解(二)

WebSocket原理详解(一)-CSDN博客 目录 1.WebSocket协议的帧数据详解 1.1.帧结构 1.2.生成数据帧 2.WebSocket协议控制帧结构详解 2.1.关闭帧 2.2.ping帧 2.3.pong帧 3.WebSocket心跳机制 1.WebSocket协议的帧数据详解 1.1.帧结构 WebSocket客户端与服务器通信的最小单…...

计算声音信号波形的谐波

计算声音信号波形的谐波 1、效果 2、定义 在振动分析中,谐波通常指的是信号中频率是基频整数倍的成分。基频是振动的主要频率,而谐波可能由机械系统中的非线性因素引起。 3、流程 1. 信号生成:生成或加载振动信号数据(模拟或实际数据)。 2. 预处理:预处理数据,如去噪…...

RepoReporter 仿照`TortoiseSVN`项目监视器,能够同时支持SVN和Git仓库

RepoReporter 项目地址 RepoReporter 一个仓库监视器&#xff0c;仿照TortoiseSVN项目监视器&#xff0c;能够同时支持SVN和Git仓库。 工作和学习会用到很多的仓库&#xff0c;每天都要花费大量的时间在频繁切换文件夹来查看日志上。 Git 的 GUI 工具琳琅满目&#xff0c;Git…...