【函数式接口使用✈️✈️】配合策略模式实现文件处理的案例

devtools/2024/11/13 9:36:34/

目录

🍸前言

🍻一、功能描述

🍺二、面向对象设计模式

🍹三、策略模式

🍦四、策略 VS 面向对象

🍨章末


🍸前言

        小伙伴们大家好,上周初步了解了下函数式接口,Consumer,Supplier,Function等接口的使用,以及结合而策略模式实现购物促销功能的案例实现,这里再配合实现文件处理的功能,案例比较简单,主要是看策略模式和普通面向对象模式的区别

🍻一、功能描述

假设我们需要实现一个文件处理器,能够读取文件内容,并根据不同的处理策略对文件内容进行处理,例如将文件内容转换为大写、小写或者进行加密。

🍺二、面向对象设计模式

       (1) 这种方式逻辑比较清晰,就是创建一个文件处理器类,该类中有各种文件内容处理方法,比如内容转大写或者加密,文件处理器类如下:

java">import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;public class FileProcessor {public void processFileToUpper(String filename) throws IOException {try (BufferedReader reader = new BufferedReader(new FileReader(filename))) {String line;while ((line = reader.readLine()) != null) {String processedLine = line.toUpperCase();System.out.println(processedLine); // 可替换为具体处理逻辑,比如写入到另一个文件}}}public void processFileToLower(String filename) throws IOException {try (BufferedReader reader = new BufferedReader(new FileReader(filename))) {String line;while ((line = reader.readLine()) != null) {String processedLine = line.toLowerCase();System.out.println(processedLine); }}}public void processFileEncrypt(String filename) throws IOException {try (BufferedReader reader = new BufferedReader(new FileReader(filename))) {String line;while ((line = reader.readLine()) != null) {// 这里只是演示,实际的加密算法应该更复杂String processedLine = line.replaceAll("[a-zA-Z]", "*");System.out.println(processedLine); }}}
}

        (2)测试下,使用很简单,实例化一个文件处理器对象,通过对象调用其具体的处理方法即可

java">import java.io.IOException;public class TestFile {public static void main(String[] args) {String filename = "C:\\Users\\ben.huang\\Desktop\\testFile.txt";FileProcessor fileProcessor = new FileProcessor();try {System.out.println("File content in uppercase:");fileProcessor.processFileToUpper(filename);System.out.println("\nFile content in lowercase:");fileProcessor.processFileToLower(filename);System.out.println("\nFile content encrypted:");fileProcessor.processFileEncrypt(filename);} catch (IOException e) {e.printStackTrace();}}
}

🍹三、策略模式

        (1)也是创建一个文件处理器类,不过该类中只有一个处理方法,具体地 实现功能要根据传入地函数名称去处理,文件处理器类如下:

java">import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;/*** @author ben.huang*/
public class FileFunction {public void processFile (String fileName, Function<String,String> processingStrategy) throws IOException {//supplier 相当于生产者,调用该函数会获取到文件地读取流Supplier<BufferedReader> fileReadSupplier = () ->{try {return new BufferedReader(new FileReader(fileName));} catch (FileNotFoundException e) {throw new RuntimeException("error opening file"+e);}};//相当于一个消费者,根据传入的函数去消费每一行读取到地数据Consumer<String> fileProcessor = line ->{String apply = processingStrategy.apply(line);System.out.println(apply);};//获取输入流BufferedReader reader = fileReadSupplier.get();String line;//依次处理每行输入流while((line = reader.readLine()) != null){fileProcessor.accept(line);}}
}

         (2)具体地文件处理函数可以单独写到一个类中,因为后期如果需要添加新的处理函数,直接在这里进行扩展即可,文件处理函数如下:

java">import java.util.function.Function;/*** @author ben.huang*/
public class FileProcessingStrategies {//返回的是函数表达式public static Function<String,String> toUpperCase(){return String::toUpperCase;}public static Function<String,String> toLowerCase(){return String::toLowerCase;}public static Function<String,String> encrypt(){return str -> str.replaceAll("[a-zA-Z]","*");}
}

        (3)测试下

java">import java.io.IOException;/*** @author ben.huang*/
public class TestFileFunction {public static void main(String[] args) {String fileName = "C:\\Users\\ben.huang\\Desktop\\testFile.txt";FileFunction fileFunction = new FileFunction();try {//方法调用的时候,传入需要的处理函数即可System.out.println("File content in uppercase:");fileFunction.processFile(fileName,FileProcessingStrategies.toUpperCase());System.out.println("\nFile content in lowercase:");fileFunction.processFile(fileName,FileProcessingStrategies.toLowerCase());System.out.println("\nFile content in encrypted:");fileFunction.processFile(fileName,FileProcessingStrategies.encrypt());} catch (IOException e) {throw new RuntimeException(e);}}
}

🍦四、策略 VS 面向对象

         首先来看面向对象设计模式,这种方式是我在初学地时候最喜欢的编码方式,这种逻辑方便观看,易读性强,调用方便,代码方便别人阅读,修改方便,直接CV修改修改就行,整个功能在一个类中全部实现,省了来回跳看的眼花,还有....(等等,串台了(bushi))

        那我们为社么还要用策略模式呢?

不知大家可曾听闻开闭原则,依鄙人来看就是说不要去修改原有的类,而是去扩展。比如说,现在又加了几个文件处理器功能,策略模式只需要在策略函数类中新增几个函数,如果使用面向对象的话,需要新增几个方法,并且这些方法中有很多代码重复,冗余度很高

        总的来说,策略模式更加直接,通过定义不同的策略类来实现不同的功能,并且可以在运行时动态切换策略。而面向对象设计模式则更加灵活,可以根据具体的需求选择不同的设计模式来实现文件处理功能

🍬后续补充

        用的比较少的话还是生疏,再给大家举几案例吧

🍧案例一、比如根据不同的商品进行不同的税费计算

        分析:按照不同商品进行计算处理,简单的方法就是使用 if else 判断属于哪种商品,然后进行对应的计算操作。使用策略模式是这样,每个商品都要计算,那么可以把计算操作当作一个接口,不同的计算逻辑可以实现该接口,然后创建一个处理类,包含具体的计算实现类,以及调用实现类方法,代码如下:
        (1)计算方法接口定义

java">interface TaxStrategy {double calculateTax(double amount);
}

        (2)计算方法具体实现类

java">class BasicTaxStrategy implements TaxStrategy {@Overridepublic double calculateTax(double amount) {return amount * 0.1; // 基本税率为10%}
}class LuxuryTaxStrategy implements TaxStrategy {@Overridepublic double calculateTax(double amount) {return amount * 0.2; // 奢侈品税率为20%}
}class FoodTaxStrategy implements TaxStrategy {@Overridepublic double calculateTax(double amount) {return amount * 0.05; // 食品税率为5%}
}

         (3)计算处理类,使用 Function 函数式接口代表具体的计算策略,构造方法接收一个函数参数,处理方法中的  apply 方法会接受一个参数,处理后返回一个参数

java">class TaxCalculator {private Function<Double, Double> taxStrategy;public TaxCalculator(Function<Double, Double> taxStrategy) {this.taxStrategy = taxStrategy;}public double calculateTax(double amount) {return taxStrategy.apply(amount);}
}//使用的时候像这样,传入一个实现类,则调用的就是这个实现类的计算方法//TaxCalculator taxCalculator = new TaxCalculator(new BasicTaxStrategy()::calculateTax);//double calculate = taxCalculator.calculate(100);

🍨章末

        文章到这里就结束了~


http://www.ppmy.cn/devtools/17897.html

相关文章

自动化机器学习流水线:基于Spring Boot与AI机器学习技术的融合探索

&#x1f9d1; 作者简介&#xff1a;阿里巴巴嵌入式技术专家&#xff0c;深耕嵌入式人工智能领域&#xff0c;具备多年的嵌入式硬件产品研发管理经验。 &#x1f4d2; 博客介绍&#xff1a;分享嵌入式开发领域的相关知识、经验、思考和感悟&#xff0c;欢迎关注。提供嵌入式方向…

部署后端常见问题:更换JDK版本

目录 #步骤一&#xff1a;创建相关目录用于安装JDK #步骤二&#xff1a;安装JDK17版本&#xff1a; 附&#xff1a; JDK8下载&#xff1a; JDK1.8下载&#xff1a; #步骤三&#xff1a;解压同时重命名文件&#xff1a; #步骤四&#xff1a;编辑文件设置环境变量 原本代…

Golang实现一个批量自动化执行树莓派指令的软件(2)指令

简介 基于上篇 Golang实现一个批量自动化执行树莓派指令的软件(1)文本加密&配置&命令行交互实现&#xff0c; 这篇实现的是指令&#xff0c; 即通过ssh执行linux指令的实现。 环境描述 运行环境: Windows&#xff0c; 基于Golang&#xff0c; 暂时没有使用什么不可跨平…

Godot3D学习笔记1——界面布局简介

创建完成项目之后可以看到如下界面&#xff1a; Godot引擎也是场景式编程&#xff0c;这里的一个场景相当于一个关卡。 这里我们点击左侧“3D场景”按钮创建一个3D场景&#xff0c;现在在中间的画面中会出现一个球。在左侧节点视图中选中“Node3D”&#xff0c;右键创建子节点…

【UE5.1 C++】提升编译速度

步骤 1. 在“C:\Users\用户\AppData\Roaming\Unreal Engine\UnrealBuildTool”目录下找到“BuildConfiguration.xml”文件 打开“BuildConfiguration.xml”&#xff0c;添加如下部分内容 <?xml version"1.0" encoding"utf-8" ?> <Configuratio…

【AIGC调研系列】Bunny-Llama-3-8B-V与其他多模态大模型相比的优劣

Bunny-Llama-3-8B-V作为基于Llama-3的多模态大模型&#xff0c;其优势主要体现在以下几个方面&#xff1a; 性能超越其他模型&#xff1a;根据我搜索到的资料&#xff0c;Bunny-Llama-3-8B-V在多个主流Benchmark上表现良好&#xff0c;超越了LLaVA-7B、LLaVA-13B、Mini-Gemini…

PyCharm 中的特殊标记

在使用 PyCharm 开发 Python 项目的时候&#xff0c;经常会有一些特殊的标记&#xff0c;有些是 IDE 提示的代码规范&#xff0c;有些则为了方便查找而自定义的标记。 我在之前写过一些关于异常捕获的文章&#xff1a;Python3 PyCharm 捕获异常报 Too broad exception clause …

前端开发攻略---用原生JS在网页中也能实现语音识别

1、语音识别的过程 语音识别涉及三个过程&#xff1a;首先&#xff0c;需要设备的麦克风接收这段语音&#xff1b;其次&#xff0c;语音识别服务器会根据一系列语法 (基本上&#xff0c;语法是你希望在具体的应用中能够识别出来的词汇) 来检查这段语音&#xff1b;最后&#xf…