朱雀的IT世界

          每天進(jìn)步一點(diǎn)點(diǎn),努力做好自己

           

          一點(diǎn)重構(gòu)心得

          昨天,要寫一段程序完成一個定時任務(wù),是有關(guān)Socket 發(fā)送的。胖子給我發(fā)了一段現(xiàn)成的程序,這段程序基本上的功能是實(shí)現(xiàn)了,但是表達(dá)的并不是那么清晰,因此我想重構(gòu)一下。沒想到重構(gòu)的過程竟然花了一個多小時,從晚上八點(diǎn)多,一下就寫到了十點(diǎn),但是重構(gòu)完后,感覺清晰多了。仔細(xì)想想收獲頗多,因此在這里寫寫經(jīng)驗(yàn)進(jìn)行總結(jié)。

          重構(gòu)程序的目的,不是因?yàn)槌绦虿荒苡貌乓闳ブ貥?gòu),重構(gòu)的目的是因?yàn)橐弧⒛愕拇a,被人看的次數(shù),遠(yuǎn)比它用到的次數(shù)多;二、重構(gòu)有利于你發(fā)現(xiàn)問題,讓你的程序結(jié)構(gòu)優(yōu)化,因此可復(fù)用性更強(qiáng),遵守了知識的唯一性,DRY 原則;三、如果你要改動這段代碼,那么先重構(gòu),使得你的代碼好改,這實(shí)際是在為你的未來減少工作量,而且一段優(yōu)秀的代碼,帶給你的價值,遠(yuǎn)比你每次都要Ctrl+C,Ctrl+V 大得多。

          寫代碼,要讓你的代碼第一次呈現(xiàn)在別人面前的時候,像讀英語一般,那么你的代碼功底是足夠了。你的代碼就可以稱作你最好的文檔了,其余什么文檔,大可不必!

          基于昨天的經(jīng)驗(yàn),我新總結(jié)了兩條:
          一、經(jīng)常使用重構(gòu)方法extract method 的人,會發(fā)現(xiàn),總是可以省掉一些臨時變量。這是好事,但這可能會造成如下的結(jié)果:

          method_one(method_two(method_three(method_four())))

          也就是說,很可能會導(dǎo)致這種長串的嵌套,導(dǎo)致程序可讀性的下降,使人看的暈頭轉(zhuǎn)向。那么如何解決呢,其實(shí)是一個度的問題。我給自己定了一個規(guī)矩,臨界點(diǎn)是三個函數(shù)這樣級聯(lián)起來,如果超過三個,我就將它們拆開。比如說上面這個小例子,我會拆成:

          arg = method_three(method(four));
          method_one(method_two(arg));

          雖然浪費(fèi)了一個臨時變量,但是這樣就可以讓人一眼看懂我的意思,可讀性提升,修改起來自然也會容易些。

          二、寫過Java I/O 的人,肯定看到過這樣的程序:

          Reader in = null;
          Writer out = null;
          try
          {
              in = new InputStreamReader(socket.getInputStream(),"utf8");
              out = new OutputStreamWriter(socket.getOutputStream(),"utf8");

          /**
           * some TODOs here
           *
          **/
          }catch(IOException ioe)
          {
              System.err.println("error message");
              ioe.printStackTrace();
          }
          finally
          {
             try
              {
                  if(in != null)
                     in.close();
                  if(out != null)
                     out.close();
              }catch(IOException ioe2)
              {
                 System.err.println("some error message");
                 ioe2.printStackTrace();
              }
          }


          怎么說呢,這段代碼看上去,其實(shí)是夠好了,其實(shí)不重構(gòu)也是可以的。也許我偏執(zhí)吧,我認(rèn)為它不夠好,因?yàn)椋菏紫龋蠖蔚膖ry catch 的確會捕獲異常,但是這段代碼至少有好幾段是會獨(dú)立拋出異常的,這里包含了四個IO 實(shí)例的創(chuàng)建和銷毀,這四段代碼如果出錯都會拋出異常,那么你捕獲的到底是哪個呢?其次,沒有把功能段合理分開,這段代碼的邏輯功能實(shí)際上是兩個,一個是讀,一個是寫,那么合并在一起,首先順序很亂,其次容易讓閱讀的人產(chǎn)生困惑,從而造成代碼可讀性差。我是這樣做的:

          private void writeFile(String fileName, String outStr)
                  {
                      Writer writer = null;
                      try
                      {
                          writer = new OutputStreamWriter(new FileOutputStream(fileName),
                                  "utf8");
                      }
                      catch (UnsupportedEncodingException e)
                      {
                          System.err.println("不支持的編碼方式");
                          e.printStackTrace();
                      }
                      catch (FileNotFoundException e)
                      {
                          System.err.println("初始化文件失敗,或路徑不存在:" + fileName);
                          e.printStackTrace();
                      }
                      try
                      {
                          writer.write(outStr);
                          writer.flush();
                      }
                      catch (IOException e)
                      {
                          System.err.println("寫文件失敗");
                          e.printStackTrace();
                      }
                      finally
                      {
                          try
                          {
                              if(writer != null)
                                  writer.close();
                          }
                          catch (IOException e)
                          {
                              System.err.println("關(guān)閉文件失敗");
                              e.printStackTrace();
                          }

                      }
                  }


          類似的,也將讀的邏輯獨(dú)立抽出來,雖然,這不但沒使代碼的量減少,卻增加了很多try catch 模塊,不過邏輯上很完整,而且發(fā)揮了每個try catch 的最佳功效。我把它起名曰,我個人的偏執(zhí)情節(jié)吧。

          困了,要睡覺了,本來還想將代碼從最初模樣,到最后模樣的過程復(fù)述一遍,改天有機(jī)會再說,精華都已經(jīng)說了。嘿嘿

          posted on 2008-01-08 23:56 朱雀 閱讀(352) 評論(0)  編輯  收藏 所屬分類: java 基礎(chǔ)應(yīng)用

          導(dǎo)航

          統(tǒng)計

          常用鏈接

          留言簿(5)

          隨筆分類

          隨筆檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 临汾市| 都匀市| 石棉县| 神池县| 高要市| 梓潼县| 修水县| 调兵山市| 拉萨市| 改则县| 洱源县| 金堂县| 沂水县| 旅游| 始兴县| 曲沃县| 洱源县| 黑龙江省| 德清县| 正宁县| 万宁市| 泰兴市| 裕民县| 丰镇市| 独山县| 武邑县| 梧州市| 兴海县| 利辛县| 海丰县| 阿图什市| 新源县| 满城县| 兴国县| 泌阳县| 修水县| 石家庄市| 中西区| 永平县| 松潘县| 临猗县|