Cactoos是一个面向对象的Java原语库, 我们几周前才开始使用它。 目的是为JDK,Guava,Apache Commons等提供一种干净且更具声明性的替代方案。 我们不是使用静态过程,而是使用对象的使用方式,而是使用对象。 让我们看看输入/输出如何以面向对象的方式工作。

假设您要读取文件。 这是使用JDK7中的实用程序类 Files的静态方法readAllBytes()进行的操作:

byte[] content = Files.readAllBytes(new File("/tmp/photo.jpg").toPath()
);

这段代码非常重要-它会立即读取文件内容,并将其放入数组中。

这就是您使用Cactoos的方法 :

Bytes source = new InputAsBytes(new FileAsInput(new File("/tmp/photo.jpg"))
);

注意-还没有方法调用。 只有三个构造函数或三个类组成一个更大的对象。 对象source的类型为Bytes ,代表文件的内容。 为了从中获取内容,我们将其方法asBytes()

bytes[] content = source.asBytes();

这是触摸文件系统的时刻。 如您所见,这种方法绝对是声明性的,并且由于它具有面向对象的所有优点。

这是另一个例子。 假设您要向文件中写入一些文本。 这是您在Cactoos中的操作方法。 首先,您需要Input

Input input = new BytesAsInput(new TextAsBytes(new StringAsText("Hello, world!"))
);

然后,您需要Output

Output output = new FileAsOutput(new File("/tmp/hello.txt")
);

现在,我们要将输入复制到输出。 OOP中没有“复制”操作。 而且,根本不能进行任何操作。 只是对象。 我们有一个名为TeeInput的类,它是一个Input ,它将您从其中读取的所有内容复制到Output ,类似于Apache Commons的 TeeInputStream所做的TeeInputStream ,但被封装了。 因此,我们不进行复制,而是创建一个Input ,如果您触摸它,它将复制:

Input tee = new TeeInput(input, output);

现在,我们必须“触摸”它。 而且我们必须触摸它的每个字节,以确保它们都被复制了。 如果我们仅read()第一个字节,则只有一个字节将被复制到文件中。 触摸所有对象的最佳方法是计算tee对象的大小,逐字节地计算。 我们有一个对象,叫做LengthOfInput 。 它封装了一个Input ,其行为类似于其以字节为单位的长度:

Scalar<Long> length = new LengthOfInput(tee);

然后我们从中取出值,然后进行文件写入操作:

long len = length.asValue();

因此,将字符串写入文件的整个操作将如下所示:

new LengthOfInput(new TeeInput(new BytesAsInput(new TextAsBytes(new StringAsText("Hello, world!"))),new FileAsOutput(new File("/tmp/hello.txt")))
).asValue(); // happens here

这是它在JDK7中的替代程序:

Files.write(new File("/tmp/hello.txt").toPath(),"Hello, world!".getBytes()
);

“为什么面向对象即使更长,也更好?” 我听到你问。 因为它完美地解耦了概念,而过程化的概念却将它们保持在一起。

假设您正在设计一个类,该类应该加密一些文本并将其保存到文件中。 这是您将如何以程序方式设计它的方法(当然,这不是真正的加密):

class Encoder {private final File target;Encoder(final File file) {this.target = file;}void encode(String text) {Files.write(this.target,text.replaceAll("[a-z]", "*"));}
}

工作正常,但是当您决定扩展它以同时写入OutputStream时,会发生什么? 您将如何修改此类? 那会多么丑陋? 那是因为设计不是面向对象的。

这就是您将使用Cactoos以面向对象的方式进行相同设计的方式:

class Encoder {private final Output target;Encoder(final File file) {this(new FileAsOutput(file));}Encoder(final Output output) {this.target = output;}void encode(String text) {new LengthOfInput(new TeeInput(new BytesAsInput(new TextAsBytes(new StringAsText(text.replaceAll("[a-z]", "*")))),this.target)).asValue();}
}

如果我们希望OutputStream被接受,我们该怎么做? 我们只添加一个辅助构造函数:

class Encoder {Encoder(final OutputStream stream) {this(new OutputStreamAsOutput(stream));}
}

做完了 那是多么容易和优雅。

那是因为概念被完美地分离并且功能被封装了。 在该过程示例中,该对象的行为位于方法外部(在encode()方法中encode() 。 该文件本身不知道如何写,有些外部过程Files.write()知道。

相反,在面向对象的设计中, FileAsOutput知道如何编写,而其他人FileAsOutput知道。 文件写入功能被封装,这使得可以用任何可能的方式装饰对象,从而创建可重用和可替换的复合对象。

您现在看到OOP的美丽了吗?

翻译自: https://www.javacodegeeks.com/2017/06/object-oriented-declarative-inputoutput-cactoos.html

Cactoos中的面向对象的声明式输入/输出相关推荐

  1. k8s中kubectl陈述式/声明式资源管理

    k8s陈述资源管理方法的说明 1.kubernetes 集群管理集群资源的唯一入口是通过相应的方法调用 apiserver 的接口 2.kubectl 是官方的CLI命令行工具,用于与 apiserv ...

  2. 在计算机系统中使用加载器,在个人计算机系统中从软盘加载基本输入/输出系统的设备和方法...

    主权项: 一种从通常接有硬文件的个人计算机系统的软盘驱动器含有的\r\r\r\r\n软盘介质中加载BIOS的设备,该个人计算机系统具有系统\r\r\r\r\n处理器.只读存储器.随机存取存储器和软盘驱 ...

  3. Spring声明式事务配置管理方法

    /*2011年8月28日 10:03:30 by Rush  */ 环境配置 项目使用SSH架构,现在要添加Spring事务管理功能,针对当前环境,只需要添加Spring 2.0 AOP类库即可.添加 ...

  4. Spring声明式事务管理的配置详解

    环境配置 项目使用SSH架构,现在要添加Spring事务管理功能,针对当前环境,只需要添加Spring 2.0 AOP类库即可.添加方法: 点击项目右键->Build Path->Add ...

  5. Spring声明式事物配置管理

    Spring声明式事物配置管理 1.首先在applicationContext.xml添加以下内容: <!-- 配置事务管理器 --> <bean id="transact ...

  6. 【Spring】spring基于注解的声明式事务控制

    结构 domin package com.itheima.domain;import java.io.Serializable;public class Account implements Seri ...

  7. 【spring】spring基于xml的声明式事务控制

    结构 domain package com.itheima.domain;import java.io.Serializable;public class Account implements Ser ...

  8. 全面分析 Spring 的编程式事务管理及声明式事务管理(转)

    摘要 Spring 的事务管理是 Spring 框架中一个比较重要的知识点,该知识点本身并不复杂,只是由于其比较灵活,导致初学者很难把握.本教程从基础知识开始,详细分析了 Spring 事务管理的使用 ...

  9. 全面分析 Spring 的编程式事务管理及声明式事务管理--转

    开始之前 关于本教程 本教程将深入讲解 Spring 简单而强大的事务管理功能,包括编程式事务和声明式事务.通过对本教程的学习,您将能够理解 Spring 事务管理的本质,并灵活运用之. 先决条件 本 ...

最新文章

  1. 流式处理框架storm浅析(下篇)
  2. php 获取xlsx,PHPExcel获取.xlsx文件内容
  3. C# 字符、字符串过滤,只能输入数字、中文、英文、大写、小写(转)
  4. permission denied是什么鬼?
  5. openstack搭建
  6. java中String字符串的替换函数:replace与replaceAll的区别
  7. 一天一个小技巧(2)——CSDN编译器的首行缩进2字符
  8. c语言冒险游戏代码大全,C语言简易文字冒险游戏源代码.doc
  9. 计算机kb和gb单位的在线换算器,KB/MB/GB。。单位换算
  10. 蓝牙、Wifi与ZigBee无线传输技术中,谁比较占有优势
  11. 100M宽带能下载多快? 关于带宽的下载速度研究
  12. WIFI能杀死植物吗?
  13. SSH2.0编程 ssh协议过程实现(转)
  14. Q1营收不及预期,高通还能带着“标准”称霸5G吗?
  15. 【2021-05-06】JS逆向之微店登入ua
  16. SQLServer2008密钥 key
  17. Freely Available Standards
  18. 第3章 你应该如何运行程序 (可选,Shell、IDE介绍,推荐看一下)
  19. 计算机二进制、八进制、十进制、十六进制的转换(计算机基础进制的转换)及进制在线转换网址
  20. lenovo L480 进入bios_B20A-BTC主板魔BIOS安装I5 94OOF CPU教程

热门文章

  1. 基于消息中间件RabbitMQ实现简单的RPC服务
  2. 架构师必须掌握的 10 条设计原则
  3. Java se之动态代理
  4. Maven精选系列--介绍与安装
  5. [编程入门]猴子吃桃的问题
  6. 对于这款APP,我充了个终身VIP!!!
  7. 有些事,父母一定不能依着孩子!
  8. 班级日常分享 | 一天一瞬间!
  9. 2019蓝桥杯省赛---java---C---9(等差数列)
  10. 2015蓝桥杯省赛---java---C---2(立方尾不变)