Java設(shè)計(jì)模式-----創(chuàng)建型模型

一、簡(jiǎn)單工廠模式:

??簡(jiǎn)單工廠模式通常是這樣:一個(gè)工廠類里面有一個(gè)靜態(tài)方法,根據(jù)不同的參數(shù),返回不同的派生自同一個(gè)父類(或?qū)崿F(xiàn)同一接口)的實(shí)例對(duì)象。

public class FoodFactory {

    public static Food makeFood(String name) {
        if (name.equals("noodle")) {
            Food noodle = new LanZhouNoodle();
            noodle.addSpicy("more");
            return noodle;
        } else if (name.equals("chicken")) {
            Food chicken = new HuangMenChicken();
            chicken.addCondiment("potato");
            return chicken;
        } else {
            return null;
        }
    }
}

二、工廠模式:


??擁有兩個(gè)及以上的工廠(注意其繼承自同一個(gè)父類或接口),然后選擇需要的工廠,再根據(jù)選擇的工廠產(chǎn)生具體的對(duì)象。

三、抽象工廠模式:


注意:抽象工廠的問(wèn)題是顯而易見(jiàn)的,比如要加個(gè)顯示器,就需要修改所有的工廠,給所有的工廠都加上制造顯示器的方法。這有點(diǎn)違反了對(duì)修改關(guān)閉,對(duì)擴(kuò)展開(kāi)放這個(gè)設(shè)計(jì)原則。

四、單例模式:

?1、餓漢模式:

public class Singleton {
    // 首先,將 new Singleton() 堵死
    private Singleton() {};
    // 創(chuàng)建私有靜態(tài)實(shí)例,意味著這個(gè)類第一次使用的時(shí)候就會(huì)進(jìn)行創(chuàng)建
    private static Singleton instance = new Singleton();

    public static Singleton getInstance() {
        return instance;
    }
    // 瞎寫(xiě)一個(gè)靜態(tài)方法。這里想說(shuō)的是,如果我們只是要調(diào)用 Singleton.getDate(...),
    // 本來(lái)是不想要生成 Singleton 實(shí)例的,不過(guò)沒(méi)辦法,已經(jīng)生成了
    public static Date getDate(String mode) {return new Date();}
}

?2、飽漢模式:

public class Singleton {
    // 首先,也是先堵死 new Singleton() 這條路
    private Singleton() {}
    // 和餓漢模式相比,這邊不需要先實(shí)例化出來(lái),注意這里的 volatile,它是必須的
    private static volatile Singleton instance = null;

    public static Singleton getInstance() {
        if (instance == null) {
            // 加鎖
            synchronized (Singleton.class) {
                // 這一次判斷也是必須的,不然會(huì)有并發(fā)問(wèn)題
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

注意:雙重檢查,指的是兩次檢查 instance 是否為 null。

?3、嵌套類:

public class Singleton3 {

    private Singleton3() {}
    // 主要是使用了 嵌套類可以訪問(wèn)外部類的靜態(tài)屬性和靜態(tài)方法 的特性
    private static class Holder {
        private static Singleton3 instance = new Singleton3();
    }
    public static Singleton3 getInstance() {
        return Holder.instance;
    }
}

五、建造者模式:

??先 new 一個(gè) Builder,然后可以鏈?zhǔn)降卣{(diào)用一堆方法,最后再調(diào)用一次 build() 方法,此時(shí)需要的對(duì)象就有了。

class User {
    // 下面是“一堆”的屬性
    private String name;
    private String password;
    private String nickName;
    private int age;

    // 構(gòu)造方法私有化,不然客戶端就會(huì)直接調(diào)用構(gòu)造方法了
    private User(String name, String password, String nickName, int age) {
        this.name = name;
        this.password = password;
        this.nickName = nickName;
        this.age = age;
    }
    // 靜態(tài)方法,用于生成一個(gè) Builder,這個(gè)不一定要有,不過(guò)寫(xiě)這個(gè)方法是一個(gè)很好的習(xí)慣
    public static UserBuilder builder() {
        return new UserBuilder();
    }

    public static class UserBuilder {
        // 下面是和 User 一模一樣的一堆屬性
        private String  name;
        private String password;
        private String nickName;
        private int age;

        private UserBuilder() {
        }

        // 鏈?zhǔn)秸{(diào)用設(shè)置各個(gè)屬性值,返回 this,即 UserBuilder
        public UserBuilder name(String name) {
            this.name = name;
            return this;
        }

        public UserBuilder password(String password) {
            this.password = password;
            return this;
        }

        public UserBuilder nickName(String nickName) {
            this.nickName = nickName;
            return this;
        }

        public UserBuilder age(int age) {
            this.age = age;
            return this;
        }

        // build() 方法負(fù)責(zé)將 UserBuilder 中設(shè)置好的屬性“復(fù)制”到 User 中。
        // 當(dāng)然,可以在 “復(fù)制” 之前做點(diǎn)檢驗(yàn)
        public User build() {
            if (name == null || password == null) {
                throw new RuntimeException("用戶名和密碼必填");
            }
            if (age <= 0 || age >= 150) {
                throw new RuntimeException("年齡不合法");
            }
            // 還可以做賦予”默認(rèn)值“的功能
              if (nickName == null) {
                nickName = name;
            }
            return new User(name, password, nickName, age);
        }
    }
}

核心是:先把所有的屬性都設(shè)置給 Builder,然后 build() 方法的時(shí)候,將這些屬性復(fù)制給實(shí)際產(chǎn)生的對(duì)象。
??此時(shí),客戶端的調(diào)用是:

public class APP {
    public static void main(String[] args) {
        User d = User.builder()
                .name("foo")
                .password("pAss12345")
                .age(25)
                .build();
    }
}

六、原型模式:

??有一個(gè)原型實(shí)例,基于這個(gè)原型實(shí)例產(chǎn)生新的實(shí)例,也就是“克隆”了。Object 類中有一個(gè) clone() 方法,它用于生成一個(gè)新的對(duì)象,如果要調(diào)用這個(gè)方法,java 要求類必須先實(shí)現(xiàn) Cloneable 接口,此接口沒(méi)有定義任何方法,但是不這么做的話,在 clone() 的時(shí)候,會(huì)拋出 CloneNotSupportedException 異常。

protected native Object clone() throws CloneNotSupportedException;

??復(fù)制代碼java 的克隆是淺克隆,碰到對(duì)象引用的時(shí)候,克隆出來(lái)的對(duì)象和原對(duì)象中的引用將指向同一個(gè)對(duì)象。通常實(shí)現(xiàn)深克隆的方法是將對(duì)象進(jìn)行序列化,然后再進(jìn)行反序列化。

七、創(chuàng)建型模式總結(jié):

1、作用:

??為了產(chǎn)生實(shí)例對(duì)象。

2、各模式總結(jié):

??簡(jiǎn)單工廠模式就是根據(jù)類中靜態(tài)方法的參數(shù)不同而產(chǎn)生不同的實(shí)例;
??工廠模式在簡(jiǎn)單工廠模式的基礎(chǔ)上增加了選擇工廠的維度,需要第一步選擇合適的工廠;
??抽象工廠模式有產(chǎn)品族的概念,如果各個(gè)產(chǎn)品是存在兼容性問(wèn)題的,就要用抽象工廠模式。
??單例模式是為了保證全局使用的是同一對(duì)象,一方面是安全性考慮,一方面是為了節(jié)省資源;
??建造者模式專門對(duì)付屬性很多的那種類,為了讓代碼更優(yōu)美;
??原型模式用得最少,了解和 Object 類中的 clone() 方法相關(guān)的知識(shí)即可。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容