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

目录

🍸前言

🍻一、功能描述

🍺二、面向对象设计模式

🍹三、策略模式

[🍦四、策略 VS 面向对象](#🍦四、策略 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 {
    @Override
    public double calculateTax(double amount) {
        return amount * 0.1; // 基本税率为10%
    }
}

class LuxuryTaxStrategy implements TaxStrategy {
    @Override
    public double calculateTax(double amount) {
        return amount * 0.2; // 奢侈品税率为20%
    }
}

class FoodTaxStrategy implements TaxStrategy {
    @Override
    public double calculateTax(double amount) {
        return amount * 0.05; // 食品税率为5%
    }
}

(3)计算处理类

java 复制代码
class TaxCalculator {
    private TaxStrategy taxStrategy;

    public TaxCalculator(TaxStrategy taxStrategy) {
        this.taxStrategy = taxStrategy;
    }

    public double calculate(double amount) {
        return taxStrategy.calculateTax(amount);
    }
}

        //使用的时候像这样,传入一个实现类,则调用的就是这个实现类的计算方法
        //TaxCalculator taxCalculator = new TaxCalculator(new BasicTaxStrategy());
        //double calculate = taxCalculator.calculate(100);

🍨章末

文章到这里就结束了~

相关推荐
瓯雅爱分享1 小时前
Java+Vue构建的采购招投标一体化管理系统,集成招标计划、投标审核、在线竞价、中标公示及合同跟踪功能,附完整源码,助力企业实现采购全流程自动化与规范化
java·mysql·vue·软件工程·源代码管理
mit6.8244 小时前
[C# starter-kit] 命令/查询职责分离CQRS | MediatR |
java·数据库·c#
诸神缄默不语4 小时前
Maven用户设置文件(settings.xml)配置指南
xml·java·maven
任子菲阳4 小时前
学Java第三十四天-----抽象类和抽象方法
java·开发语言
学Linux的语莫5 小时前
机器学习数据处理
java·算法·机器学习
找不到、了5 小时前
JVM的即时编译JIT的介绍
java·jvm
西瓜er5 小时前
JAVA:Spring Boot 集成 FFmpeg 实现多媒体处理
java·spring boot·ffmpeg
你总是一副不开心的样子(´ . .̫ .5 小时前
一、十天速通Java面试(第三天)
java·面试·职场和发展·java面试
迎風吹頭髮5 小时前
UNIX下C语言编程与实践63-UNIX 并发 Socket 编程:非阻塞套接字与轮询模型
java·c语言·unix
我是华为OD~HR~栗栗呀5 小时前
23届考研-Java面经(华为OD)
java·c++·python·华为od·华为·面试