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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

避免代码冗余,使用接口和泛型重构Java代码

發布時間:2023/12/3 java 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 避免代码冗余,使用接口和泛型重构Java代码 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

轉載自?避免代碼冗余,使用接口和泛型重構Java代碼

在使用動態語言和.NET工作了若干年后,我又回到老本行–Java開發。在Ruby中,清除代碼冗余是非常方便的,而在Java中則需要結合接口和泛型實現類似的功能。

原始代碼

以下是這個類中的一些方法用于后續的闡述。為了使例子更簡潔,我移除了些代碼。

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667publicV get(finalK key){??Session s;??try{??????s = oGrid.getSession();??????ObjectMap map = s.getMap(cacheName);??????return(V) map.get(key);??}??catch(ObjectGridException oge)??{??????thrownew RuntimeException("Error performing cache operation", oge);??}??finally??{??????if(s != null)??????????s.close();??????????}?????returnnull;}?????publicvoid put(finalK key, finalV value){??Session s;??try{??????s = oGrid.getSession();??????ObjectMap map = s.getMap(cacheName);??????map.upsert(key, value);??}??catch(ObjectGridException oge)??{??????thrownew RuntimeException("Error performing cache operation", oge);??}??finally??{??????if(s != null)??????????s.close();??????????????}???????????}publicMap<K, V> getAll(Set<? extendsK> keys){??finalList<V> valueList = newArrayList<V>();??finalList<K> keyList = newArrayList<K>();??keyList.addAll(keys);??Session s;??try{??????s = oGrid.getSession();??????ObjectMap map = s.getMap(cacheName);??????valueList.addAll(map.getAll(keyList));??}??catch(ObjectGridException oge)??{??????thrownew RuntimeException("Error performing cache operation", oge);??}??finally??{??????if(s != null)??????????s.close();??????????????}??Map<K, V> map = newHashMap<K, V>();??for(inti = 0; i < keyList.size(); i++) {??????map.put(keyList.get(i), valueList.get(i));??}??returnmap;}

遇到的問題

123456789101112131415Session s;try{??s = oGrid.getSession();??ObjectMap map = s.getMap(cacheName);??// Some small bit of business logic goes here}catch(ObjectGridException oge){??thrownew RuntimeException("Error performing cache operation", oge);}finally{??if(s != null)??????s.close();????????????}

上面的代碼段幾乎存在于類的每個方法中,這違反了DRY原則 。將來如果需要改變檢索Session 和 ObjectMap實例的方式,或著某天這段代碼被發現有缺陷,我們就不得不修改每個(包含這段代碼的)方法,因此需要找到一種方式來復用這些執行代碼。

重構后的代碼

為了傳遞包含了原方法中業務邏輯的實例,我們創建一個帶有抽象方法的 Executable 接口 。execute()方法參數為我們欲操作的ObjectMap實例。

123interfaceExecutable<T> {??publicT execute(ObjectMap map) throwsObjectGridException;}

由于我們的目的僅僅是在每個方法中操作ObjectMap實例,可以創建executeWithMap()方法封裝前述的那一大段重復代碼。這個方法的參數是Executable接口的實例,實例包含著操作map的必要邏輯(譯者注:這樣Executable接口的實例中就是純粹的業務邏輯,實現了解耦合)。

12345678910111213141516171819private<T> T executeWithMap(Executable<T> ex){??Session s;??try{??????s = oGrid.getSession();??????ObjectMap map = s.getMap(cacheName);??????// Execute our business logic??????returnex.execute(map);??}??catch(ObjectGridException oge)??{??????thrownew RuntimeException("Error performing cache operation", oge);??}??finally??{??????if(s != null)??????????s.close();??????????????}}

現在,可以用如下形式的模板代碼替換掉第一個例子中的代碼:這個模板創建了一個匿名內部類,實現了Executable接口和execute()方法。其中execute()方法執行業務邏輯,并以getXXX()的方式返回結果(若為Void方法,返回null)

1234567891011121314151617181920212223242526272829303132333435363738publicV get(finalK key){??returnexecuteWithMap(newExecutable<V>() {??????publicV execute(ObjectMap map) throwsObjectGridException??????{??????????return(V) map.get(key);??????}??});?????????????}?????publicvoid put(finalK key, finalV value){??executeWithMap(newExecutable<Void>() {??????publicVoid execute(ObjectMap map) throwsObjectGridException??????{??????????map.upsert(key, value);??????????returnnull;??????}??});?????????????}publicMap<K, V> getAll(Set<? extendsK> keys){??finalList<K> keyList = newArrayList<K>();??keyList.addAll(keys);??List<V> valueList = executeWithMap(newExecutable<List<V>>() {??????publicList<V> execute(ObjectMap map) throwsObjectGridException??????{??????????returnmap.getAll(keyList);??????}??});???????????????????????????????Map<K, V> map = newHashMap<K, V>();??for(inti = 0; i < keyList.size(); i++) {??????map.put(keyList.get(i), valueList.get(i));??}??returnmap;}

FunctionalInterface Annotation (功能接口注釋)

Java 8 的 @FunctionalInterface annotation 使這一切變的簡單。若某接口帶有一個抽象方法,這個接口便可以被用作為lambda表達式的參數,稱為功能接口。

1234@FunctionalInterfaceinterfaceExecutable<T> {??publicT execute(ObjectMap map) throwsObjectGridException;}

只要接口僅僅包含一個抽象方法,便可以使用這個annotation。這樣就能減少相當數量的模板代碼。

12345678910111213141516171819202122publicV get(finalK key){??returnexecuteWithMap((ObjectMap map) -> (V) map.get(key));}?????publicvoid put(finalK key, finalV value){??executeWithMap((ObjectMap map) -> { map.upsert(key, value); returnnull; });}publicMap<K, V> getAll(Set<? extendsK> keys){??finalList<K> keyList = newArrayList<K>();??keyList.addAll(keys);??List<V> valueList = executeWithMap((ObjectMap map) -> map.getAll(keyList));??Map<K, V> map = newHashMap<K, V>();??for(inti = 0; i < keyList.size(); i++) {??????map.put(keyList.get(i), valueList.get(i));??}??returnmap;}

結論

實現這些重構我很開心。它比原始的代碼略復雜一點,但是更簡明,更DRY,所以一切都是值得的。 盡管還有提升的空間,但這是一個良好的開始。

原文鏈接:? michaelbrameld ?翻譯:? ImportNew.com? -? ImportNew讀者
譯文鏈接:? http://www.importnew.com/6761.html

總結

以上是生活随笔為你收集整理的避免代码冗余,使用接口和泛型重构Java代码的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。