朱雀的IT世界

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

           

          一點重構(gòu)心得

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

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

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

          基于昨天的經(jīng)驗,我新總結(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)向。那么如何解決呢,其實是一個度的問題。我給自己定了一個規(guī)矩,臨界點是三個函數(shù)這樣級聯(lián)起來,如果超過三個,我就將它們拆開。比如說上面這個小例子,我會拆成:

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

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

          二、寫過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();
              }
          }


          怎么說呢,這段代碼看上去,其實是夠好了,其實不重構(gòu)也是可以的。也許我偏執(zhí)吧,我認(rèn)為它不夠好,因為:首先,大段的try catch 的確會捕獲異常,但是這段代碼至少有好幾段是會獨立拋出異常的,這里包含了四個IO 實例的創(chuàng)建和銷毀,這四段代碼如果出錯都會拋出異常,那么你捕獲的到底是哪個呢?其次,沒有把功能段合理分開,這段代碼的邏輯功能實際上是兩個,一個是讀,一個是寫,那么合并在一起,首先順序很亂,其次容易讓閱讀的人產(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();
                          }

                      }
                  }


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

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

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

          導(dǎo)航

          統(tǒng)計

          常用鏈接

          留言簿(5)

          隨筆分類

          隨筆檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 白朗县| 崇礼县| 黄平县| 南和县| 安福县| 夏河县| 乐清市| 廉江市| 花莲县| 象州县| 喜德县| 普格县| 布拖县| 延长县| 宣汉县| 和静县| 潍坊市| 苏尼特左旗| 墨玉县| 迭部县| 汉寿县| 讷河市| 梁河县| 平远县| 安平县| 筠连县| 定远县| 康马县| 苏州市| 东兰县| 兰坪| 庐江县| 桃园县| 上杭县| 株洲市| 寿阳县| 巴东县| 长寿区| 蕉岭县| 彝良县| 南华县|