oop 类和对象的_实用程序类的OOP替代
oop 類和對象的
實用程序類(也稱為幫助程序類)是僅具有靜態方法且不封裝狀態的“結構”。 StringUtils , IOUtils , FileUtils從Apache的共享 ; Guava的 Iterables和Iterators以及JDK7的Files是實用程序類的完美示例。
這種設計思想在Java世界(以及C#,Ruby等)中非常流行,因為實用程序類提供了在各處使用的通用功能。
在這里,我們要遵循DRY原則并避免重復。 因此,我們將通用代碼塊放入實用程序類中,并在必要時重用它們:
確實,這是一種非常方便的技術!
實用程序類是邪惡的
但是,在面向對象的世界中,實用程序類被認為是非常不好的實踐(有些甚至可能說“可怕”)。
關于這個主題已經有很多討論。 僅舉幾例: Helper Classes Evil? 尼克·馬利克(Nick Malik)撰寫的《 為什么西蒙·哈特(Simon Hart)的助手,單身人士和實用程序類大多不好 ,沃德元帥避免使用實用程序類 , 殺死 實用程序類 ! 由Dhaval Dalal撰寫, 幫助類是 Rob Bagby的代碼氣味 。
此外,在StackExchange上還有一些關于實用程序類的問題: 如果“實用程序”類是邪惡的,那么我應該將通用代碼放在哪里? , 實用程序類是邪惡的 。
他們所有論點的簡要總結是,實用程序類不是正確的對象。 因此,它們不適合面向對象的世界。 它們從過程編程中繼承而來,主要是因為大多數方法都用于那時的功能分解范例。
假設您同意這些參數并且想停止使用實用程序類,我將通過示例展示如何用適當的對象替換這些生物。
程序示例
舉例來說,假設您要讀取一個文本文件,將其拆分為幾行,修剪每一行,然后將結果保存到另一個文件中。 這可以通過Apache Commons的FileUtils完成:
void transform(File in, File out) {Collection<String> src = FileUtils.readLines(in, "UTF-8");Collection<String> dest = new ArrayList<>(src.size());for (String line : src) {dest.add(line.trim());}FileUtils.writeLines(out, dest, "UTF-8"); }上面的代碼看起來很干凈; 但是,這是過程編程,而不是面向對象的。 我們正在處理數據(字節和位),并明確指示計算機從何處檢索數據,然后在何處將其放置在每一行代碼中。 我們正在定義執行程序 。
面向對象的替代
在面向對象的范例,我們應該實例和撰寫的對象,從而讓他們管理數據時, 他們如何渴望。 與其調用補充靜態函數,不如創建能夠公開我們正在尋求的行為的對象:
public class Max implements Number {private final int a;private final int b;public Max(int x, int y) {this.a = x;this.b = y;}@Overridepublic int intValue() {return this.a > this.b ? this.a : this.b;} }此過程調用:
int max = NumberUtils.max(10, 5);將成為面向對象的:
int max = new Max(10, 5).intValue();土豆土豆 并不是的; 只是繼續閱讀...
對象而不是數據結構
這就是我如何設計與上述相同的文件轉換功能,但是是以面向對象的方式進行的:
void transform(File in, File out) {Collection<String> src = new Trimmed(new FileLines(new UnicodeFile(in)));Collection<String> dest = new FileLines(new UnicodeFile(out));dest.addAll(src); }FileLines實現Collection<String>并封裝所有文件讀取和寫入操作。 FileLines實例的行為與字符串的集合完全相同,并且隱藏了所有I / O操作。 當我們迭代它時—正在讀取一個文件。 當我們addAll()時—正在寫入文件。
Trimmed還實現了Collection<String>并封裝了一個字符串集合( Decorator模式 )。 每次檢索下一行時,都會對其進行修剪。
所有服用參與片斷類是相當小: Trimmed , FileLines和UnicodeFile 。 他們每個人都對自己的單一功能負責,因此完全遵循單一責任原則 。
在我們這方面,作為庫的用戶,這可能并不那么重要,但是對于他們的開發人員而言,這勢在必行。 與在80多個方法和3000行實用程序類FileUtils使用readLines()方法相比,開發,維護和測試FileLines類要容易得多。 認真地看一下其源代碼 。
面向對象的方法使延遲執行成為可能。 in需要輸入數據之前,不會讀取in文件。 如果我們不能開out由于一些I / O錯誤,第一個文件甚至不能觸及。 整個節目只有在我們調用addAll()之后才開始。
除了最后一個片段外,第二個片段中的所有行都實例化并將較小的對象組合為較大的對象。 該對象組合對于CPU而言相當便宜,因為它不會引起任何數據轉換。
除此之外,很明顯第二個腳本在O(1)空間中運行,而第一個腳本在O(n)中運行。 這是我們對第一個腳本中的數據采用過程方法的結果。
在面向對象的世界中,沒有數據。 只有對象及其行為!
相關文章
您可能還會發現以下有趣的帖子:
- 為什么NULL是錯誤的?
- 避免字符串串聯
- 對象應該是不可變的
- Java代碼中的典型錯誤
翻譯自: https://www.javacodegeeks.com/2014/09/oop-alternative-to-utility-classes.html
oop 類和對象的
總結
以上是生活随笔為你收集整理的oop 类和对象的_实用程序类的OOP替代的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java基准测试_星期五基准功能Java
- 下一篇: maven的常见问题_Maven常见问题