探索设计模式的魅力:抽象工厂模式的艺术

news2024/11/18 11:20:48

抽象工厂模式(Abstract Factory Pattern)是一种创建型设计模式,用于在不指定具体类的情况下创建一系列相关或相互依赖的对象。它提供了一个接口,用于创建一系列“家族”相关依赖对象,而无需指定它们的具体类。

        

主要参与者:

  1. 抽象工厂(Abstract Factory):提供一个接口,用于创建一些相关或相互依赖的对象家族,而不需要指定它们具体的类。
  2. 具体工厂(Concrete Factory):实现抽象工厂的操作以生产具体的产品对象。
  3. 抽象产品(Abstract Product):为一系列产品对象声明一个接口。
  4. 具体产品(Concrete Product):抽象产品的子类,定义用于生产的具体产品对象。
  5. 客户(Client):仅使用由抽象工厂和抽象产品类声明的接口。

实现步骤:

  1. 定义抽象产品,确定产品家族中的不同产品。
  2. 创建抽象工厂类,定义创建抽象产品的接口。
  3. 实现具体工厂类,每个工厂类负责创建不同的产品变体。
  4. 客户端代码通过抽象工厂和抽象产品类接口与工厂和产品交互。

优势:

  • 隔离具体类的生成:客户端不需要知道它所使用的对象的具体类,只需要关心所使用对象的接口。
  • 易于交换产品系列:因为具体的工厂类都派生自同一个抽象类,可以很容易地更换使用的工厂类来切换整个产品系列。
  • 增强一致性:产品在一系列中一致地创建,这保证了客户端始终只使用同一产品系列中的对象。

缺点:

  • 难以支持新种类的产品:如果需要添加额外的产品到系列中,抽象工厂和所有具体工厂类都需要改变,这违反了开闭原则。

探索设计模式的魅力:简单工厂模式-CSDN博客文章浏览阅读2.5k次,点赞58次,收藏46次。实现简单工厂的难点就在于 “如何选择” 实现,前面便子中传递参数的方法, 那都是静态的参数,还可以实现成为动态的参数。客户端通过简单工厂创建 了一个实现接口的对象,然后面向接口编程,从客户端来看,它根本不知道具体的实现是什么,也不知道是如何实现的,它只知道通过工厂获得了一个接口对象 , 然后通过这个接口来获取想要的功能。如果通过客户端的参数来选择具体的实现类,那么就必须让客户端能理解各个参数所代表的具体功能和含义,这样会增加客户端使用的难度,也部分暴露了内部实现,这种情况可以选用可配置的方式来实现。https://blog.csdn.net/danci_/article/details/135566105探索设计模式的魅力:工厂方法模式-CSDN博客文章浏览阅读2.5k次,点赞83次,收藏47次。工厂方法模式是一种创建型设计模式,它提供了一种创建对象的接口,但将具体实例化对象的工作推迟到子类中完成。这样做的目的是创建对象时不用依赖于具体的类,而是依赖于抽象,这提高了系统的灵活性和可扩展性。优点:降低耦合度、增加了系统的可扩展性 和 提高代码的可维护性;缺点:增加了代码的复杂性 和 需要更多的设计考虑。https://blog.csdn.net/danci_/article/details/135611783

目录

一、案例

1.1 示例代码

  1.1.1 简单工厂实现

  1.1.2 问题        

  1.1.3 抽象工厂实现

二、模式讲解

 2.1 功能

 2.2 抽象工厂模式的结构及说明

 2.3 示例代码程序结构图

 2.4 抽象工厂模式与简单工厂模式

 2.5 抽象工厂模式与工厂方法模式


一、案例

        场景:造一辆汽车(买零件来组装),汽车有很多的零组成,成百上千个零件相互依赖配合工作,比如发动机和变速箱。

        选择零件时,每个零件的品牌、规格 等如何才能选择到合适的搭配才能配合正常工作,也就是说汽车是一个整体,每个零件之间有关联的。

1.1 示例代码

        汽车零件有成百上升个,这里只举例发动机和变速箱。市面上有各种品牌的发动机和变速箱,同一品牌还有各种型等,这里举两个。

  1.1.1 简单工厂实现

         发动机接口:

public interface EngineApi {

    void run();
}

        变速箱接口:

public interface GearboxApi {

    void run();
}

        林肯发动机和林肯变速箱:

public class LinkenEngineApiImpl implements EngineApi {

    @Override
    public void run() {
        System.out.println("林肯发动机工作了");
    }
}

public class LinkenGearboxApiImpl implements GearboxApi {

    @Override
    public void run() {
        System.out.println("林肯变速箱工作了");
    }
}

        丰田发动机和丰田变速箱:

public class ToyotaEngineApiImpl implements EngineApi {

    @Override
    public void run() {
        System.out.println("丰田发动机工作了");
    }
}

public class ToyotaGearboxApiImpl implements GearboxApi {
    @Override
    public void run() {
        System.out.println("丰田变速箱工作了");
    }
}

        发动机工厂:

public class EngineFactory {
    public static EngineApi getEngineApi(int i) {
            if (i == 1) {
                return new LinkenEngineApiImpl();
            }
            return new ToyotaEngineApiImpl();
        }
}

        变速箱工厂 :

public class GearboxFactory {
    public static GearboxApi getGearbox(int i) {
        if (1 == i) {
            return new LinkenGearboxApiImpl();
        }
        return new ToyotaGearboxApiImpl();
    }
}

        汽车组装类:

public class CarEngineer {

    public void makeCar(int engineType, int gearboxType) {
        EngineApi engineApi = EngineFactory.getEngineApi(engineType);
        GearboxApi gearbox = GearboxFactory.getGearbox(gearboxType);
        engineApi.run();
        gearbox.run();
    }
}

        客户端:

public class CarClient {

    public static void main(String[] args) {
        CarEngineer carEngineer = new CarEngineer();
        carEngineer.makeCar(1, 1);
    }
}

        运行结果:

/Library/Java/JavaVirtualMachines/jdk1.8.0_311.jdk/...
林肯发动机工作了
林肯变速箱工作了

        修改客户端carEngineer.makeCar(1, 2); 运行结果:

/Library/Java/JavaVirtualMachines/jdk1.8.0_311.jdk/...
林肯发动机工作了
丰田变速箱工作了

  1.1.2 问题        

        修改了产数之后,组装的汽车使用了林肯的发动机,而变速箱是丰田的,此时发动机与变速箱不是一个品牌,如果发动机与变速箱不匹配无法正常配合工作,那么组装的这个汽车就等于废了(这里假设只有同品牌的零部件才能正常配合动作)。

        显然发动机与变速箱是需要互相匹配,强依赖关系。就是选了这个发动机就必须选定某个变速箱。抽象工厂来解决这个问题。

        

  1.1.3 抽象工厂实现

抽象工厂模式:提供一个创建一系列相关或相互依赖对象的接又,而无需指定它们具体的类。

        解决1.1.2问题是要创建一序列有相互依赖关联和相互约束的产品——抽象工厂模式。

        代码改造

        发动机接口和变速箱接口不变:

public interface EngineApi {
    void run();
}
public interface GearboxApi {

    void run();
}

        发动机和变速箱的实现也不变:

public class LinkenEngineApiImpl implements EngineApi {
    @Override
    public void run() {
        System.out.println("林肯发动机工作了");
    }
}

public class LinkenGearboxApiImpl implements GearboxApi {
    @Override
    public void run() {
        System.out.println("林肯变速箱工作了");
    }
}

public class ToyotaEngineApiImpl implements EngineApi {
    @Override
    public void run() {
        System.out.println("丰田发动机工作了");
    }
}

public class ToyotaGearboxApiImpl implements GearboxApi {
    @Override
    public void run() {
        System.out.println("丰田变速箱工作了");
    }
}

        添加抽象工厂:(工厂抽象出来)

public interface AbstractFactory {

    /**
     * 创建发动机 <br/>
     */
    EngineApi createLinken();
    /**
     * 创建变速箱 <br/>
     */
    GearboxApi createGearbox();
}

        发动机工厂修改为林肯工厂,并实现抽象工厂:(//注释部分为简单工厂代码)

public class LinkenFactory implements AbstractFactory {
//public class EngineFactory {

    /**
     * 生产林肯发动机
     */
    @Override
    public EngineApi createLinken() {
        return new LinkenEngineApiImpl();
    }
    /**
     * 生产林肯发变速箱
     */
    @Override
    public GearboxApi createGearbox() {
        return new LinkenGearboxApiImpl();
    }

    //public static EngineApi getEngineApi(int i) {
    //    if (i == 1) {
    //        return new LinkenEngineApiImpl();
    //    }
    //
    //    return new ToyotaEngineApiImpl();
    //}
}

        变速箱工厂修改为丰田工厂,并实现抽象工厂:(//注释部分为简单工厂代码)

public class ToyotaFactory implements AbstractFactory {
//public class GearboxFactory {

    /**
     * 生产丰田发动机
     */
    @Override
    public EngineApi createLinken() {
        return new ToyotaEngineApiImpl();
    }
    /**
     * 生产丰田变事箱
     */
    @Override
    public GearboxApi createGearbox() {
        return new ToyotaGearboxApiImpl();
    }
    //public static GearboxApi getGearbox(int i) {
    //    if (1 == i) {
    //        return new LinkenGearboxApiImpl();
    //    }
    //
    //    return new ToyotaGearboxApiImpl();
    //}
}

         汽车组装类有修改:(//注释部分为简单工厂代码)

public class CarEngineer {
    /**
     * 接收选择好的哪一个序列产品工厂
     * @param factory
     */
    public void makeCar(AbstractFactory factory) {
        EngineApi engineApi = factory.createLinken();
        GearboxApi gearbox = factory.createGearbox();
        engineApi.run();
        gearbox.run();
    }
    //public void makeCar(int engineType, int gearboxType) {
    //    EngineApi engineApi = EngineFactory.getEngineApi(engineType);
    //    GearboxApi gearbox = GearboxFactory.getGearbox(gearboxType);
    //    engineApi.run();
    //    gearbox.run();
    //}
}

        客户端:(//注释部分为简单工厂代码)

public class CarClient {
    public static void main(String[] args) {
        //CarEngineer carEngineer = new CarEngineer();
        //carEngineer.makeCar(1, 2);

        CarEngineer carEngineer = new CarEngineer();
        // 传入选中的哪种产品工厂
        carEngineer.makeCar(new LinkenFactory());
    }
}

        运行结果:

/Library/Java/JavaVirtualMachines/jdk1.8.0_311.jdk/...
林肯发动机工作了
林肯变速箱工作了

        修改选中的产品工厂carEngineer.makeCar(new ToyotaFactory()) ,运行结果:

/Library/Java/JavaVirtualMachines/jdk1.8.0_311.jdk/...
丰田发动机工作了
丰田变速箱工作了

        这个抽象工厂相当于选择一套方案,方案确定好,里面的零件也就确定好了。不用一个零件一个零件的选择以免选择出错

        

二、模式讲解

 2.1 功能

功能: 为一系列相关对象或相互依赖的对象创建一个接口。

接口内的方法是一系列相互依赖和约束的方法。

        

 2.2 抽象工厂模式的结构及说明

  • AbstractFactory:抽象工厂,定义创建一系列产品对象的操作接口。

  • FactoryA:具体的工厂,实现抽象工厂定义的方法,具体实现一系列产品对象的创建。

  • AbstractProduct:定义类产品对象的接口。

  • ProductA:具体的产品实现对象,通常在具体工厂里面,会选择具体的产品实现对象,来创建符合抽象工厂定义的方法返回的产品类型的对象。

  • Client:客户端,主要使用抽象工厂来获取一系列所需要的产品对象,然后面向这些产品对象的接口编程,以实现需要的功能。

        

 2.3 示例代码程序结构图

        抽象工厂模式主要用于以下几个方面的应用场景中:

  1. 需要创建一系列相互依赖的对象:当一组对象之间存在依赖关系,并且需要保证这些对象是兼容的,抽象工厂模式可以用来创建这些对象的族群。

  2. 希望实现多个产品族的变化:抽象工厂模式允许你定义多个工厂类,每个工厂类可以创建不同的产品族,从而可以实现对产品族的变化。

  3. 需要切换产品组合:通过使用抽象工厂模式,可以很方便地切换不同的产品组合,而无需修改已有的客户端代码。

        优势方面,抽象工厂模式具有以下几个优势:

  1. 封装了对象的创建过程:客户端只需关注抽象工厂类和抽象产品类,而无需关心具体的创建细节,将对象创建的过程封装在工厂类中,提供了更高的封装性和抽象性。

  2. 符合开闭原则:抽象工厂模式对于新增新的产品族非常方便,只需创建对应的新的工厂类即可,并且不需要修改已有的代码,符合开闭原则。

  3. 保持产品族的一致性:通过抽象工厂模式创建的产品族中的产品具有一定的约束关系,保证了产品的一致性,避免了不兼容的产品组合。

        

 2.4 抽象工厂模式与简单工厂模式

        抽象工厂模式和简单工厂模式是两种常见的设计模式,它们在对象的创建和管理上有一些不同之处。

  1. 目的和应用场景:

  • 简单工厂模式(Simple Factory Pattern)旨在根据给定的参数来创建单一类型的对象实例。它适用于需要根据条件创建不同类型的对象的情况,但它并没有分离对象的创建和使用,违反了单一职责原则。
  • 抽象工厂模式(Abstract Factory Pattern)旨在创建一系列相关或相互依赖的对象,而无需显式指定其具体类。它适用于需要创建一组相关的产品对象,并且需要确保这些产品是兼容的情况。

  2. 结构与实现:

  • 简单工厂模式通常由一个工厂类通过静态方法来创建对象,客户端通过调用工厂类的方法并传入相应的参数来获得所需的对象。
  • 抽象工厂模式通常由一组抽象工厂和一组具体工厂类组成,每个具体工厂负责创建一组特定的产品。

  3. 灵活性与扩展性:

  • 简单工厂模式的灵活性相对较低,因为一旦需要添加新类型的产品,通常需要修改工厂类的静态方法。
  • 抽象工厂模式支持产品族的概念,可以非常容易地添加新的产品族,只需要新增对应的具体工厂类即可,而不需要修改客户端代码。

总的来说,简单工厂模式适用于需要创建单一类型的对象,并且可以根据条件动态地创建不同类型的对象。而抽象工厂模式适用于创建一系列相关或相互依赖的对象,并且需要确保这些对象是兼容的情况。在实际应用中,根据具体的需求和设计目标来选择合适的设计模式。

        

 2.5 抽象工厂模式与工厂方法模式

        抽象工厂模式(Abstract Factory Pattern)和工厂方法模式(Factory Method Pattern)虽然同属于创建型设计模式,旨在解耦对象的创建和使用,但两者在目的、实现方式及应用场景上存在明显区别:

  1. 目的:

  • 工厂方法模式的目的是允许一个类在不知道将要创建的对象的具体类型的情况下,推迟其实例化到子类中进行。
  • 抽象工厂模式的目的是创建一系列相关或者相互依赖的对象,而不需要指定它们具体的类。

  2. 实现方式:

  • 工厂方法模式定义了一个用于创建对象的接口,但由子类决定实例化哪一个类。工厂方法让类的实例化推迟到子类中进行。
  • 抽象工厂模式提供了一个创建一系列相关或互相依赖对象的接口,而不需要指定它们具体的类。它通常包含多个工厂方法来创建一系列不同的产品。

  3. 应用场景:

  • 工厂方法模式主要用于单一产品的创建情形,即客户端只需要一个产品,而具体哪个产品则由具体工厂类在运行时决定。
  • 抽象工厂模式适用于创建一组产品(产品族),这些产品设计成合作使用的,客户端需要多个产品对象,这些对象要按照一定的方式配合工作。

  4. 结构复杂度:

  • 工厂方法模式结构相对简单,每个具体工厂类只需要负责一个产品的创建。
  • 抽象工厂模式结构相对复杂,一个工厂类需要负责多个产品对象的创建,这些对象通常属于不同的类系列。

  5. 扩展难度:

  • 工厂方法模式较容易扩展,引入新的产品类型只需要添加相应的具体工厂类和产品类即可。
  • 抽象工厂模式相对难以扩展,如果需要添加新的产品系列,需修改抽象工厂的接口以及所有的实现类,这会违反开闭原则。

总之,工厂方法模式用于创建一个产品,而抽象工厂模式用于创建多个相互依赖或相互关联的产品族。在选择使用哪一个模式时,需要根据具体场景和设计需求去判断。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux安装ossutil工具且在Jenkins中执行shell脚本下载文件

测试中遇到想通过Jenkins下载OSS桶上的文件&#xff0c;要先在linux上安装ossutil工具&#xff0c;记录安装过程如下&#xff1a; 一、下载安装ossutil&#xff0c;使用命令 1.下载&#xff1a;wget https://gosspublic.alicdn.com/ossutil/1.7.13/ossutil64 2.一定要赋权限…

大创项目推荐 深度学习的视频多目标跟踪实现

文章目录 1 前言2 先上成果3 多目标跟踪的两种方法3.1 方法13.2 方法2 4 Tracking By Detecting的跟踪过程4.1 存在的问题4.2 基于轨迹预测的跟踪方式 5 训练代码6 最后 1 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 基于深度学习的视频多目标跟踪实现 …

服务器数据恢复—OceanStor存储raid5热备盘同步数据失败的数据恢复案例

服务器数据恢复环境&#xff1a; 华为OceanStor某型号存储&#xff0c;存储内有一组由24块硬盘组建的raid5阵列&#xff0c;配置1块热备盘。 服务器故障&#xff1a; 该存储raid5阵列中有一块硬盘离线&#xff0c;热备盘自动激活并开始同步数据&#xff0c;在热备盘同步数据的…

C400/10/1/1/1/00嵌入式系统中的模块动态加载技术

基于模块化设计的嵌入式软件测试方法 "... 进行分析。 关键词&#xff1a;模块化设计 嵌入式软件 软件测试 ... 相对较小的模块。为了减少模块与模块之间的关联性&#xff0c;模块之间的逻辑结构 ... 执行后发生错误&#xff0c;则由模块&#xff22;和模块&…

【Alibaba工具型技术系列】「EasyExcel技术专题」摒除OOM!让你的Excel操作变得更加优雅和安全

摒除OOM&#xff01;让你的Excel操作变得更加优雅和安全 前提概要存在隐患问题解决方案更优秀的选择 EasyExcel的介绍说明技术原理对比POIEasyExcel技术原理图节省内存的开销 Maven仓库依赖基础API介绍&#xff08;参考官方文档&#xff09;实战案例读取Excel实现Demo数据模型D…

网络性能评估工具Iperf

一、网络性能评估工具Iperf Iperf是一款基于TCP/IP和UDP/IP的网络性能测试工具&#xff0c;它可以用来测量网络带宽和网络质量&#xff0c;还可以提供网络延迟抖动、数据包丢失率、***传输单元等统计信息。网络管理员可以根据这些信息了解并判断网络性能问题&#xff0c;从而定…

Statistics with Python: Week2 Nhanes Assignment

这门课不知出于什么原因比较小众&#xff0c;如果有人在做&#xff0c;在week2的assignment中出现问题&#xff0c;希望我的回答可以帮到你。 这个作业的目的就是抓取nhanes&#xff08;美国健康与营养检测&#xff09;2015-2016的数据&#xff0c;然后计算平均数/中位数/方差…

如何利用SD-WAN升级企业网络,混合组网稳定性更高?

随着企业信息化的升级&#xff0c;传统网络架构已经无法满足企业复杂的、多样化的组网互联需求。 企业多样化的组网需求包括&#xff1a; 一是需要将各办公点互联起来进行数据传输、资源共享&#xff1b; 二是视频会议、ERP、OA、邮箱系统、云服务应用程序等访问需求&#xff…

71.网游逆向分析与插件开发-角色数据的获取-修复角色名与等级显示问题

内容参考于&#xff1a;易道云信息技术研究院VIP课 上一个内容&#xff1a;自动化助手UI显示角色数据-CSDN博客 码云地址&#xff08;ui显示角色数据 分支&#xff09;&#xff1a;https://gitee.com/dye_your_fingers/sro_-ex.git 码云版本号&#xff1a;0049452c079867779…

ChatGLM3报错:No chat template is defined for this tokenizer

使用官方提供的脚本创建ChatGLM3的DEMO&#xff1a; cd basic_demo python web_demo_gradio.py 出现效果异常问题&#xff1a; conversation [{role: user, content: 你好}, {role: assistant, content: 你好&#xff0c;有什么我可以帮助你的吗&#xff1f;\n\n<|im_end|…

数字时代的大对决

数字时代如今正酝酿着一场大对决&#xff0c;浏览器、艺术品、音乐平台和社交通信的巅峰之战正在发生。Brave、Yuga Labs、Audius和Discord分别对标着Chrome、Disney、Spotify和WhatsApp&#xff0c;这场数字时代的较量不仅涉及浏览器、艺术品、音乐平台和社交通信的竞争&#…

基于YOLOv8深度学习的100种中草药智能识别系统【python源码+Pyqt5界面+数据集+训练代码】目标检测、深度学习实战

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 ✌更多学习资源&#xff0c;可关注公-仲-hao:【阿旭算法与机器学习】&#xff0c;共同学习交流~ &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推…

uniapp实现微信小程序富文本之mp-html插件详解

uniapp实现微信小程序富文本之mp-html插件 1 文章背景1.1 正则表达式1.2 mp-html插件1.3 uniapp 2 过程详解2.1 下载mp-html插件2.2 项目中引入mp-html2.3 引入正则规范图片自适应2.4 效果展示 3 全部代码 1 文章背景 1.1 正则表达式 正则表达式&#xff0c;又称规则表达式,&…

游泳耳机怎么选?国产十大游泳耳机排行榜TOP4品牌

随着人们对健康生活的追求和对多样化运动方式的探索&#xff0c;游泳作为一项完美的全身运动逐渐受到更多人的喜爱。在游泳过程中&#xff0c;佩戴一副优质的游泳耳机&#xff0c;不仅可以享受音乐的陪伴&#xff0c;还能让您更好地沉浸在水下世界中。本文将为大家推荐国产十大…

微信小程序 image bindload 事件不触发,图片加载不出来

问题&#xff1a; 当小程序图片页面反复跳转时&#xff0c;或者微信打开小程序页面之后&#xff0c;处于后台运行。 图片加载不出来&#xff0c;我图片加载是通过bindload事件不判断是否下载完成再显示。但是现在bindload不触发&#xff0c;一直显示加载层。 分析&#xff1…

查看神经网络中间层特征矩阵及卷积核参数

可视化feature maps以及kernel weights&#xff0c;使用alexnet模型进行演示。 1. 查看中间层特征矩阵 alexnet模型&#xff0c;修改了向前传播 import torch from torch import nn from torch.nn import functional as F# 对花图像数据进行分类 class AlexNet(nn.Module):d…

Elasticsearch8 集群搭建(二)配置篇:(3)安全配置

此篇记录Elasticsearch 8.x传输层的安全配置。 传输层节点间&#xff1a; 如果集群有多个节点&#xff0c;必须在节点间配置TLS。生产模式下&#xff0c;如果不启用TLS&#xff0c;集群将无法启动。 图片来源&#xff1a;Set up basic security for the Elastic Stack | Elas…

2018年认证杯SPSSPRO杯数学建模D题(第二阶段)投篮的最佳出手点全过程文档及程序

2018年认证杯SPSSPRO杯数学建模 D题 投篮的最佳出手点 原题再现&#xff1a; 影响投篮命中率的因素不仅仅有出手角度、球感、出手速度&#xff0c;还有出手点的选择。规范的投篮动作包含两膝微屈、重心落在两脚掌上、下肢蹬地发力、身体随之向前上方伸展、同时抬肘向投篮方向…

vue2使用mapbox

1.安装mapbox 这里安装的是"mapbox-gl": "^3.0.1", npm install --save mapbox-gl 安装mapbox 2.安装worker-loader npm install worker-loader --save-dev 安装worker-loader 配置vue.config.js const { defineConfig } require(vue/cli-servic…

MFC 序列化机制

目录 文件操作相关类 序列化机制相关类 序列化机制使用 序列化机制执行过程 序列化类对象 文件操作相关类 CFile&#xff1a;文件操作类&#xff0c;封装了关于文件读写等操作&#xff0c;常见的方法&#xff1a; CFile::Open&#xff1a;打开或者创建文件CFile::Write/…