潛魚在淵

          Concentrating on Architectures.

          posts - 77, comments - 309, trackbacks - 0, articles - 0
            BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

          代碼檢查(1)

          Posted on 2008-10-25 00:32 非魚 閱讀(2282) 評(píng)論(2)  編輯  收藏 所屬分類: Java技術(shù)
          這個(gè)系列,結(jié)合IDEA的Inspection和我自己的理解編寫。

          抽象問(wèn)題

          1. 把實(shí)例造型(cast)成具體的類型

          這個(gè)問(wèn)題的含義是,當(dāng)?shù)玫揭粋€(gè)實(shí)例時(shí),把它c(diǎn)ast到一個(gè)更加具體的類型使用。這個(gè)問(wèn)題存在于以下場(chǎng)景:
          • 出于個(gè)人原因,比如只熟悉這個(gè)具體的類型、不動(dòng)腦筋的編碼。
          這是新手常見的問(wèn)題。比如可能程序員只熟悉ArrayList,并不知道其上的更加抽象的接口;或者個(gè)人感覺ArrayList更加“好用”。這是不應(yīng)該出現(xiàn)的問(wèn)題,有經(jīng)驗(yàn)的程序員應(yīng)該指導(dǎo)初學(xué)者,避免犯錯(cuò)。
          • 需要的方法不在更抽象的類型中,只在具體類型中才有定義。
          這個(gè)問(wèn)題更多的表示了設(shè)計(jì)層面考慮的不充分。比如組織本身的代碼(非外來(lái)代碼),接口定義的類型不能滿足接口實(shí)現(xiàn)者的具體需求;返回值的類型過(guò)于泛化;本地變量(Local variable)定義的類型過(guò)于泛化等等。這些問(wèn)題一般意味著在設(shè)計(jì)上考慮不周,導(dǎo)致了對(duì)象交互過(guò)程中的“對(duì)接不順利”,這是設(shè)計(jì)上的不一致,需要對(duì)設(shè)計(jì)進(jìn)行仔細(xì)評(píng)估。以下是幾個(gè)這樣的例子:

          public Collection aMethod(Collection c) {
            List list = (List)c;
            Object o = list.get(0); // Collection中沒有g(shù)et方法。導(dǎo)致實(shí)現(xiàn)者必須cast。
            ...
          }

          public void test() {
            // 返回值必須cast才能使用更加具體的方法。
            List alist = (List)aMethod(Arrays.asList(new String[]{"1", "2"}));
            Object obj = alist.get(0);
            ...
          }

          public someMethod() {
            MyInterface mi = new MyImplementation();
            ...
            // 大部分時(shí)間調(diào)用MyInterface中的方法,但忽然發(fā)現(xiàn)有某個(gè)地方需要調(diào)用特定的非接口實(shí)現(xiàn):
            int count = ((MyImplementation)mi).specialMethod();
            ...
          }

          最后這個(gè)例子,可能是方法的實(shí)現(xiàn)本身的問(wèn)題,比如完全可以直接使用MyImplementation來(lái)定義變量mi;也可能是抽象問(wèn)題,即沒有把本來(lái)具有普遍性的方法放到接口中,而是放到了具體實(shí)現(xiàn)中。
          • 受環(huán)境約束,必須安全的使用造型。
          上面談到的設(shè)計(jì)問(wèn)題,是指的組織內(nèi)部的設(shè)計(jì)。在很多時(shí)候,需要使用外部的接口和實(shí)現(xiàn),這些接口因?yàn)榭紤]了更加廣泛的使用環(huán)境而采用了更加泛化的接口。這就需要順應(yīng)已經(jīng)存在的設(shè)計(jì)來(lái)實(shí)現(xiàn),不得不使用cast。但同時(shí)也要注意,在不得不cast的時(shí)候,一定要安全的使用cast,比如安全檢查或者安全的類型轉(zhuǎn)換,下面是示例:

          public boolean equals(Object o) {
            if (o == null) return false;
            if (o instanceof MyClass) { // 安全檢查!
              MyClass mc = (MyClass)o;
              // 調(diào)用MyClass中的特定方法。
              ...
          }

          public method() {
            Collection c = aMethodReturnsCollection();
            List list = new ArrayList(c); //安全的類型轉(zhuǎn)換,把Collection轉(zhuǎn)換成List。
            ...
          }


          , , ,


          評(píng)論

          # re: 編碼問(wèn)題(1)[未登錄]  回復(fù)  更多評(píng)論   

          2008-10-27 13:37 by xxx
          inspection

          # re: 編碼問(wèn)題(1)  回復(fù)  更多評(píng)論   

          2008-10-27 19:04 by 非魚
          @xxx
          Thanks, corrected.
          主站蜘蛛池模板: 维西| 甘泉县| 保山市| 金堂县| 康保县| 本溪市| 昌乐县| 莱州市| 德安县| 凤城市| 凤山市| 新源县| 林芝县| 淮南市| 双鸭山市| 屏东市| 永顺县| 印江| 三明市| 施甸县| 奉化市| 武陟县| 岚皋县| 额尔古纳市| 洪洞县| 嵊州市| 普宁市| 安化县| 德令哈市| 四川省| 贵港市| 西充县| 资中县| 常宁市| 许昌县| 浦城县| 清丰县| 莱州市| 滦南县| 陕西省| 宝应县|