用Java静态工厂模式制作一个属于自己的文件格式转换工厂的小程序!!!

一、前言

  这两周,我刚接触了Java设计模式,于是脑洞大开,想用Java写一个文件格式转换的小程序。一开始是只是随便写写,但是写着写着,发现不容易维护,于是就想用刚学习的静态工厂模式来完成文件格式转换。虽然静态工厂模式不属于GoF的23种经典设计模式,但是作为一个最容易上手,也是最容易体会面向对象设计的模式,用文件格式转换练练手,强化一下自己对静态工厂模式的认识和理解。

二、准备工作

  Java编译器:Idea
  所需jar包:aspose.pdf-11.8.0.jar、aspose.slides-19.3.jar、aspose.cells-8.5.2.jar、aspose.words-18.6-jdk16-crack.jar、commons-io-2.11.0.jar、fontbox-2.0.27.jar、java-1.0.2.jar、pdfbox-2.0.27.jar、Spire.Pdf.jar
  所需配置文件:license.xml
  所需jar包可从它们的官网获取:Spire相关包aspose相关包commons-io相关包pdfbox相关包fontbox相关包java-1.0.2包
  注:本博客只作为知识分享,切勿商用以上相关的jar包,否则后果自负。

三、绘制类图

  在一开始拿到项目的时候,就开始编码是一个非常不好的习惯,我们应该学着分析项目,自然就可以从先画类图开始。
文件格式转换类图

四、创建工程,编写代码

  在项目跟路径下,创建一个lib文件夹,用于存放相关jar包。同时在src文件夹下,创建一个resources文件夹,用于存放配置文件。普通Java工程的resources文件夹创建较为特殊,以下是创建步骤:

  • 先创建普通的文件夹,为其取名为resources。
    resources文件夹的创建
  • 找到File,选择Project Structure。
    resources文件夹的创建
    resources文件夹的创建
  • 选择Modules,找到resources文件夹,单机鼠标右键,选择Sources。
    resources文件夹的创建
    resources文件夹的创建
  • 最后选择Apply,然后ok即可。
    resources文件夹的创建
  • resources文件夹创建好后,接下来把配置文件放resources文件夹里。
    项目结构
  • 根据类图,去创建相关的文件夹。
    项目结构
    完成以上操作后,就可以根据上面的类图开始写代码了。
  • 在type文件夹下,创建一个FileType的抽象类。
package com.YuGong.type;

import java.io.File;
import java.io.InputStream;

/**
 * 抽象文件类型类
 * 作者:Cool_foolisher
 * 开始日期:2023-3-24
 * 结束日期:2023-3-24
 */
public abstract class FileType {
    protected InputStream fileInput; // 待处理的文件的路径
    protected File outputFile; // 输出路径
    public String oldFile; // 存储原文件路径
    public String newFile; // 存储新文件路径
    public String fileType; // 存储需要转换文件的类型名
    public String userType; // 存储转换后类型的类型名(用户选择的文件类型)
    protected double time; // 存储转换的时间

    /**
     * 文件类型转换的抽象方法
     */
    public abstract void typeChange(String yFile, String xFile);

    /**
     * 获取License配置文件
     * @return 是否获取成功 true:成功 false:失败
     */
    protected abstract boolean getLicense();

}

  • 然后再根据类图,在concreteType文件夹下,分别创建WordToPDF和PDFtoOther类。
package com.YuGong.concreteType;

import com.YuGong.type.FileType;
import com.YuGong.util.Method;
import com.aspose.words.Document;
import com.aspose.words.License;
import com.aspose.words.SaveFormat;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;


/**
 * 文字转PDF类
 * 作者:Cool_foolisher
 * 开始日期:2023-3-24
 * 结束日期:2023-3-24
 */
public class WordToPDF extends FileType {
    /**
     * 获取WordLicense配置文件
     * @return 是否获取成功 true:成功 false:失败
     */
    @Override
    protected boolean getLicense() {
        boolean result = false;
        try {
            File file = new File(String.valueOf(WordToPDF.class.getResource("/license.xml")));
            License asposeLic = new License();
            String s = Method.cutLongStr(file.getPath());
            String value = new String(s.getBytes("utf-8"), "utf-8");
            System.out.println("凭证文件的路径:" + value);
            // 凭证文件的路径
            asposeLic.setLicense(value);
            result = true;
        } catch (Exception e) {
            System.out.println("获取Word凭证文件出现异常:");
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 文字转PDF具体方法
     * @param yFile 原文件的路径
     * @param xFile 新文件的路径
     */
    @Override
    public void typeChange(String yFile, String xFile) {
        // 验证License
        if (!getLicense()) {
            return;
        }
        FileOutputStream os = null;
        String fileName = yFile.substring(yFile.lastIndexOf("\\")+1, yFile.lastIndexOf("."));
        try {
            long old = System.currentTimeMillis();
            File file = new File(xFile + "\\" + fileName + userType); // 新建一个空白pdf文档
            os = new FileOutputStream(file);
            Document doc = new Document(yFile); // Address是将要被转化的word文档
            // 全面支持DOC, DOCX, OOXML, RTF HTML, OpenDocument, PDF, EPUB, XPS, SWF 相互转换
            doc.save(os, SaveFormat.PDF);
            System.out.println("原Word文件的路径:" + yFile);
            System.out.println("新PDF文件的路径:" + file.getPath());
            System.out.println("您把Word文件转换为PDF文件!!!");
            System.out.println("文件正在转换...");
            long now = System.currentTimeMillis();
            int t1; // 用于存储将小数变成整数的时间
            // 毫秒除以1000化成秒,秒除以60化成分,分 * 1000 取int 变成整数 赋值给 t1
            t1 = (int) ((((now - old) / 1000.0) / 60) * 1000);
            // t1在变成小数 除以 1000 变成 只有三位小数的时间 赋值给 time
            time = (double) t1 / 1000;
            System.out.println("共耗时:" + time + "分钟!!!");
        } catch (Exception e) {
            System.out.println("亲,您的word转PDF出现异常:");
            e.printStackTrace();
        }finally {
            if (os != null) {
                try {
                    os.flush();
                    os.close();
                } catch (IOException e) {
                    System.out.println("亲,您的word转PDF结束出现异常:");
                    e.printStackTrace();
                }
            }
        }
    }
}

package com.YuGong.concreteType;

import com.YuGong.type.FileType;
import com.YuGong.util.Method;
import com.aspose.pdf.Document;
import com.aspose.pdf.License;
import com.aspose.pdf.SaveFormat;

import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Paths;


/**
 * PDF转其他类(其他包括:Word、PPT、Excel)
 * 作者:Cool_foolisher
 * 开始日期:2023-3-24
 * 结束日期:2023-3-24
 */
public class PDFToOther extends FileType {
    /**
     * 获取PDFLicense配置文件
     * @return 是否获取成功 true:成功 false:失败
     */
    @Override
    protected boolean getLicense() {
        boolean result = false;
        String fileName = oldFile.substring(oldFile.lastIndexOf("\\")+1, oldFile.lastIndexOf("."));
        try {
            ClassLoader loader = Thread.currentThread().getContextClassLoader();
            File file = new File(String.valueOf(PDFToOther.class.getResource("/license.xml")));
            String s = Method.cutLongStr(file.getPath());
            String value = new String(s.getBytes("utf-8"), "utf-8");
            // 凭证文件的路径
            System.out.println("凭证文件的路径:" + value);
            // 凭证文件的路径
            InputStream license = Files.newInputStream(Paths.get(value));// 凭证文件
            if (oldFile != null) {
                System.out.println("原文件路径:" + oldFile);
                fileInput = Files.newInputStream(Paths.get(oldFile));// 待处理的文件
            }
            System.out.println("新文件的保存路径:" + newFile);
            outputFile = new File(newFile + "\\" + fileName + userType);// 输出路径
            License asposeLic = new License();
            asposeLic.setLicense(license);
            license.close();
            result = true;
        } catch (Exception e) {
            System.out.println("获取PDF凭证文件出现异常:");
            e.printStackTrace();
        }
        return result;
    }

    /**
     * PDF转其他具体方法
     * @param yFile 原文件的类型
     * @param xFile 新文件的类型
     */
    @Override
    public void typeChange(String yFile, String xFile) {
        // 验证License
        if (!getLicense()) {
            return;
        }
        try {
            long old = System.currentTimeMillis();
            Document pdfDocument = new Document(fileInput);
            OutputStream fileOutput = Files.newOutputStream(outputFile.toPath());
            if (userType.equals(".docx")) {
                pdfDocument.save(fileOutput, SaveFormat.DocX);
                System.out.println("您把PDF文件转换为Word文件!!!");
                System.out.println("文件正在转换...");
            } else if (userType.equals(".doc")) {
                pdfDocument.save(fileOutput, SaveFormat.Doc);
                System.out.println("您把PDF文件转换为Word文件!!!");
                System.out.println("文件正在转换...");
            } else if (userType.equals(".xls") || userType.equals(".xlsx")) {
                pdfDocument.save(fileOutput, SaveFormat.Excel);
                System.out.println("您把PDF文件转换为Excel文件!!!");
                System.out.println("文件正在转换...");
            } else if (userType.equals(".ppt") || userType.equals(".pptx")) {
                pdfDocument.save(fileOutput, SaveFormat.Pptx);
                System.out.println("您把PDF文件转换为PPT文件!!!");
                System.out.println("文件正在转换...");
            }
            fileOutput.close();
            long now = System.currentTimeMillis();
            int t1; // 用于存储将小数变成整数的时间
            // 毫秒除以1000化成秒,秒除以60化成分,分 * 1000 取int 变成整数 赋值给 t1
            t1 = (int) ((((now - old) / 1000.0) / 60) * 1000);
            // t1在变成小数 除以 1000 变成 只有三位小数的时间 赋值给 time
            time = (double) t1 / 1000;
            System.out.println("共耗时:" + time + "分钟");
        } catch (Exception e) {
            System.out.println("亲,您的PDF转其他类型出现异常:");
            e.printStackTrace();
        }
    }
}

  • 接着,我们在factory文件夹下,创建一个FileTypeFactory工厂类。
package com.YuGong.factory;

import com.YuGong.concreteType.*;
import com.YuGong.type.FileType;

/**
 * 文件类型转换简单工厂类
 * 作者:Cool_foolisher
 * 开始日期:2023-3-24
 * 结束日期:2023-3-24
 */
public class FileTypeFactory {
    public static FileType changeType(String oldType, String newType){
        FileType fileType = null;
        if ((".docx".equals(oldType) && ".pdf".equals(newType))
                || (".doc".equals(oldType) && ".pdf".equals(newType))
        ) {
            fileType = new WordToPDF();
        }
        else if ((".pdf".equals(oldType))) {
            fileType = new PDFToOther();
        }
        else {
            System.out.println(oldType +"类型转换尚未开发!!!");
        }
        return fileType;
    }
}

  哈哈,这样我们的文件格式转换工厂的简单小程序就写好了,最后一步就是编写我们的测试类。在src下,创建一个Test测试类,来试试我们刚刚写好的小程序究竟能不能进行格式转换。

import com.YuGong.factory.FileTypeFactory;
import com.YuGong.type.FileType;

/**
 * 文件类型转换的测试类
 * 作者:Cool_foolisher
 * 开始日期:2023-3-24
 * 结束日期:2023-3-24
 */
public class Test {
    public static void main(String[] args) {
        String oldType; // 转换前类型
        String newType; // 转换后类型

        /*
            Word转PDF的使用例子
         */
        oldType = ".docx";
        newType = ".pdf";
        FileType wordToPDF = FileTypeFactory.changeType(oldType, newType);
        wordToPDF.oldFile = "C:\\Users\\YuGong\\Desktop\\test.docx";
        wordToPDF.newFile = "C:\\Users\\YuGong\\Desktop";
        wordToPDF.userType = newType;
        wordToPDF.typeChange(wordToPDF.oldFile, wordToPDF.newFile);

        /*
            PDF转Word的使用例子
         */
        oldType = ".pdf";
        newType = ".docx";
        FileType pdfToOther = FileTypeFactory.changeType(oldType, newType);
        pdfToOther.oldFile = "C:\\Users\\YuGong\\Desktop\\test.pdf";
        pdfToOther.newFile = "C:\\Users\\YuGong\\Desktop";
        pdfToOther.userType = newType;
        pdfToOther.typeChange(pdfToOther.oldFile, pdfToOther.newFile);
    }
}

  测试文件可以用自己的文件哦!!!

五、结束语

  到这里,大家可能会有一个疑问,这个项目明明引了这么多jar包,为什么却仅仅只能Word转PDF、PDF转其他(其他包括:Word、PPT、Excel)呢?原因很简单,其他类型文件之间的转换代码我没有写,😂😂😂~~~聪明的你,我相信,看到这里也一定可以自己去完善这个小程序了。给大家一点小提示,其实使用静态工厂模式来写项目时,我们在增加新功能的时候,不需要去改动原来的代码,只需要新建一个类即可,这也就满足我们面向对象设计原则的开闭原则,即:对扩展开放,对修改关闭。同时我们每一个具体类(如:PDFToOther)仅仅只实现一个功能,这也满足了单一职责原则。通过使用这些原则可以大大提高我们的软件结构的设计水平。
  大家对于用静态工厂模式来写代码还有疑问,可以访问我的仓库,在认真的看一看!!!
  如果觉得我的这篇文章对您有帮助,欢迎大家给我点赞,对于静态工厂模式任有疑问的话,欢迎大家在评论留言!!!本人也是刚刚学习编程的小菜鸟,文章如有写的不对的地方,也欢迎大佬的指正!!!

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

学徒钝子生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值