设计模式之结构型模式(适配器、桥接、组合、享元、装饰者、外观、代理)

文章目录

    • 一、结构型设计模式
    • 二、适配器模式
    • 三、桥接模式
    • 四、组合模式
    • 五、享元模式
    • 六、装饰者模式
    • 七、外观模式
    • 八、代理设计模式

一、结构型设计模式

这篇文章我们来讲解下结构型设计模式,结构型设计模式,主要处理类或对象的组合关系,为如何设计类以形成更大的结构提供指南。

结构型设计模式包括:适配器模式(Adapter Pattern)、桥接模式(Bridge Pattern)、组合模式(Composite Pattern)、装饰器模式(Decorator Pattern)、外观模式(Facade Pattern)、享元模式(Flyweight Pattern)、代理模式(Proxy Pattern)

二、适配器模式

适配器模式(Adapter Pattern)是作为两个不兼容的接口之间的桥梁。它结合了两个独立接口的功能。
优点:

  1. 可以让任何两个没有关联的类一起运行。
  2. 提高了类的复用。
  3. 增加了类的透明度。
  4. 灵活性好。

这种模式涉及到一个单一的类,该类负责加入独立的或不兼容的接口功能。举个真实的例子,在视频播放器中,假设视频播放器只能播放MP4格式的视频,那现在又有个VLC格式的视频,就不能播放了,那要如何解决这个问题?如果我们做个转换器,将VLC格式的视频转换为MP4格式的视频不就可以播放了吗,那这个转换器我们就可以采用适配器设计模式来设计。

下面使用程序演示下上面的例子:

  1. 定义视频接口
public interface VideoInterFace {
    String getVideoPath();
}
  1. 定时Mp4格式视频实例
public class Mp4Video implements VideoInterFace {
    @Override
    public String getVideoPath() {
        return "Mp4视频的路径";
    }
}
  1. 定义VLC格式视频实例
public class VlcVideo implements VideoInterFace{
    @Override
    public String getVideoPath() {
        return "Vlc视频的路径";
    }
}
  1. 定义播放器,只接口Mp4格式的视频
public class Player {
    private Mp4Video video;

    public Player(Mp4Video video) {
        this.video = video;
    }

    public void play() {
        System.out.println(StringFormatter.concat("播放视频视频地址:", video.getVideoPath()).getValue());
    }
}
  1. 需要播放VLC格式的视频,定义Mp4的适配器,并接收VLC格式视频,进行转码。
public class Mp4Adapter extends Mp4Video {

    private VlcVideo vlcVideo;

    public Mp4Adapter(VlcVideo vlcVideo) {
        this.vlcVideo = vlcVideo;
    }

    @Override
    public String getVideoPath() {
        System.out.println(StringFormatter.concat("开始格式转换,vlc地址:", vlcVideo.getVideoPath()).getValue());
        return "转换后的Mp4路径!";
    }
}
  1. 测试
public class demo {
    public static void main(String[] args) {
        Player player = new Player(new Mp4Video());
        player.play();

        VlcVideo vlcVideo = new VlcVideo();
        Player player1 = new Player(new Mp4Adapter(vlcVideo));
        player1.play();
    }
}

在这里插入图片描述

从上面的例子可以看出,需要播放VLC格式,就需要写一个目标适配器,这里是Mp4适配器,并继承Mp4,使之有Mp4的特性,并在内部做相应的转换即可,提高了系统的可扩展性。

三、桥接模式

桥接模式(Bridge)是用于把抽象化与实现化解耦,使得二者可以独立变化。它通过提供抽象化和实现化之间的桥接结构,来实现二者的解耦
这种模式涉及到一个作为桥接的接口,使得实体类的功能独立于接口实现类。这两种类型的类可被结构化改变而互不影响。
优点:

  1. 抽象和实现的分离。
  2. 优秀的扩展能力。
  3. 实现细节对客户透明。

举个例子:绘画不同颜色的各种图像,画不同的形状和涂颜色,便是两个不同的功能,但两者又相互联系,在画完形状后需要涂颜色,但颜色和形状有使多种多样的,此时就可以采用桥接设计模式,将两者的抽象化与实现化解耦,形状和颜色可以独立变化

下面使用程序演示下上面的例子:

  1. 定义颜色的接口
public interface ColorApi {
   public void drawCircle();
}
  1. 定义不同颜色的实现,这里采用红色和绿色
public class ReqColor implements ColorApi {
    @Override
    public void drawCircle() {
        System.out.println("开始涂红色!");
    }
}
public class GreenColor implements ColorApi {
   @Override
   public void drawCircle() {
      System.out.println("开始涂绿色!");
   }
}
  1. 定义形状的接口
public interface ShapeApi {
    //画形状
    void draw();
    //画形状并涂颜色
    void drawShapeAndsColor();
}
  1. 定义形状的抽象模板,将共性的操作定义到抽象中
public abstract class ShapeAbstract implements ShapeApi {

    public ColorApi colorApi;

    public ShapeAbstract(ColorApi colorApi) {
        this.colorApi = colorApi;
    }

    @Override
    public void drawShapeAndsColor() {
        draw();
        colorApi.drawCircle();
    }
}
  1. 定义圆形的实例
public class Circle extends ShapeAbstract {

   public Circle(ColorApi colorApi) {
      super(colorApi);
   }
 
   @Override
   public void draw() {
      System.out.println("开始画圆形!");
   }
}
  1. 定义矩形的实例
public class Rectangle extends ShapeAbstract {

    public Rectangle(ColorApi colorApi) {
        super(colorApi);
    }

    @Override
    public void draw() {
        System.out.println("开始画矩形");
    }
}
  1. 演示
public class demo {
   public static void main(String[] args) {
      ShapeApi shapeReq = new Circle(new ReqColor());
      shapeReq.drawShapeAndsColor();

      ShapeApi shapeGreen = new Circle(new GreenColor());
      shapeGreen.drawShapeAndsColor();

      ShapeApi rectangle = new Rectangle(new GreenColor());
      rectangle.drawShapeAndsColor();
   }
}

在这里插入图片描述

上面可以看出,可以灵活的定义形状和颜色的组合,并且他们两个都可以独立变化,添加新的形状只需,建立新的类并实现形状接口,添加颜色也是如此,极大的提高的系统的可扩展性和可维护型。

四、组合模式

组合模式(Composite Pattern),又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象
组合模式依据树形结构来组合对象,用来表示部分以及整体层次。它创建了对象组的树形结构。
优点:

  1. 高层模块调用简单。
  2. 节点自由增加。

缺点:
在使用组合模式时,其叶子和树枝的声明都是实现类,而不是接口,违反了依赖倒置原则。

举个例子:一个公司,从上到下分为,公司、部门、小组等,他们整个在一起才能称为一个完整的公司,要表示做个公司的结构,就可以采用组合设计模式。

下面使用程序演示下上面的例子:

  1. 定义属性类,用来表示不同层级的对象
@Data
public class Property {
   private String name;
   //下一层的子集
   private List<Property> next;

   public Property(String name) {
      this.name = name;
      next = new ArrayList<Property>();
   }
 
   public void add(Property e) {
      next.add(e);
   }
 
   public void remove(Property e) {
      next.remove(e);
   }
 
   public List<Property> getSubordinates(){
     return next;
   }
}
  1. 使用演示
public class demo {
   public static void main(String[] args) {
      Property company = new Property("公司");
      Property department = new Property("部门");
      Property group = new Property("小组");

      company.add(department);
      department.add(group);

      System.out.println(company);
   }
}

在这里插入图片描述

上面就演示了一个公司的组合,通过company对象就可以获得整个公司的各个部分的对象。组合设计模式主要适合于整体部分的场景。

五、享元模式

享元模式(Flyweight Pattern)主要用于减少创建对象的数量,以减少内存占用和提高性能。它提供了减少对象数量从而改善应用所需的对象结构的方式。
享元模式尝试重用现有的同类对象,如果未找到匹配的对象,则创建新对象。他的优点是大大减少对象的创建,降低系统的内存,使效率提高,但也有可能造成内存的浪费。比如Spring的采用容器的方式存储bean,使用时从容器中获取。

还是拿画不同颜色形状的例子演示下享元设计模式的使用:

  1. 定义形状的接口
public interface Shape {
   void draw();
}
  1. 定义圆形的实现,并接收一个颜色值:
public class Circle implements Shape {

    private String color;

    public Circle(String color) {
        this.color = color;
    }

    @Override
    public void draw() {
        System.out.println(StringFormatter.concat("开始画 ", color, " 色的圆 ").getValue());
    }
}
  1. 定义形状对象获取工厂,根据颜色值将对象存储到HashMap中,后再根据颜色值取对象,达到复用的效果。
public class ShapeFactory {

    private static final HashMap<String, Shape> circleMap = new HashMap<>();

    public static Shape getCircle(String color) {
        if (!circleMap.containsKey(color)) {
            System.out.println(StringFormatter.concat(">> 创建", color, "颜色的圆 ").getValue());
            circleMap.put(color, new Circle(color));
        }
        return circleMap.get(color);
    }
}
  1. 使用
public class demo {
    private static final String colors[] =
            {"Red", "Green", "Blue", "White", "Black"};

    public static void main(String[] args) {

        for (int i = 0; i < 20; ++i) {
            Shape circle = ShapeFactory.getCircle(getRandomColor());
            circle.draw();
        }
    }

    private static String getRandomColor() {
        return colors[(int) (Math.random() * colors.length)];
    }
}

在这里插入图片描述

上面可以看出,享元设计模式可以大大减少对象的创建,但也有可以造成内存的浪费,比如某个对象的使用频率非常低,如果一直存在内存中就有点浪费空间了。

六、装饰者模式

装饰者模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。它是作为现有的类的一个包装
装饰类和被装饰类可以独立发展,不会相互耦合,装饰者模式是继承的一个替代模式,装饰者模式可以动态扩展一个实现类的功能。

举个例子:还是绘画不同的形状的例子,加入系统中有画各种形状的功能,但随着功能后期的演化,需要画出带有边框的各种形状,那么此时就可以采用装饰者设计模式来做增强。

下面使用程序演示下上面的例子:

  1. 定义形状接口
public interface Shape {
   void draw();
}
  1. 定义圆形的实现
public class Circle implements Shape {
 
   @Override
   public void draw() {
      System.out.println("开始画圆形!");
   }
}
  1. 定义矩形的实现
public class Rectangle implements Shape {
 
   @Override
   public void draw() {
      System.out.println("开始画矩形!");
   }
}
  1. 定义装饰器的抽象模板
public abstract class ShapeDecorator implements Shape {
   protected Shape decoratedShape;
 
   public ShapeDecorator(Shape decoratedShape){
      this.decoratedShape = decoratedShape;
   }
 
   @Override
   public void draw(){
      decoratedShape.draw();
   }  
}
  1. 定义具体的边框装饰器
public class BorderShapeDecorator extends ShapeDecorator {
 
   public BorderShapeDecorator(Shape decoratedShape) {
      super(decoratedShape);     
   }
 
   @Override
   public void draw() {
      decoratedShape.draw();         
      setRedBorder(decoratedShape);
   }
 
   private void setRedBorder(Shape decoratedShape){
      System.out.println("画边框!");
   }
}
  1. 演示
public class demo {
   public static void main(String[] args) {
      Shape circle = new Circle();
      circle.draw();

      Shape shape = new BorderShapeDecorator(new Circle());
      shape.draw();

      Shape shape1 = new BorderShapeDecorator(new Rectangle());
      shape1.draw();
   }
}

在这里插入图片描述

上面可以看出再不改变原先类的基础上,做了画边框的效果,对原有做增强,使用装饰者设计模式,可以大大提高系统的可扩展性。

七、外观模式

外观模式(Facade Pattern)隐藏系统的复杂性,并向客户端提供了一个客户端可以访问系统的接口。它向现有的系统添加一个接口,来隐藏系统的复杂性。
这种模式涉及到一个单一的类,该类提供了客户端请求的简化方法和对现有系统类方法的委托调用。
它的优点是可以减少系统相互依赖、提高灵活性、提高了安全性。但是它不符合开闭原则,如果要改东西很麻烦,继承重写都不合适。

举个例子:画各种图形的例子,比如要画圆形、矩形、三角形,每画一种图像都要拿到对应的抽象,并调用绘制方法,如果要画的形状过多,这么多的抽象就不好管理了,而如果使用外观设计模式,提供一个统一的抽象,在这个抽象中就可以完成上面不同的绘制,这样就方便了我们的管理。

下面使用程序演示下上面的例子:

  1. 定义形状的接口
public interface Shape {
   void draw();
}
  1. 定义圆形的实例
public class Circle implements Shape {
    @Override
    public void draw() {
        System.out.println("开始画圆!");
    }
}
  1. 定义矩形的实例
public class Rectangle implements Shape {
 
   @Override
   public void draw() {
      System.out.println("开始画矩形!");
   }
}
  1. 定义三角形的实例
public class Triangle implements Shape {
 
   @Override
   public void draw() {
      System.out.println("开始画三角形!");
   }
}
  1. 定义一个外观类,并调用上面的功能
public class ShapeFacade {
   private Shape circle;
   private Shape rectangle;
   private Shape square;
 
   public ShapeFacade() {
      circle = new Circle();
      rectangle = new Rectangle();
      square = new Triangle();
   }
 
   public void drawCircle(){
      circle.draw();
   }
   public void drawRectangle(){
      rectangle.draw();
   }
   public void drawSquare(){
      square.draw();
   }
}
  1. 演示
public class demo {
   public static void main(String[] args) {
      ShapeFacade shapeFacade = new ShapeFacade();
      shapeFacade.drawCircle();
      shapeFacade.drawRectangle();
      shapeFacade.drawSquare();
   }
}

在这里插入图片描述
外观设计模式还是比较容易理解的,就是把多个功能统一整个到一个对象中,由这个对象再去调用具体的类和方法。

八、代理设计模式

代理设计模式通过代理控制对象的访问,可以详细访问某个对象的方法,在这个方法调用处理,或调用后处理。既(AOP微实现) 。

代理有分静态代理动态代理

  • 静态代理:在程序运行前就已经存在代理类的字节码文件,代理类和委托类的关系在运行前就确定了。
  • 动态代理:是在使用时,动态的生成代理对象,他是在内存中构建代理对象的。

举个例子,在做数据库操作时,一般我们都会在事物中做SQL的操作,那就需要在操作前开启事物,操作后如果成功就需要提交事物,如果代用代理设计模式,就可以将事物开启提交逻辑放在代理类中,被代理的类,只需要关注业务逻辑即可。

下面以支付和事物为例演示下代理模式

采用静态代理,实现上面例子:

  1. 定义支付接口
public interface PayInterFace {
    void pay();
}
  1. 定义微信支付实现
public class WxPay implements PayInterFace {
    @Override
    public void pay() {
        System.out.println("支付中...");
    }
}
  1. 定义支付的代理类
public class PayProxy implements PayInterFace {
    private WxPay pay;

    public PayProxy(WxPay pay) {
        this.pay = pay;
    }

    @Override
    public void pay() {
        System.out.println("事物开始!");
        pay.pay();
        System.out.println("提交事物!");
    }
}
  1. 演示
public class demo {
    public static void main(String[] args) {
        PayInterFace pay = new PayProxy(new WxPay());
        pay.pay();
    }
}

在这里插入图片描述

上面的静态代理,可以看出,我们需要对每个被代理对象设计一个代理类,如果代理的功能非常多,那就需要开发人员写特别多的代理类,下面可以看下动态代理的使用。

采用动态代理,实现上面例子:
这里使用JDK自带的动态代理来实现

  1. 再定义一个支付宝的支付实现
public class ZfbPay implements PayInterFace {
    @Override
    public void pay() {
        System.out.println("支付宝支付中...");
    }
}
  1. 定义代理对象,采用jdk的 InvocationHandler 接口
public class PayProxy implements InvocationHandler {

    private Object object;

    public PayProxy(Object object) {
        this.object = object;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("事物开始!");
        Object result = method.invoke(object, args);
        System.out.println("提交事物!");
        return result;
    }
}
  1. 演示
public class demo {
    public static void main(String[] args) {
        PayInterFace pay = (PayInterFace) Proxy.newProxyInstance(
                PayInterFace.class.getClassLoader(),
                new Class[]{PayInterFace.class},
                new PayProxy(new WxPay()));
        pay.pay();


        PayInterFace pay1 = (PayInterFace) Proxy.newProxyInstance(
                PayInterFace.class.getClassLoader(),
                new Class[]{PayInterFace.class},
                new PayProxy(new ZfbPay()));
        pay1.pay();

    }
}

在这里插入图片描述

上面使用一个代理类,代理了多个对象,相对于静态代理,是代码更简介,灵活性也更高。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

怎样实现燃气产业的数字化转型之路?

关键词&#xff1a;智慧燃气、燃气数字化、智慧燃气建设、智慧燃气解决方案、智慧燃气平台 燃气产业不仅是我国能源的支柱产业&#xff0c;更是推进经济建设与生态保护协同发展的主战场。数字技术与企业生产、经营及管理深度融合是驱动企业转型升级的重要路径。基于产业融合视…

【bash指令全集合】最全教程-持续更新!

作者&#xff1a;20岁爱吃必胜客&#xff08;坤制作人&#xff09;&#xff0c;近十年开发经验, 跨域学习者&#xff0c;目前于新西兰奥克兰大学攻读IT硕士学位。荣誉&#xff1a;阿里云博客专家认证、腾讯开发者社区优质创作者&#xff0c;在CTF省赛校赛多次取得好成绩。跨领域…

智慧工地源码 SaaS模式云平台

伴随着技术的不断发展&#xff0c;信息化手段、移动技术、智能穿戴及工具在工程施工阶段的应用不断提升&#xff0c;智慧工地概念应运而生&#xff0c;庞大的建设规模催生着智慧工地的探索和研发。 什么是智慧工地&#xff1f; 伴随着技术的不断发展&#xff0c;信息化手段、移…

基于Jenkins实现接口自动化持续集成

一、JOB项目配置 1、添加描述 可选选项可填可不填 2、限制项目的运行节点 节点中要有运行环境所需的配置 节点配置教程&#xff1a;https://blog.csdn.net/YZL40514131/article/details/131504280 3、源码管理 需要将脚本推送到远程仓库中 4、构建触发器 可以选择定时构建…

内衣迷你洗衣机什么牌子好?好用不贵的内衣洗衣机推荐

由于内衣洗衣机在目前的市场上越来越受欢迎&#xff0c;使得不少的小伙伴都在犹豫要不要为自己入手一台专用的内衣洗衣机&#xff0c;专门来清洗一些内衣裤等等贴身衣物&#xff0c;这个问题的答案是很有必要的&#xff0c;因为目前市场上的家用大型洗衣机对衣物只能够起到清洁…

AI 大模型爆发后,智能计算的需求有多强烈?

自从 ChatGPT 横空出世以来&#xff0c;AI 技术就成为科技领域备受关注的热门话题之一。据 OpenAI 的报告显示&#xff0c;自 2012 年以来&#xff0c;AI 大模型的规模呈指数级增长&#xff0c;其参数数量每 16 个月翻一番。 这些大型预训练模型&#xff0c;如 GPT-4、文心一言…

uniapp-hubildx配置

1.配置浏览器 &#xff08;1&#xff09;运行》运行到浏览器配置》配置web服务器 &#xff08;2&#xff09;选择浏览器安装路径 &#xff08;3&#xff09;浏览器安装路径&#xff1a; &#xff08;3.1&#xff09; 右键点击图标》属性 &#xff08;3.2&#xff09;选择目标&…

ubuntu安装kafka

一、前提&#xff0c;先去安装java环境 二、安装kafka wget http://www.apache.org/dyn/closer.cgi?path/kafka/2.8.0/kafka_2.13-3.6.0.tgz tar xzf kafka_2.13-3.6.0.tgz mv kafka_2.13-3.6.0 /usr/local/kafka // 这一步也可以不用 启动zookeeper sudo /usr/local/kafka_2…

ubuntu启动kafka报错Could not create the Java Virtual Machine.

网上有两种方式&#xff0c;但是需要具体看自己的错误信息&#xff0c;我的错误信息如下: 这里大概是说要写入日志无权限&#xff0c;所以执行的时候&#xff0c;前面加一下sudo 执行成功。

10.机器人系统仿真(urdf集成gazebo、rviz)

目录 1 机器人系统仿真的必要性与本篇学习目的 1.1 机器人系统仿真的必要性 1.2 一些概念 URDF是 Unified Robot Description Format 的首字母缩写&#xff0c;直译为统一(标准化)机器人描述格式&#xff0c;可以以一种 XML 的方式描述机器人的部分结构&#xff0c;比如底盘…

利用yolov5输出提示框,segment-anything生成掩膜实现图像的自动标注

文章目录 一. 创建环境二. 下载模型文件三. 编辑代码 一. 创建环境 anaconda下新建一个环境 conda create -n yolo-sam python3.8激活新建的环境 conda activate yolo-sam更换conda镜像源 conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/fre…

Hive SQL的各种join总结

说明 Hive join语法有6中连接 inner join&#xff08;内连接&#xff09;、left join&#xff08;左连接&#xff09;、right join&#xff08;右连接&#xff09;、full outer join&#xff08;全外连接&#xff09;、left semi join&#xff08;左半开连接&#xff09;、cr…

批量免费AI写作工具,批量免费AI写作软件

人工智能&#xff08;AI&#xff09;的应用在各个领域不断创新。面对繁重的写作任务,我们应该怎么完成&#xff1f;本文将专心分享批量免费AI写作的方法、工具以及选择时需要注意的事项。 批量免费AI写作的方法 利用开源AI模型 一种常见的批量免费AI写作方法是利用开源的AI模…

CUDA简介——CUDA内存模式

1. 引言 前序博客&#xff1a; CUDA简介——基本概念CUDA简介——编程模式CUDA简介——For循环并行化CUDA简介——Grid和Block内Thread索引 CUDA内存模式&#xff0c;采用分层设计&#xff0c;是CUDA程序与正常C程序的最大不同之处&#xff1a; Thread-Memory Correspondenc…

《数字中台建设总体方案》

《数字中台建设总体方案》 制定数字中台战略规划&#xff1a;制定符合企业实际情况的数字中台战略规划&#xff0c;明确建设目标、重点任务和时间表。确定数字中台架构&#xff1a;根据企业业务需求和特点&#xff0c;确定数字中台的架构&#xff0c;包括技术架构、应用架构和数…

vFW搭建IRF

正文共&#xff1a;2328字 40图&#xff0c;预估阅读时间&#xff1a;5 分钟 IRF&#xff08;Intelligent Resilient Framework&#xff0c;智能弹性架构&#xff09;技术通过将多台设备连接在一起&#xff0c;虚拟化成一台设备&#xff0c;集成多台设备的硬件资源和软件处理能…

Selenium自动化测试技巧还不知道吗?

1、前言 与以前瀑布式开发模式不同&#xff0c;现在软件测试人员具有使用自动化工具执行测试用例套件的优势&#xff0c;而以前&#xff0c;测试人员习惯于通过测试脚本执行来完成测试。 但自动化测试的目的不是完全摆脱手动测试&#xff0c;而是最大程度地减少手动运行的测试…

玻色量子计算应用奖公布!MathorCup大赛圆满落幕

2023年8月15日&#xff0c;中国优选法统筹法与经济数学研究会主办的2023年第十三届MathorCup高校数学建模挑战赛圆满落幕。为了培养优秀学子的创新意识及运用数学方法和量子计算技术解决实际问题的能力&#xff0c;推动量子计算的实际落地应用&#xff0c;北京玻色量子科技有限…

计算机网络:可靠数据传输(rdt)、流水协议、窗口滑动协议

文章目录 前言一、Rdt1.Rdt1.02.Rdt2.03.Rdt2.14.Rdt2.25.Rdt3.0 二、流水线协议1.滑动窗口&#xff08;slide window&#xff09;协议发送窗口接收窗口正常情况下的2个窗口互动异常情况下GBN的2个窗口互动异常情况下SR的2窗口互动GBN协议和SR协议的异同 2.小结 总结 前言 Rdt…

Linux之重谈文件和c语言文件接口

重谈文件 文件 内容 属性, 所有对文件的操作都是: a.对内容操作 b.对属性操作 关于文件 一&#xff1a; 即使文件的内容为空&#xff0c;该文件也会在磁盘上也会占空间&#xff0c;因为文件不仅仅只有内容还有文件对应的属性&#xff0c;文件的内容会占用空间, 文件的属性也…