小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

78條高質(zhì)量編碼建議《Effective Java》(1~2)閱讀筆記

 狼圖騰1224 2017-09-26

Java經(jīng)典書籍《Effective Java(第二版)》相信大家都看過,此書共有78條關(guān)于編寫高質(zhì)量Java代碼的建議,這里是通俗易懂地講解,會持續(xù)全部更新完78條,希望大家每天讀一篇,一起學(xué)完這78條,相信可以寫出高質(zhì)量代碼。

1.考慮靜態(tài)工廠方法代替構(gòu)造器

通常情況下我們會利用類的構(gòu)造器對其進行實例化,這似乎毫無疑問。但“靜態(tài)工廠方法”也需要引起我們的高度注意。
  什么是“靜態(tài)工廠方法”?這不同于設(shè)計模式中的工廠方法,我們可以理解它為“在一個類中用一個靜態(tài)方法來返回這個類的實例”,例如:

publica static People getInsatance(){

        return new People();

}


它是一個“方法”,那么它不同于構(gòu)造器,它可以隨意修改方法名,這就帶來第一個優(yōu)點——有名稱。有時一個類的構(gòu)造器往往不止一個,而它們的名稱都是相同的,不同的僅僅是參數(shù),如果不同參數(shù)帶來不同的含義這樣對于調(diào)用方來說除了注釋很難理解它們有什么不同的含義。例如BigInteger(int, int, Random)返回一個素數(shù),但調(diào)用者很難理解API設(shè)計者所要想表達的意思,如果此時有BigInteger.probablePrime靜態(tài)工廠方法,則能一目了然的清楚API設(shè)計者所要想表達的含義。舉一個JDK的例子:Executors類,在這個類中有newFixedThread、newSingleThreadExecutor、newCachedThreadPool等靜態(tài)方法,因為它們有“名字”,所有就較為清晰的明白API的含義。

  《Effective Java》中所提到的靜態(tài)工廠方法第二個優(yōu)點在于不用重復(fù)創(chuàng)建一個對象,實際上也就是勤加載或者稱為餓漢式的單例模式。例如:

        public class Instance() {

            private static Instance instance = new Instance();

            private Instance(){}

            public static Instance getInstance() {

            return instance;

            }

        }

靜態(tài)工廠方法的第三個優(yōu)點,可以返回原返回類型的任何子類型的。這句話初看不好理解,舉個JDK中的例子:Collections類。

        List list = Collections.synchroizedList(new ArrayList())


這個例子就說明了可以返回原返回類型的任何子類型的對象。
  關(guān)于靜態(tài)工廠方法的第四個優(yōu)點,在創(chuàng)建參數(shù)化類型實例的時候,它們使代碼變得更加簡潔,書中舉了一個例子:

        Map<String,List<String>> map = new HashMap<String,List<String>>()//繁瑣


給集合類提供靜態(tài)工廠方法后:


        public static  <K,V>   HashMap<K,V> newInstance(){

              return new HashMap<K,V>();

        }


        HashMap<String,List<String>> map = HashMap.newInstance();


但是實際上從JDK7(包括JDK7)之后的集合類可以用以下簡潔的代碼代替:


        Map<String,List<String>> map = new HashMap<>();


靜態(tài)工廠方法也有兩個缺點一是公有的靜態(tài)方法所返回的非公有類不能被實例化,也就是說Collections.synchronizedList返回的SynchronizedList不能被實例化;二是查找API比較麻煩,它們不像普通的類有構(gòu)造器在API中標(biāo)識出來,而是和其他普通靜態(tài)方法一樣,鑒于此,書中提到了幾種慣用名稱:

  valueOf
  of  
  getInstance
  newInstance
  getType
  newType

2,遇到不同參數(shù)的多個構(gòu)造器考慮用構(gòu)建器

   你經(jīng)常寫一下類似的代碼

    public class Student{

        private Sring name;

        

        private int age;

        

        private String sex;

        

        private String grade;

        

        public Student(String name, String sex){

            this(name,sex,0);

        }

        

       public Student(String name,String sex,int age){

           this(name,sex,age,'');


       }
      public Student(String name,String sex,int age,String grade){

          this.name=name;

          this.sex=sex;

          this.age=age;

          this.grade=grade;

     }

}

當(dāng)我想實例化一個名字叫“kevin”,性別男,但是不寫年齡,只有年級“1年級”,這個時候代碼就:不得不要為年齡這個參數(shù)傳遞值。如果新增一個只含年級的構(gòu)造方法,那又將多出許多代碼,更嚴(yán)重的是,如果沒有一份詳盡的文檔或者注釋,看到如此多的構(gòu)造方法將無從下手,這就是非常常見的重疊構(gòu)造器。

        Student student = new Student('joan','male','0','1年假');


當(dāng)然還有另外一種方法,只有一個必填項的構(gòu)造方法,而其他選填項利用setter方法傳遞。例如:

        Student student = new Student('joan','male');

        student.setGrade('1年級');

這實際上導(dǎo)致了在構(gòu)造過程中JavaBean可能處于不一致的狀態(tài),也就是說實例化對象本該是一氣呵成,但現(xiàn)在卻分割成了兩大步,這會導(dǎo)致它線程不安全,進一步引發(fā)不可預(yù)知的后果。
  書中提到較為“完美”的解決方案就是利用“Builder模式(建造者模式)”,有關(guān)此設(shè)計模式可以查看《建造者模式》。這種解決方案屬建造者模式的一種形式,其核心就是不直接生成想要的對象,而是讓客戶端利用所有必要的參數(shù)調(diào)用構(gòu)造器(或者靜態(tài)工廠),得到一個builder對象,再調(diào)用類似setter的方法設(shè)置相關(guān)可選參數(shù)。構(gòu)建器模式如下所示:

        /**

         * 構(gòu)建器模式

         * Created by yulinfeng on 2017/8/3.

         */

        public class Student {

            /*必填*/

            private String name;

            private int age;

            /*選填*/

            private String sex;

            private String grade;

        

            public static class Builder {

                private String name;

                private int age;

                private String sex = '';

                private String grade = '';

        

                public Builder(String name, int age) {

                    this.name = name;

                    this.age = age;

                }

                public Builder sex(String sex) {

                    this.sex = sex;

                    return this;

                }

                public Builder grade(String grade) {

                    this.grade = grade;

                    return this;

                }

                public Student build() {

                    return new Student(this);

                }

            }

            private Student(Builder builder) {

                this.name = builder.name;

                this.age = builder.age;

                this.sex = builder.sex;

                this.grade = builder.grade;

            }

        }

 以上本質(zhì)上是個靜態(tài)內(nèi)部類
客戶端代碼:

       Student student = new Student.Builder('joan','mea').grade('1年級').build();

這樣的客戶端代碼很容易邊寫,并且便于閱讀。對于不了解的可能來說利用構(gòu)建器模式編寫Student類不算易事,甚至代碼比重疊構(gòu)造器的代碼更多。所以當(dāng)可選參數(shù)在很多時,謹(jǐn)慎使用重疊構(gòu)造器,而是使用構(gòu)建器模式。


今天就這么多了,明天持續(xù)更新,下期內(nèi)容:

3.用私有構(gòu)造器或者枚舉類型強化Singleton屬性

4.通過私又構(gòu)造器強化不可實例的能力



Effective Java(第2版)PDF中英文(有源碼) 下載。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多