一、簡(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í)即可。