Cactoos中的面向对象的声明式输入/输出
Cactoos是一個(gè)面向?qū)ο蟮腏ava原語庫, 我們幾周前才開始使用它。 目的是為JDK,Guava,Apache Commons等提供一種干凈且更具聲明性的替代方案。 我們不是使用靜態(tài)過程,而是使用對(duì)象的使用方式,而是使用對(duì)象。 讓我們看看輸入/輸出如何以純面向?qū)ο蟮姆绞焦ぷ鳌?
假設(shè)您要讀取文件。 這是使用JDK7中的實(shí)用程序類 Files的靜態(tài)方法readAllBytes()進(jìn)行的操作:
byte[] content = Files.readAllBytes(new File("/tmp/photo.jpg").toPath() );這段代碼非常重要-它會(huì)立即讀取文件內(nèi)容,并將其放入數(shù)組中。
這就是您使用Cactoos的方法 :
Bytes source = new InputAsBytes(new FileAsInput(new File("/tmp/photo.jpg")) );注意-還沒有方法調(diào)用。 只有三個(gè)構(gòu)造函數(shù)或三個(gè)類組成一個(gè)更大的對(duì)象。 對(duì)象source的類型為Bytes ,代表文件的內(nèi)容。 為了從中獲取內(nèi)容,我們將其方法asBytes() :
bytes[] content = source.asBytes();這是觸摸文件系統(tǒng)的時(shí)刻。 如您所見,這種方法絕對(duì)是聲明性的,并且由于它具有面向?qū)ο蟮乃袃?yōu)點(diǎn)。
這是另一個(gè)例子。 假設(shè)您要向文件中寫入一些文本。 這是您在Cactoos中的操作方法。 首先,您需要Input :
Input input = new BytesAsInput(new TextAsBytes(new StringAsText("Hello, world!")) );然后,您需要Output :
Output output = new FileAsOutput(new File("/tmp/hello.txt") );現(xiàn)在,我們要將輸入復(fù)制到輸出。 純 OOP中沒有“復(fù)制”操作。 而且,根本不能進(jìn)行任何操作。 只是對(duì)象。 我們有一個(gè)名為TeeInput的類,它是一個(gè)Input ,它將您從其中讀取的所有內(nèi)容復(fù)制到Output ,類似于Apache Commons的 TeeInputStream所做的TeeInputStream ,但被封裝了。 因此,我們不進(jìn)行復(fù)制,而是創(chuàng)建一個(gè)Input ,如果您觸摸它,它將復(fù)制:
Input tee = new TeeInput(input, output);現(xiàn)在,我們必須“觸摸”它。 而且我們必須觸摸它的每個(gè)字節(jié),以確保它們都被復(fù)制了。 如果我們僅read()第一個(gè)字節(jié),則只有一個(gè)字節(jié)將被復(fù)制到文件中。 觸摸所有對(duì)象的最佳方法是計(jì)算tee對(duì)象的大小,逐字節(jié)地計(jì)算。 我們有一個(gè)對(duì)象,叫做LengthOfInput 。 它封裝了一個(gè)Input ,其行為類似于其以字節(jié)為單位的長度:
Scalar<Long> length = new LengthOfInput(tee);然后我們從中取出值,然后進(jìn)行文件寫入操作:
long len = length.asValue();因此,將字符串寫入文件的整個(gè)操作將如下所示:
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() );“為什么面向?qū)ο蠹词垢L,也更好?” 我聽到你問。 因?yàn)樗昝赖?strong>解耦了概念,而過程化的概念卻將它們保持在一起。
假設(shè)您正在設(shè)計(jì)一個(gè)類,該類應(yīng)該加密一些文本并將其保存到文件中。 這是您將如何以程序方式設(shè)計(jì)它的方法(當(dāng)然,這不是真正的加密):
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]", "*"));} }工作正常,但是當(dāng)您決定擴(kuò)展它以同時(shí)寫入OutputStream時(shí),會(huì)發(fā)生什么? 您將如何修改此類? 那會(huì)多么丑陋? 那是因?yàn)樵O(shè)計(jì)不是面向?qū)ο蟮摹?
這就是您將使用Cactoos以面向?qū)ο蟮姆绞竭M(jìn)行相同設(shè)計(jì)的方式:
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被接受,我們?cè)撛趺醋?#xff1f; 我們只添加一個(gè)輔助構(gòu)造函數(shù):
class Encoder {Encoder(final OutputStream stream) {this(new OutputStreamAsOutput(stream));} }做完了 那是多么容易和優(yōu)雅。
那是因?yàn)楦拍畋煌昝赖胤蛛x并且功能被封裝了。 在該過程示例中,該對(duì)象的行為位于方法外部(在encode()方法中encode() 。 該文件本身不知道如何寫,有些外部過程Files.write()知道。
相反,在面向?qū)ο蟮脑O(shè)計(jì)中, FileAsOutput知道如何編寫,而其他人FileAsOutput知道。 文件寫入功能被封裝,這使得可以用任何可能的方式裝飾對(duì)象,從而創(chuàng)建可重用和可替換的復(fù)合對(duì)象。
您現(xiàn)在看到OOP的美麗了嗎?
翻譯自: https://www.javacodegeeks.com/2017/06/object-oriented-declarative-inputoutput-cactoos.html
總結(jié)
以上是生活随笔為你收集整理的Cactoos中的面向对象的声明式输入/输出的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 苹果电脑查使用记录查询(苹果电脑查历史记
- 下一篇: hadoop综述_Hadoop书籍赠品–