Android下如何優(yōu)雅流暢地寫代碼

原創(chuàng)博客,如有轉(zhuǎn)載蝇完,請注明出處官硝,非常感謝。

首先說一下短蜕,靈感來自于RxAndroid氢架,自從用上了這個庫之后,整個思路都變了朋魔,原來異步還可以玩的這么溜岖研,這還不是重點,重點是我學會了如何使寫代碼更加的流暢警检!

那么除了Rx的異步之外孙援,我究竟學到了什么呢?對的扇雕,就是方法鏈(Method Chaining赃磨,或者叫Named method idiom)和方法參數(shù)盡可能少于等于1個,在鏈條的末端偶爾出現(xiàn)兩三個參數(shù)還是可以接受的洼裤,這兩個點讓我從此代碼風格完全變了邻辉,思路也完全變了!先舉些例子:

  1. 當你設置全局配置的時候腮鞍,可能會這樣做值骇,并且你一直認為,這樣挺好移国,我也是一直這么認為的:
GlobalConfig.getInstance().setServerInfo("192.168.1.2", 65530, 5 * 60 * 1000, true);

這種風格對我來說吱瘩,有兩個問題,一直困擾我迹缀,但是我居然懶惰的沒去想過解決這兩個困擾我的問題使碾,第一個問題是參數(shù)多蜜徽,哪個對應哪個經(jīng)常記不清楚,需要翻看方法的定義的位置看看票摇,或者鼠標點在方法上拘鞋,再按ctrl之類的一堆快捷鍵看看方法簽名:

public void setServerInfo(String ip, int port, long heartBeatTime, boolean reconnectOnNetworkChange) {
        // code comes here
    }

哦,原來第一個參數(shù)是ip地址矢门,第二個是端口盆色,第三個是心跳包間隔,第四個是網(wǎng)絡改變的時候是否重連祟剔,大家看到?jīng)]隔躲?記憶力差那么一丁點的時候,必然在這樣的方法調(diào)用時卡你一下物延,而我們的項目里面經(jīng)常充滿這種N個參數(shù)的方法宣旱,每天寫代碼就這樣卡幾次,誰來救救我叛薯?
第二個問題是總感覺有點問題响鹃,就像長城寬帶看高清,總會卡你幾幀案训,寬帶你知道是網(wǎng)絡問題买置,這個代碼有什么問題還一時說不上來,長期習慣了也就覺得强霎,卡一下是應該的忿项,畢竟本人又不是清華北大的高才生,還不是計算機專業(yè)出身的城舞,就像長城寬帶看高清轩触,你交的網(wǎng)費還不到電信的五分之一,偶爾卡一下也能接受家夺。對于方法鏈脱柱,或者有人叫鏈式調(diào)用,我是一直知道的拉馋,并且也在用榨为,各種Builder模式不就是經(jīng)典的代表場景么?Hibernate不是這樣的么煌茴?都習以為常了随闺,要不是RxAndroid給我的震撼感覺,我絕對不會想到蔓腐,上面的代碼應該要重構(gòu)優(yōu)化的>乩帧!回论!現(xiàn)在我的調(diào)用變成了:

GlobalConfig
                .getInstance()
                .ip("192.168.1.2")
                .port(65530)
                .heartBeatTime(5 * 60 * 1000)
                .reconnectOnNetworkChange(true);

一下子就豁然開朗了散罕,記憶力沒有了負擔分歇,整個人都精神多了,腰也不酸腿也不疼欧漱,媽媽再也不用擔心我沒有名牌大學畢業(yè)了职抡。怎么做到的呢?看重構(gòu)后的代碼(這里為了篇幅去掉了注釋硫椰,不過方法名本身就已經(jīng)非常好的注釋自己了,可能這也是為什么方法鏈有人叫Named method idiom的原因吧):

public GlobalConfig ip(String ip) {
        this.ip = ip;
        return this;
    }

    public GlobalConfig port(int port) {
        this.port = port;
        return this;
    }

    public GlobalConfig heartBeatTime(long time) {
        this.heartBeatTime = time;
        return this;
    }

    public GlobalConfig reconnectOnNetworkChange(boolean reconn) {
        this.reconnectOnNetworkChange = reconn;
        return this;
    }

換個思維萨蚕,生活就是這么幸福靶草。

  1. 以下場景更常見,創(chuàng)建一個POJO對象岳遥,為對應的字段一一賦值奕翔,沒有哪個場景比這個更常見更習以為常了吧?像這樣:
User user = new User();
user.setName(name);
user.setAge(age);
user.setGender(gender);
// ... 省略更多
UserDao.getInstance().save(user);

有沒有想過可以這樣呢浩蓉?

UserDao.getInstance()
       .save(
           User.newInstance()
               .setName(name)
               .setAge(age)
               .setGender(gender)
               // 省略更多
        );

對應的派继,在User這個類里,setter的方法變了捻艳,變成如下:

  public User setName(String name) {
      this.name = name;
      return this;
  }
  // 其他方法類似驾窟,略去,自行腦補

這時候估計你會跳出來說认轨,我setter方法都是自動生成的绅络,你這不是坑我么?生成setter之后嘁字,我還需要手工去改所有的setter恩急,WTF!
等等纪蜒,我有說這些代碼是我手工寫的么衷恭?Android Studio生成getter/setter的時候本身就自帶這種實現(xiàn),你不看怪我咯纯续,看随珠,連AS都覺得有必要提供這樣的setter生成方式了,不用是不是有點浪費了呢猬错?過程如下:

  1. 去到你需要生成getter/setter的類牙丽,注意了,操作跟以前是一樣的兔魂,按ALT + Insert鍵烤芦,彈出菜單選擇getter/setter
  2. 選擇字段,在setter template那個框選擇Builder析校,然后OK构罗,完成了铜涉,生成的代碼就是上面那種了
    以防說的不清楚,有圖有真相:


    setter.png

    default.png

    builder.png

    對了遂唧,就是這樣芙代。

  1. 對于下面這種activity的跳轉(zhuǎn)方法,大家都一致認為是比較不錯的盖彭,至少纹烹,這是目前公認的做的比較合理的一種方式:
  // 這個方法是靜態(tài)的,寫在XXXActivity里召边,如果有多種跳轉(zhuǎn)方式的铺呵,寫多個類似的方法
   public static void startXXXActivity(Activity fromActivity, String articleId, String thumbImgUrl) {
      Intent in = new Intent(fromActivity, XXXActivity.class);
      in.putExtra("articleId", articleId);
      in.putExtra("thumbImgUrl", thumbImgUrl);
      fromActivity.startActivity(in);
  }

然后調(diào)用的時候就相對簡單了:

  XXXActivity.startXXXActivity(this, "id123456", "http://www.example.com/example.png");

這里的問題跟第一個幾乎是一模一樣的,但是相對于第一種情況隧熙,這里復雜不止一點點片挂,首先,這里有放進Intent的key要管理贞盯,如果很多activity用到的key都相同音念,該抽出來嗎?好吧躏敢,key的問題不展開了闷愤。其次你沒法getInstance(),XXXActivity還沒創(chuàng)造出來呢件余,你怎么使用這個實例來創(chuàng)建方法鏈肝谭?即使你有辦法做出方法鏈,那么多activity蛾扇,你得寫的多累啊攘烛,有了RxAndroid的啟發(fā),我現(xiàn)在是接受不了舊的啟動方式了镀首,怎么辦坟漱?好的,我只好自己寫了一個庫更哄,并且開源了芋齿,托管在github上:SmartKey,大家可以參考一下成翩,如果覺得好請給個星星鼓勵一下觅捆,如果大家有更好的實現(xiàn),也請告訴我一聲麻敌,讓我開開眼界栅炒,提前謝謝大家。終于現(xiàn)在代碼就成了:

SmartTargets.toXXXActivityATarget()
        .params(ParamsIBuilder
            .newBuilder()
            .articleId("id123456")
            .thumbImgUrl("http://www.example.com/example.png"))
        .go(this);

注意,這里SmartTargets類赢赊、ParamsIBuilder類都是自動生成的乙漓,你要做的就是在你的Application類告訴我,你的manifest文件在哪释移,然后把XXXActivity需要的所有參數(shù)叭披,寫一個叫做Params(名字隨意,N個組件可以公用玩讳,只要是通過Bundle涩蜘、Intent傳遞參數(shù)的都可以用)的非常簡單的連getter/setter都省了的POJO用于描述參數(shù),并且在XXXActivity里可以直接用這個Params類訪問到傳進來的參數(shù)熏纯,至于放進Intent的key同诫,忘掉它吧,你放了參數(shù)進ParamsIBuilder豆巨,在目標Activity就能直接問ParamsIBuilder要回Params對象了剩辟,key的事情掐场,還是不用管最好往扔。關于這個庫,我會再寫兩篇博客詳細說一下熊户,兩篇文章題目都想好了萍膛,分別是:《原來Activity跳轉(zhuǎn)還可以這么舒暢》和《如何優(yōu)雅地管理SharedPreferences》,正在編寫中嚷堡。

好了蝗罗,先寫到這里,總結(jié)一下蝌戒,從RxAndroid我學到的額外東西主要兩個:

第一個是方法鏈串塑,讓你可以專心當前的流程,不再為每次從頭寫變量名等分心了北苟,一直點到目的地桩匪,點到天荒地老,別看這么一點點變化友鼻,就像高手喜歡終端上做關鍵的事情一樣傻昙,減少了例行性的參數(shù)名的編寫就像使用終端減少了鼠標使用減少雙手離開鍵盤一樣,能極大的提高效率彩扔。

第二個是一個方法盡可能的接受更少量的參數(shù)妆档,鏈條內(nèi)盡可能保證少于等于一個參數(shù),末端允許偶爾出現(xiàn)兩個三個的參數(shù)虫碉,再多就要認真想想是不是哪里有問題了贾惦,這樣可以讓你的方法更語義化,方法內(nèi)的職責也可以更加單一化了,這樣可以極大減少記憶力的負擔纤虽,不再需要以前那樣經(jīng)常翻看方法簽名了乳绕,相當于家里的電纜換成了光纖,網(wǎng)絡一下子流暢了逼纸,離準時下班又近一步了洋措。

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市杰刽,隨后出現(xiàn)的幾起案子菠发,更是在濱河造成了極大的恐慌,老刑警劉巖贺嫂,帶你破解...
    沈念sama閱讀 218,122評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件滓鸠,死亡現(xiàn)場離奇詭異,居然都是意外死亡第喳,警方通過查閱死者的電腦和手機糜俗,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來曲饱,“玉大人悠抹,你說我怎么就攤上這事±┑恚” “怎么了楔敌?”我有些...
    開封第一講書人閱讀 164,491評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長驻谆。 經(jīng)常有香客問我卵凑,道長,這世上最難降的妖魔是什么胜臊? 我笑而不...
    開封第一講書人閱讀 58,636評論 1 293
  • 正文 為了忘掉前任勺卢,我火速辦了婚禮,結(jié)果婚禮上象对,老公的妹妹穿的比我還像新娘黑忱。我一直安慰自己,他們只是感情好织盼,可當我...
    茶點故事閱讀 67,676評論 6 392
  • 文/花漫 我一把揭開白布杨何。 她就那樣靜靜地躺著,像睡著了一般沥邻。 火紅的嫁衣襯著肌膚如雪危虱。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,541評論 1 305
  • 那天唐全,我揣著相機與錄音埃跷,去河邊找鬼蕊玷。 笑死,一個胖子當著我的面吹牛弥雹,可吹牛的內(nèi)容都是我干的垃帅。 我是一名探鬼主播,決...
    沈念sama閱讀 40,292評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼剪勿,長吁一口氣:“原來是場噩夢啊……” “哼贸诚!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起厕吉,我...
    開封第一講書人閱讀 39,211評論 0 276
  • 序言:老撾萬榮一對情侶失蹤酱固,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后头朱,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體运悲,經(jīng)...
    沈念sama閱讀 45,655評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,846評論 3 336
  • 正文 我和宋清朗相戀三年项钮,在試婚紗的時候發(fā)現(xiàn)自己被綠了班眯。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,965評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡烁巫,死狀恐怖署隘,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情程拭,我是刑警寧澤定踱,帶...
    沈念sama閱讀 35,684評論 5 347
  • 正文 年R本政府宣布棍潘,位于F島的核電站恃鞋,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏亦歉。R本人自食惡果不足惜恤浪,卻給世界環(huán)境...
    茶點故事閱讀 41,295評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望肴楷。 院中可真熱鬧水由,春花似錦、人聲如沸赛蔫。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,894評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽呵恢。三九已至鞠值,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間渗钉,已是汗流浹背彤恶。 一陣腳步聲響...
    開封第一講書人閱讀 33,012評論 1 269
  • 我被黑心中介騙來泰國打工钞钙, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人声离。 一個月前我還...
    沈念sama閱讀 48,126評論 3 370
  • 正文 我出身青樓芒炼,卻偏偏與公主長得像,于是被迫代替她去往敵國和親术徊。 傳聞我的和親對象是個殘疾皇子本刽,可洞房花燭夜當晚...
    茶點故事閱讀 44,914評論 2 355

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務發(fā)現(xiàn)赠涮,斷路器盅安,智...
    卡卡羅2017閱讀 134,657評論 18 139
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,133評論 25 707
  • 1. Java基礎部分 基礎部分的順序:基本語法,類相關的語法世囊,內(nèi)部類的語法别瞭,繼承相關的語法,異常的語法株憾,線程的語...
    子非魚_t_閱讀 31,631評論 18 399
  • 從三月份找實習到現(xiàn)在蝙寨,面了一些公司,掛了不少嗤瞎,但最終還是拿到小米墙歪、百度、阿里贝奇、京東虹菲、新浪、CVTE掉瞳、樂視家的研發(fā)崗...
    時芥藍閱讀 42,246評論 11 349
  • 夜夜夜夜 不知這樣多久了 換了工作之后忙碌了起來 這也是我想要的一種狀態(tài) 忙點好毕源,忙著忙著就會忘了孤獨 好讓自己不...
    閔大喵閱讀 179評論 0 0