qileilove

          blog已經轉移至github,大家請訪問 http://qaseven.github.io/

          Java中有些好的特性(一):靜態導入

           首先,請原諒我用了一個很土,很有爭議的標題。小弟才思枯竭,實在想不出來什么文雅的了,抱歉~~

            前言

            換了東家后,從一個死忠C# Fans搖身一變,客串了一把Java程序員,可能是受老趙的《Why Java Sucks》系列博文影響太大,剛開始那幾天有很大的抵觸情緒,后來想想,何不乘此機會深入了解一下Java。

            扮演Java程序員兩個月以來,受到的折磨比較多,由于以前習慣了微軟的飯來張口,衣來伸手的策略,咋角色一轉變還真有點不適應,什么都得自己動手。雖然Java社區開源項目無數,框架一大把,但可能是選擇太多就更迷茫,還是有點不適應。

            我想寫《Java中有些好的特性》這個系列文章,主要是抱著從一個C#程序員的角度,向Java學習的態度,決沒有任何吵架的意思。汲取精華,去其糟粕嘛,呵呵。當然,這個系列是不是寫的下去,要看看我是否真的碰到了我覺得Java比C#好的地方,碰到了一個我就會記錄一篇~~

            靜態導入

            優點

            前言就說到這兒,現在進入今兒這篇文章的正題:靜態導入(static import)。

            先看下面這段示例代碼:

          1: public class SayHelloTest{
          2:     @Test
          3:     public void should_say_hello_when_given_your_name(){
          4:         gotoPage("hello");
          5:
          6:         input("name","yuyijq");
          7:
          8:         click("sayButton");
          9:
          10:         assertThat(helloPage.getLabel(),is("hello yuyijq"));
          11:     }
          12: }

            這是一段典型的功能測試代碼。對于功能測試來說,關鍵的就是要模擬用戶場景,而不涉及技術細節,用領域的語言來表達出測試。上面的測試用很清晰的步驟表達出了測試的意圖,要注意的是這里的gotoPage,input,click以及assertThat方法都不是SayHelloTest類的實例方法,都是定義在別的類甚至是第三方框架中的靜態方法。通過Java的靜態導入特性,使得現在代碼的可讀性更高:

          1: import static com.cnblogs.yuyijq.functionalTest.gotoPage;

            弊端

            通過靜態導入,我們可以去掉類名的前綴,這樣就可以將代碼寫得更自然,更像是在描述一件事兒。但靜態導入也并不是沒有缺點。在軟件開發中,很多特性適當的使用都很好,但是一旦使用過度就有可能變成壞事,這就是那個名言:不要拿著錘子,就把啥都當釘子。請看下面的代碼:

          1: map.get(MOST_VIEWED.toString());
          2: map.get(LAST_VIEWED.toString());
          3: map.get(IS_LAST_ARTICLE.toString());
          4: map.get(IS_SHOW_PICTURE.toString());
          5: //....下面有類似代碼若干行

            咋一看還以為這些MOST_VIEWED什么的全部是常量,但最后發現這些都是枚舉PortalOptions里的項,都是通過靜態導入導進來的。但由于沒了PortalOptions這個具有說明信息的枚舉名作為前綴,丟失了很多信息,造成這段代碼不是很容易看懂,不知道map.get出來的到底是什么。代碼雖然短了很多,但是如果加上PortalOptions,那么就能很直觀的直到我們需要從這個map里獲得PortalOptions相關的東東。

            在C#里畫瓢

            好的東西是要學習的,那我們如何在C#里照樣畫個瓢呢。可惜C#目前還不支持這種靜態導入,我也沒想到什么好法子能畫這個瓢。在C#里不要類名或實例名這個前綴,那除非這個方法是本類的方法,但我們肯定不可能為了使用這樣的東東,就給每個類添加這些方法,不過C#里有一個擴展方法特性,我們看看是不是能用擴展方法來畫這個瓢:

          1: public static class UnitTestExtensions
          2: {
          3:     public static T mock<T>(this object o,Type mockType)
          4:     {
          5:         return (T)NMock.Mock(mockType);
          6:     }
          7:
          11:
          12:
          13: }

            由于我們是給object類擴展的方法,所以在所有的類中都可以像是自己的方法一樣使用,也就可以寫下下面這樣的代碼了:

          1: public class SayHelloControllerTest
          2: {
          3:     [Test]
          4:     public void should_load_user_when_given_username()
          5:     {
          6:         User user = new UserBuilder()
          7:                     .withUserName("yuyijq")
          8:                     .withAge(80)
          9:                     .withSex(male)
          10:                     .build();
          11:         UserDAO userDAO = mock(typeof(UserDAO));
          12:         when(userDAO.findByUserName("yuyijq")).thenReturn(user);
          13:         replay(userDAO);
          14:         SayHelloController controller = new SayHelloController(userDAO);
          15:         verify(userDAO);
          16:         ModelAndView mv = controller.show("yuyijq");
          17:
          18:         assertModelAttribute(mv,"user",user);
          19:     }
          20: }

            不過給object添加擴展方法實在不是一個好主意,污染太大了。目前也沒有想出更好的辦法,所以就此作罷~~

            后語

            靜態導入就記敘到這里,兩個月以來我還是對Java的語法嗤之以鼻,不過對Java社區對開源的采納程度卻是由衷的感嘆。

            附加說明

            我在這里沒有任何意思表明Java好于C#,只是我在使用Java過程中發現的一些挺好的地方。這些地方能讓我寫出我自己覺得更好的代碼,而且在我心里C#遠超過Java的

            地方多得多,這是毋庸置疑的。

          posted on 2012-02-27 18:02 順其自然EVO 閱讀(197) 評論(0)  編輯  收藏


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          <2012年2月>
          2930311234
          567891011
          12131415161718
          19202122232425
          26272829123
          45678910

          導航

          統計

          常用鏈接

          留言簿(55)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 南阳市| 花莲市| 马山县| 麟游县| 文水县| 界首市| 阳山县| 即墨市| 武汉市| 邻水| 沅江市| 武冈市| 扬州市| 申扎县| 仪陇县| 罗田县| 衡阳市| 二连浩特市| 四子王旗| 彝良县| 浪卡子县| 上高县| 祁门县| 印江| 石狮市| 巴马| 来安县| 延边| 大安市| 长顺县| 于田县| 南城县| 巴南区| 千阳县| 香港| 彭泽县| 云安县| 岗巴县| 彝良县| 八宿县| 上蔡县|