日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

用装饰器改变收藏

發(fā)布時間:2023/12/3 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 用装饰器改变收藏 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

裝飾圖案

自從第一次學(xué)習(xí)編程設(shè)計模式以來,裝飾器模式一直是我的最愛。 在我看來,這是一個很新穎的想法,比其他想法有趣得多。 不要誤會我的意思,其他大多數(shù)人也引起了我的注意,但沒有什么比裝飾器模式更重要。 至今,它仍然是我的最愛之一。

(如果您不熟悉設(shè)計模式,我強烈建議您采用Head First Design Patterns 。如果您只是想了解裝飾器模式,請參見這本書的裝飾器章節(jié)摘錄 。)

我個人認為裝飾器模式通常沒有得到充分利用。 可能有幾個原因。 一方面,我認為這不適用于所有情況。 另外,裝飾器模式可以解決的問題通常很難發(fā)現(xiàn)。 是什么讓該模式如此令我贊嘆,這是因為可能很難弄清楚該模式在哪里的原因,這是一個不尋常的想法。 就是說,直到您對“繼承之上的構(gòu)成”的原理非常熟悉為止。

太多的地方將繼承深深地打入您的腦海,以至于使人難以相信組合通常是比繼承更好的主意。

無論如何,裝飾器模式不僅是我最喜歡的模式,而且在Java 8我最喜歡的新功能之一中也強烈使用了它:Stream API。 實際上,我要向您展示的大部分內(nèi)容都在很大程度上模仿了Stream API的某些行為。

問題

假設(shè)您有一個字符串列表,但它們可能有也可能沒有不需要的前導(dǎo)或尾隨空格。 您可能會這樣做,以消除不需要的空間。

List untrimmedStrings = aListOfStrings(); List trimmedStrings = new ArrayList();for(String untrimmedString : untrimmedStrings) {trimmedStrings.add(untrimmedString.trim()); }//use trimmed strings...

在這種情況下,您將創(chuàng)建一個全新的字符串列表,并用第一個列表中的字符串填充它,但會對其進行修剪。 這有幾個問題。 首先,它立即創(chuàng)建了一個完整的新列表。 相反,每個經(jīng)過修剪的String的創(chuàng)建都可以延遲到需要時才進行,甚至在不需要時也永遠不會完成。 另外,如果有人想添加更多字符串,則必須將它們添加到兩個列表中。 您還必須確保先修剪新的字符串,然后再將它們放入修剪的列表中。 最后,此代碼是命令性的,而不是聲明性的。

讓我們看一下代碼的更具聲明性的版本,然后看看如何使用它來解決其他問題。

List untrimmedStrings = aListOfStrings(); List trimmedStrings = trimmed(untrimmedStrings);//use trimmed strings...

哎呀,該trimmed()函數(shù)可能會發(fā)生任何事情! 看看那個; 它返回字符串列表,就像前面的方法一樣。 這樣做的好處,對吧?

錯誤。 是的,該函數(shù)從技術(shù)上講可以做與我們之前所做的相同的事情,這意味著我們所做的只是使外部代碼具有聲明性。 但是在此示例中,它打算是一個靜態(tài)工廠方法(帶有靜態(tài)導(dǎo)入),該方法創(chuàng)建一個新的Trimmed對象,該對象包裝了untrimmedStrings列表。 Trimmed實現(xiàn)了List接口,但它幾乎將所有內(nèi)容都委派給包裝的列表,但通常具有修飾的功能。 添加或刪除新的String時,通過對包裝的列表進行處理,可以對兩個列表進行“合并”。 并且當它添加新的String時,可以按原樣添加它,但是只需要確保在輸出時將其修剪即可。

另外,由于僅在從列表中提取數(shù)據(jù)時才進行修剪,因此我們不必立即完成修剪每個String的所有工作。 有可能甚至無法處理某些字符串,因此永遠不會不必要地修剪那些字符串。

但是,這有一些缺點。 一種,如果修剪過的字符串多次從列表中拉出,則最終每次都會修剪。 這不會占用任何額外的內(nèi)存,但是會增加一些時間,尤其是如果您遍歷整個列表幾次。 其次,它會產(chǎn)生修剪后的列表和未修剪的列表為同一列表的副作用。 無論我們是否想要,更改一個都會影響另一個。

我不想在本文中浪費太多時間和空間,以向您展示完全創(chuàng)建的Trimmed的List實現(xiàn)(為List定義了30多種方法),所以我將對其進行調(diào)整,以便僅定義的可迭代方法。 由于在很多時候,您真正要做的就是遍歷集合,因此必須相對可以接受。

public class Trimmed implements Iterable {public static List trimmed(List base) {return base;}public Trimmed(Iterable base){this.base = base;}public Iterator iterator(){return new TrimmedIterator(base.iterator());}private Iterable base; }class TrimmedIterator implements Iterator {public TrimmedIterator(Iterator base){this.base = base;}public boolean hasNext(){return base.hasNext();}public String next(){return base.next().trim();}public void remove(){throw new UnsupportedOperationException();}private Iterator base; }

如何裝飾對象

我不記得有人在任何地方提及此事,但這很重要,因此我想告訴您。

有兩種關(guān)于裝飾對象的基本思想。 第一種是當您簡單地傳入傳入裝飾/包裝的對象創(chuàng)建裝飾器的新實例時。第二種方法是在要裝飾的對象上調(diào)用一個方法。

這兩個選項都顯示在這里

MyCollection untrimmedStrings = aCollectionOfStrings();//new Decorator Instance MyCollection trimmedStrings = new TrimmingDecorator(untrimmedStrings);//OR//method call on the to-be-decorated object MyCollection trimmedStrings2 = untrimmedStrings.trimmed();

而且trimmed()的代碼如下所示:

public MyCollection trimmed() {return new TrimmingDecorator(this); }

每種方法都有其優(yōu)點和缺點。 由于每個選項的弊端本質(zhì)上都缺乏另一個選項的優(yōu)點,因此我只列出每個選項的優(yōu)點。

新實例專家:

  • 比方法調(diào)用選項可擴展,因為方法調(diào)用必須嘗試覆蓋裝飾器的所有可能性
  • 用戶可以更輕松地看到它是裝飾器模式
  • 可修飾界面中所需的方法更少

方法調(diào)用的優(yōu)點:

  • 如果用戶不需要知道,則隱藏裝飾器實現(xiàn)
  • 用戶端沒有明確的“新”關(guān)鍵字(通常被認為是不好的)
  • 用戶可以輕松找到所有裝飾器,因為它們都在可裝飾對象的界面上列出了

Java的原始IO庫是新實例修飾的一個很好的例子,而Java 8中的Stream API是方法調(diào)用修飾的一個很好的例子。 我個人的喜好是使用方法調(diào)用選項,因為它使所有可能性對用戶顯而易見,但是如果要這樣做,則用戶也可以使用自己的裝飾器擴展對象,那么您絕對應(yīng)該使用新的實例路由。

翻譯自: https://www.javacodegeeks.com/2015/01/transforming-collections-with-decorators.html

總結(jié)

以上是生活随笔為你收集整理的用装饰器改变收藏的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。