oop 类和对象的_实用程序类的OOP替代
oop 類和對(duì)象的
實(shí)用程序類(也稱為幫助程序類)是僅具有靜態(tài)方法且不封裝狀態(tài)的“結(jié)構(gòu)”。 StringUtils , IOUtils , FileUtils從Apache的共享 ; Guava的 Iterables和Iterators以及JDK7的Files是實(shí)用程序類的完美示例。
這種設(shè)計(jì)思想在Java世界(以及C#,Ruby等)中非常流行,因?yàn)閷?shí)用程序類提供了在各處使用的通用功能。
在這里,我們要遵循DRY原則并避免重復(fù)。 因此,我們將通用代碼塊放入實(shí)用程序類中,并在必要時(shí)重用它們:
確實(shí),這是一種非常方便的技術(shù)!
實(shí)用程序類是邪惡的
但是,在面向?qū)ο蟮氖澜缰?#xff0c;實(shí)用程序類被認(rèn)為是非常不好的實(shí)踐(有些甚至可能說“可怕”)。
關(guān)于這個(gè)主題已經(jīng)有很多討論。 僅舉幾例: Helper Classes Evil? 尼克·馬利克(Nick Malik)撰寫的《 為什么西蒙·哈特(Simon Hart)的助手,單身人士和實(shí)用程序類大多不好 ,沃德元帥避免使用實(shí)用程序類 , 殺死 實(shí)用程序類 ! 由Dhaval Dalal撰寫, 幫助類是 Rob Bagby的代碼氣味 。
此外,在StackExchange上還有一些關(guān)于實(shí)用程序類的問題: 如果“實(shí)用程序”類是邪惡的,那么我應(yīng)該將通用代碼放在哪里? , 實(shí)用程序類是邪惡的 。
他們所有論點(diǎn)的簡要總結(jié)是,實(shí)用程序類不是正確的對(duì)象。 因此,它們不適合面向?qū)ο蟮氖澜纭?它們從過程編程中繼承而來,主要是因?yàn)榇蠖鄶?shù)方法都用于那時(shí)的功能分解范例。
假設(shè)您同意這些參數(shù)并且想停止使用實(shí)用程序類,我將通過示例展示如何用適當(dāng)?shù)膶?duì)象替換這些生物。
程序示例
舉例來說,假設(shè)您要讀取一個(gè)文本文件,將其拆分為幾行,修剪每一行,然后將結(jié)果保存到另一個(gè)文件中。 這可以通過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"); }上面的代碼看起來很干凈; 但是,這是過程編程,而不是面向?qū)ο蟮摹?我們正在處理數(shù)據(jù)(字節(jié)和位),并明確指示計(jì)算機(jī)從何處檢索數(shù)據(jù),然后在何處將其放置在每一行代碼中。 我們正在定義執(zhí)行程序 。
面向?qū)ο蟮奶娲?/h2>
在面向?qū)ο蟮姆独?#xff0c;我們應(yīng)該實(shí)例和撰寫的對(duì)象,從而讓他們管理數(shù)據(jù)時(shí), 他們?nèi)绾慰释?與其調(diào)用補(bǔ)充靜態(tài)函數(shù),不如創(chuàng)建能夠公開我們正在尋求的行為的對(duì)象:
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;} }此過程調(diào)用:
int max = NumberUtils.max(10, 5);將成為面向?qū)ο蟮?#xff1a;
int max = new Max(10, 5).intValue();土豆土豆 并不是的; 只是繼續(xù)閱讀...
對(duì)象而不是數(shù)據(jù)結(jié)構(gòu)
這就是我如何設(shè)計(jì)與上述相同的文件轉(zhuǎn)換功能,但是是以面向?qū)ο蟮姆绞竭M(jìn)行的:
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實(shí)現(xiàn)Collection<String>并封裝所有文件讀取和寫入操作。 FileLines實(shí)例的行為與字符串的集合完全相同,并且隱藏了所有I / O操作。 當(dāng)我們迭代它時(shí)—正在讀取一個(gè)文件。 當(dāng)我們addAll()時(shí)—正在寫入文件。
Trimmed還實(shí)現(xiàn)了Collection<String>并封裝了一個(gè)字符串集合( Decorator模式 )。 每次檢索下一行時(shí),都會(huì)對(duì)其進(jìn)行修剪。
所有服用參與片斷類是相當(dāng)小: Trimmed , FileLines和UnicodeFile 。 他們每個(gè)人都對(duì)自己的單一功能負(fù)責(zé),因此完全遵循單一責(zé)任原則 。
在我們這方面,作為庫的用戶,這可能并不那么重要,但是對(duì)于他們的開發(fā)人員而言,這勢在必行。 與在80多個(gè)方法和3000行實(shí)用程序類FileUtils使用readLines()方法相比,開發(fā),維護(hù)和測試FileLines類要容易得多。 認(rèn)真地看一下其源代碼 。
面向?qū)ο蟮姆椒ㄊ寡舆t執(zhí)行成為可能。 in需要輸入數(shù)據(jù)之前,不會(huì)讀取in文件。 如果我們不能開out由于一些I / O錯(cuò)誤,第一個(gè)文件甚至不能觸及。 整個(gè)節(jié)目只有在我們調(diào)用addAll()之后才開始。
除了最后一個(gè)片段外,第二個(gè)片段中的所有行都實(shí)例化并將較小的對(duì)象組合為較大的對(duì)象。 該對(duì)象組合對(duì)于CPU而言相當(dāng)便宜,因?yàn)樗粫?huì)引起任何數(shù)據(jù)轉(zhuǎn)換。
除此之外,很明顯第二個(gè)腳本在O(1)空間中運(yùn)行,而第一個(gè)腳本在O(n)中運(yùn)行。 這是我們對(duì)第一個(gè)腳本中的數(shù)據(jù)采用過程方法的結(jié)果。
在面向?qū)ο蟮氖澜缰?#xff0c;沒有數(shù)據(jù)。 只有對(duì)象及其行為!
相關(guān)文章
您可能還會(huì)發(fā)現(xiàn)以下有趣的帖子:
- 為什么NULL是錯(cuò)誤的?
- 避免字符串串聯(lián)
- 對(duì)象應(yīng)該是不可變的
- Java代碼中的典型錯(cuò)誤
翻譯自: https://www.javacodegeeks.com/2014/09/oop-alternative-to-utility-classes.html
oop 類和對(duì)象的
總結(jié)
以上是生活随笔為你收集整理的oop 类和对象的_实用程序类的OOP替代的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java基准测试_星期五基准功能Java
- 下一篇: win8电脑怎么恢复出厂设置如何是电脑恢