一篇文章帶你了解設計模式——創建者模式
在之前的文章中我們已經學習了設計模式的基本原則和基本分類
下面我們來介紹第一種設計模式,創建型模式的主要關注點是怎樣創建物件,它的主要特點是“將物件的創建與使用分離”,
下面我們將從下面四個方面講述五種創建者模式:
- 單例模式
- 工廠模式
- 原型模式
- 建造者模式
單例模式
首先我們來介紹單例模式
單例模式介紹
單例模式在我的文章中已經是第三次出現了,所以下面我們做一個簡單的介紹:
- 單例模式屬于創建型模式,它提供了一種創建物件的最佳方式
- 該模式涉及到一個單一的類,該類負責創建自己的物件,同時確保只有單個物件被創建,
- 這個類提供了一種訪問其唯一的物件的方式,可以直接訪問,不需要實體化該類的物件,
單例模式主要有以下角色:
- 單例類:只能創建一個實體的類
- 訪問類:使用單例類
單例模式展示
單例模式的創建主要分為三種,下面我們來一一介紹:
- 餓漢式
/*
餓漢式:類加載就會導致該單實體物件被創建
*/
/**
* 餓漢式
* 靜態變數創建類的物件
*/
public class Singleton {
// 私有構造方法
private Singleton() {}
// 在成員位置創建該類的物件并直接初始化
private static Singleton instance = new Singleton();
// 對外提供靜態方法獲取該物件
public static Singleton getInstance() {
return instance;
}
}
/**
* 餓漢式
* 在靜態代碼塊中創建該類物件
*/
public class Singleton {
//私有構造方法
private Singleton() {}
//在成員位置創建該類的物件
private static Singleton instance;
// 直接在靜態代碼塊中進行初始化,一旦類產生就直接創建單例物件,為餓漢式
static {
instance = new Singleton();
}
//對外提供靜態方法獲取該物件
public static Singleton getInstance() {
return instance;
}
}
- 懶漢式
/*
懶漢式:類加載不會導致該單實體物件被創建,而是首次使用該物件時才會創建
*/
/**
* 懶漢式
* 執行緒不安全
*/
public class Singleton {
//私有構造方法
private Singleton() {}
//在成員位置創建該類的物件
private static Singleton instance;
//對外提供靜態方法獲取該物件
public static Singleton getInstance() {
if(instance == null) {
instance = new Singleton();
}
return instance;
}
}
/**
* 懶漢式
* 執行緒安全
*/
public class Singleton {
//私有構造方法
private Singleton() {}
//在成員位置創建該類的物件
private static Singleton instance;
//對外提供靜態方法獲取該物件
public static synchronized Singleton getInstance() {
if(instance == null) {
instance = new Singleton();
}
return instance;
}
}
/**
* 懶漢式
* 雙重檢查方式
*/
public class Singleton {
//私有構造方法
private Singleton() {}
private static volatile Singleton instance;
//對外提供靜態方法獲取該物件
public static Singleton getInstance() {
//第一次判斷,如果instance不為null,不進入搶鎖階段,直接回傳實際
if(instance == null) {
synchronized (Singleton.class) {
//搶到鎖之后再次判斷是否為空
if(instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
/**
* 懶漢式
* 靜態內部類方式
*/
public class Singleton {
//私有構造方法
private Singleton() {}
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
//對外提供靜態方法獲取該物件
public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
- 惡漢式
/*
惡漢式:采用非類的方法創建單例物件
*/
/**
* 惡漢式
* 列舉方式
*/
public enum Singleton {
INSTANCE;
}
單例模式應對策略
單例模式通常會出現三種錯誤,其中兩種是可以處理的:
- 預防反射破壞單例物件
/*
反射破壞單例物件原理:
通過反射獲得類本身,通過類的構造方法創建新的類物件以破壞單例物件
預防反射破壞單例物件原理:
修改類的構造方法,使構造方式失效或者使構造方法直接回傳單例物件而不是創建新的物件
*/
/*代碼展示*/
public class Singleton implements Serializable{
// 首先我們需要擁有一個私有的構造方法(為了防止其他物件呼叫構造方法產生新物件)
private Singleton(){
// 這里我們需要做一個判斷,如果已存在單例物件,且其他物件呼叫構造方法,直接報錯(為了預防反射獲得類然后新創物件)
if( INSTANCE != null){
throw new RuntimeException("單例物件不可重復創建");
}
System.out.println("private Singleton");
}
private static final Singleton INSTANCE = new Singleton();
public static Singleton getInstance(){
return INSTANCE;
}
public static void otherMethod(){
System.out.println("otherMethod");
}
}
- 預防反序列化破壞單例物件
/*
反序列化破壞單例物件原理:
呼叫readResolve方法使用位元組流輸入輸出獲得新的物件
預防反序列化破壞單例物件原理:
重寫readResolve方法使其直接回傳單例物件
*/
/*代碼展示*/
public class Singleton implements Serializable {
//私有構造方法
private Singleton() {}
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
//對外提供靜態方法獲取該物件
public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
/**
* 下面是為了解決序列化反序列化破解單例模式
*/
private Object readResolve() {
return SingletonHolder.INSTANCE;
}
}
工廠模式
下面我們來介紹工廠模式,主要會介紹到三種工廠模式的使用
工廠模式思考
在正式介紹工廠模式之前,我們首先給出沒有工廠模式會出現的問題:

具體問題:
/*
需求:
設計一個咖啡店點餐系統,
具體想法:
設計一個咖啡類(Coffee),并定義其兩個子類(美式咖啡【AmericanCoffee】和拿鐵咖啡【LatteCoffee】);
再設計一個咖啡店類(CoffeeStore),咖啡店具有點咖啡的功能,
問題展示:
在java中,萬物皆物件,這些物件都需要創建,如果創建的時候直接new該物件,就會對該物件耦合嚴重,假如我們要更換物件,所有new物件的地方都需要修改一遍,這顯然違背了軟體設計的開閉原則,如果我們使用工廠來生產物件,我們就只和工廠打交道就可以了,徹底和物件解耦,如果要更換物件,直接在工廠里更換該物件即可,達到了與物件解耦的目的;所以說,工廠模式最大的優點就是:解耦,
*/
簡單工廠模式
簡單工廠模式不是二十三種設計模式成員,他更傾向于是一種思想
簡單工廠模式結構
簡單工廠包含如下角色:
- 抽象產品 :定義了產品的規范,描述了產品的主要特性和功能,
- 具體產品 :實作或者繼承抽象產品的子類
- 具體工廠 :提供了創建產品的方法,呼叫者通過該方法來獲取產品,
簡單工廠模式實戰
我們如果使用簡單工廠模式去修改前面的問題:

具體分析:
/*
工廠(factory)處理創建物件的細節,一旦有了SimpleCoffeeFactory,CoffeeStore類中的orderCoffee()就變成此物件的客戶,后期如果需要Coffee物件直接從工廠中獲取即可,這樣也就解除了和Coffee實作類的耦合,同時又產生了新的耦合,CoffeeStore物件和SimpleCoffeeFactory工廠物件的耦合,工廠物件和商品物件的耦合,
后期如果再加新品種的咖啡,我們勢必要需求修改SimpleCoffeeFactory的代碼,違反了開閉原則,工廠類的客戶端可能有很多,比如創建美團外賣等,這樣只需要修改工廠類的代碼,省去其他的修改操作,
*/
/* 工廠類代碼 */
public class SimpleCoffeeFactory {
public Coffee createCoffee(String type) {
Coffee coffee = null;
if("americano".equals(type)) {
coffee = new AmericanoCoffee();
} else if("latte".equals(type)) {
coffee = new LatteCoffee();
}
return coffee;
}
}
簡單工廠模式分析
我們分別給出簡單工廠模式的優缺點:
- 優點
封裝了創建物件的程序,可以通過引數直接獲取物件,把物件的創建和業務邏輯層分開,這樣以后就避免了修改客戶代碼,如果要實作新產品直接修改工廠類,而不需要在原代碼中修改,這樣就降低了客戶代碼修改的可能性,更加容易擴展,
- 缺點
增加新產品時還是需要修改工廠類的代碼,違背了“開閉原則”,
簡單工廠模式擴展
我們以簡單工廠模式為基準可以創新出靜態工廠模式(注:靜態工廠模式也不是二十三種設計模式成員):
public class SimpleCoffeeFactory {
// 將方法設定為靜態,主類可以直接使用工廠的方法而省去創建物件的一步
public static Coffee createCoffee(String type) {
Coffee coffee = null;
if("americano".equals(type)) {
coffee = new AmericanoCoffee();
} else if("latte".equals(type)) {
coffee = new LatteCoffee();
}
return coffe;
}
}
工廠方法模式
工廠方法模式屬于二十三種設計模式成員
定義一個用于創建物件的介面,讓子類決定實體化哪個產品類物件;工廠方法使一個產品類的實體化延遲到其工廠的子類,
工廠方法模式結構
工廠方法模式的主要角色:
- 抽象工廠(Abstract Factory):提供了創建產品的介面,呼叫者通過它訪問具體工廠的工廠方法來創建產品,
- 具體工廠(ConcreteFactory):主要是實作抽象工廠中的抽象方法,完成具體產品的創建,
- 抽象產品(Product):定義了產品的規范,描述了產品的主要特性和功能,
- 具體產品(ConcreteProduct):實作了抽象產品角色所定義的介面,由具體工廠來創建,它同具體工廠之間一一對應,
工廠方法模式實戰
我們如果使用工廠方法模式去修改前面的問題:

具體分析:
/*
要增加產品類時也要相應地增加工廠類,不需要修改工廠類的代碼了,這樣就解決了簡單工廠模式的缺點,
工廠方法模式是簡單工廠模式的進一步抽象,由于使用了多型性,工廠方法模式保持了簡單工廠模式的優點,而且克服了它的缺點,
*/
/* 咖啡店類 */
public class CoffeeStore {
private CoffeeFactory factory;
public CoffeeStore(CoffeeFactory factory) {
this.factory = factory;
}
public Coffee orderCoffee(String type) {
Coffee coffee = factory.createCoffee();
coffee.addMilk();
coffee.addsugar();
return coffee;
}
}
/* 抽象工廠 */
public interface CoffeeFactory {
Coffee createCoffee();
}
/* 具體工廠 */
public class LatteCoffeeFactory implements CoffeeFactory {
public Coffee createCoffee() {
return new LatteCoffee();
}
}
public class AmericanCoffeeFactory implements CoffeeFactory {
public Coffee createCoffee() {
return new AmericanCoffee();
}
}
工廠方法模式分析
我們分別給出工廠方法模式的優缺點:
- 優點
用戶只需要知道具體工廠的名稱就可得到所要的產品,無須知道產品的具體創建程序;
在系統增加新的產品時只需要添加具體產品類和對應的具體工廠類,無須對原工廠進行任何修改,滿足開閉原則;
- 缺點
每增加一個產品就要增加一個具體產品類和一個對應的具體工廠類,這增加了系統的復雜度,
抽象工廠模式
抽象工廠模式屬于二十三種設計模式成員
抽象工廠模式實際上就是工廠方法模式的升級模式,他將一系列相關的類的創建都產生在同一個工廠中,使其一個工廠類產生多個產品類
抽象工廠模式結構
抽象工廠模式的主要角色如下:
- 抽象工廠(Abstract Factory):提供了創建產品的介面,它包含多個創建產品的方法,可以創建多個不同等級的產品,
- 具體工廠(Concrete Factory):主要是實作抽象工廠中的多個抽象方法,完成具體產品的創建,
- 抽象產品(Product):定義了產品的規范,描述了產品的主要特性和功能,抽象工廠模式有多個抽象產品,
- 具體產品(ConcreteProduct):實作了抽象產品角色所定義的介面,由具體工廠來創建,它 同具體工廠之間是多對一的關系,
抽象工廠模式實戰
我們的例題發生了一點點的改變,我們所需要的產品類增多后,單單使用工廠方法模式顯得過于繁雜:

具體分析:
/*
題目更改:
現咖啡店業務發生改變,不僅要生產咖啡還要生產甜點,如提拉米蘇、抹茶慕斯等,要是按照工廠方法模式,需要定義提拉米蘇類、抹茶慕斯類、提拉米蘇工廠、抹茶慕斯工廠、甜點工廠類,很容易發生類爆炸情況,其中拿鐵咖啡、美式咖啡是一個產品等級,都是咖啡;提拉米蘇、抹茶慕斯也是一個產品等級;拿鐵咖啡和提拉米蘇是同一產品族(也就是都屬于意大利風味),美式咖啡和抹茶慕斯是同一產品族(也就是都屬于美式風味),所以這個案例可以使用抽象工廠模式實作,
*/
/* 抽象工廠 */
public interface DessertFactory {
Coffee createCoffee();
Dessert createDessert();
}
/* 具體工廠 */
//美式甜點工廠
public class AmericanDessertFactory implements DessertFactory {
public Coffee createCoffee() {
return new AmericanCoffee();
}
public Dessert createDessert() {
return new MatchaMousse();
}
}
//意大利風味甜點工廠
public class ItalyDessertFactory implements DessertFactory {
public Coffee createCoffee() {
return new LatteCoffee();
}
public Dessert createDessert() {
return new Tiramisu();
}
抽象工廠模式分析
我們首先給出抽象工廠模式的適用場景:
-
當需要創建的物件是一系列相互關聯或相互依賴的產品族時,如電器工廠中的電視機、洗衣機、空調等,
-
系統中有多個產品族,但每次只使用其中的某一族產品,如有人只喜歡穿某一個品牌的衣服和鞋,
-
系統中提供了產品的類別庫,且所有產品的介面相同,客戶端不依賴產品實體的創建細節和內部結構,
-
如:輸入法換皮膚,一整套一起換,生成不同作業系統的程式,
我們再分別給出抽象工廠模式的優缺點:
- 優點
當一個產品族中的多個物件被設計成一起作業時,它能保證客戶端始終只使用同一個產品族中的物件,
- 缺點
當產品族中需要增加一個新的產品時,所有的工廠類都需要進行修改,
原型模式
下面我們來介紹原型模式
原型模式介紹
首先我們對原型模式做一個簡單的介紹:
- 用一個已經創建的實體作為原型,通過復制該原型物件來創建一個和原型物件相同的新物件,
原型模式結構
原型模式包含如下角色:
- 抽象原型類:規定了具體原型物件必須實作的的 clone() 方法,
- 具體原型類:實作抽象原型類的 clone() 方法,它是可被復制的物件,
- 訪問類:使用具體原型類中的 clone() 方法來復制新的物件,
原型模式關系圖如下:

原型模式實作
原型模式的實作主要分為兩種實作方式:
- 淺克隆:創建一個新物件,新物件的屬性和原來物件完全相同,對于非基本型別屬性,仍指向原有屬性所指向的物件的記憶體地址,
- 深克隆:創建一個新物件,屬性中參考的其他物件也會被克隆,不再指向原有物件地址,
其主要實作方法來自于:
- Java中的Object類中提供了 clone() 方法來實作淺克隆,
- Cloneable 介面是上面的類圖中的抽象原型類,而實作了Cloneable介面的子實作類就是具體的原型類,
我們給出一個簡單的原型模式實作:
/* 抽象原型類:實際上就是Object,已經實作了clone方法 */
/* 具體原型類 */
public class Realizetype implements Cloneable {
public Realizetype() {
System.out.println("具體的原型物件創建完成!");
}
@Override
protected Realizetype clone() throws CloneNotSupportedException {
System.out.println("具體原型復制成功!");
return (Realizetype) super.clone();
}
}
/* 測驗訪問類 */
public class PrototypeTest {
public static void main(String[] args) throws CloneNotSupportedException {
Realizetype r1 = new Realizetype();
Realizetype r2 = r1.clone();
System.out.println("物件r1和r2是同一個物件?" + (r1 == r2));
}
}
原型模式案例
我們首先給出一個簡單的案例:
- 同一學校的“三好學生”獎狀除了獲獎人姓名不同,其他都相同
- 可以使用原型模式復制多個“三好學生”獎狀出來,然后在修改獎狀上的名字即可,
那么我們可以直接使用淺克隆來完成上述案例:
//獎狀類
public class Citation implements Cloneable {
private String name;
public void setName(String name) {
this.name = name;
}
public String getName() {
return (this.name);
}
public void show() {
System.out.println(name + "同學:在2020學年第一學期中表現優秀,被評為三好學生,特發此狀!");
}
@Override
public Citation clone() throws CloneNotSupportedException {
return (Citation) super.clone();
}
}
//測驗訪問類
public class CitationTest {
public static void main(String[] args) throws CloneNotSupportedException {
Citation c1 = new Citation();
c1.setName("張三");
//復制獎狀
Citation c2 = c1.clone();
//將獎狀的名字修改李四
c2.setName("李四");
c1.show();
c2.show();
}
}
但是當我們修改了內部屬性,將簡單物件改為了參考物件時,兩者的參考物件都會指向原本的地址,就會導致修改一處造成全部修改
所以我們可以采用深克隆來完成這個操作:
//獎狀類
public class Citation implements Cloneable {
private Student stu;
public Student getStu() {
return stu;
}
public void setStu(Student stu) {
this.stu = stu;
}
void show() {
System.out.println(stu.getName() + "同學:在2020學年第一學期中表現優秀,被評為三好學生,特發此狀!");
}
@Override
public Citation clone() throws CloneNotSupportedException {
return (Citation) super.clone();
}
}
//學生類
public class Student {
private String name;
private String address;
public Student(String name, String address) {
this.name = name;
this.address = address;
}
public Student() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
// 測驗訪問類
public class CitationTest1 {
public static void main(String[] args) throws Exception {
Citation c1 = new Citation();
Student stu = new Student("張三", "西安");
c1.setStu(stu);
//創建物件輸出流物件
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("C:\\Users\\Think\\Desktop\\b.txt"));
//將c1物件寫出到檔案中
oos.writeObject(c1);
oos.close();
//創建物件出入流物件
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("C:\\Users\\Think\\Desktop\\b.txt"));
//讀取物件
Citation c2 = (Citation) ois.readObject();
//獲取c2獎狀所屬學生物件
Student stu1 = c2.getStu();
stu1.setName("李四");
//判斷stu物件和stu1物件是否是同一個物件
System.out.println("stu和stu1是同一個物件?" + (stu == stu1));
c1.show();
c2.show();
}
}
建造者模式
最后我們來介紹建造者模式,它將一個復雜物件的構建與表示分離,使得同樣的構建程序可以創建不同的表示,
建造者模式介紹
我們首先來介紹一下建造者模式:
- 分離了部件的構造(由Builder來負責)和裝配(由Director負責), 從而可以構造出復雜的物件,這個模式適用于:某個物件的構建程序復雜的情況,
- 由于實作了構建和裝配的解耦,不同的構建器,相同的裝配,也可以做出不同的物件;相同的構建器,不同的裝配順序也可以做出不同的物件,也就是實作了構建演算法、裝配演算法的解耦,實作了更好的復用,
- 建造者模式可以將部件和其組裝程序分開,一步一步創建一個復雜的物件,用戶只需要指定復雜物件的型別就可以得到該物件,而無須知道其內部的具體構造細節,
建造者模式結構
建造者(Builder)模式包含如下角色:
-
抽象建造者類(Builder):這個介面規定要實作復雜物件的那些部分的創建,并不涉及具體的部件物件的創建,
-
具體建造者類(ConcreteBuilder):實作 Builder 介面,完成復雜產品的各個部件的具體創建方法,在構造程序完成后,提供產品的實體,
-
產品類(Product):要創建的復雜物件,
-
指揮者類(Director):呼叫具體建造者來創建復雜物件的各個部分,在指導者中不涉及具體產品的資訊,只負責保證物件各部分完整創建或按某種順序創建,
建造者模式關系圖如下:

建造者模式實作
我們同樣通過一個簡單的例子來展示建造者模式:

具體分析:
/*
題目介紹:
生產自行車是一個復雜的程序,它包含了車架,車座等組件的生產,
而車架又有碳纖維,鋁合金等材質的,車座有橡膠,真皮等材質,
對于自行車的生產就可以使用建造者模式,
關系圖介紹:
這里Director是指揮者;
Bike是產品,包含車架,車座等組件;
Builder是抽象建造者,MobikeBuilder和OfoBuilder是具體的建造者;
*/
/* 具體代碼展示 */
//自行車類
public class Bike {
private String frame;
private String seat;
public String getFrame() {
return frame;
}
public void setFrame(String frame) {
this.frame = frame;
}
public String getSeat() {
return seat;
}
public void setSeat(String seat) {
this.seat = seat;
}
}
// 抽象 builder 類
public abstract class Builder {
protected Bike mBike = new Bike();
public abstract void buildFrame();
public abstract void buildSeat();
public abstract Bike createBike();
}
//摩拜單車Builder類
public class MobikeBuilder extends Builder {
@Override
public void buildFrame() {
mBike.setFrame("鋁合金車架");
}
@Override
public void buildSeat() {
mBike.setSeat("真皮車座");
}
@Override
public Bike createBike() {
return mBike;
}
}
//ofo單車Builder類
public class OfoBuilder extends Builder {
@Override
public void buildFrame() {
mBike.setFrame("碳纖維車架");
}
@Override
public void buildSeat() {
mBike.setSeat("橡膠車座");
}
@Override
public Bike createBike() {
return mBike;
}
}
//指揮者類
public class Director {
private Builder mBuilder;
public Director(Builder builder) {
mBuilder = builder;
}
public Bike construct() {
mBuilder.buildFrame();
mBuilder.buildSeat();
return mBuilder.createBike();
}
}
//測驗類
public class Client {
public static void main(String[] args) {
showBike(new OfoBuilder());
showBike(new MobikeBuilder());
}
private static void showBike(Builder builder) {
Director director = new Director(builder);
Bike bike = director.construct();
System.out.println(bike.getFrame());
System.out.println(bike.getSeat());
}
}
/* 部分代碼優化:有些情況下需要簡化系統結構,可以把指揮者類和抽象建造者進行結合 */
// 抽象 builder 類
public abstract class Builder {
protected Bike mBike = new Bike();
public abstract void buildFrame();
public abstract void buildSeat();
public abstract Bike createBike();
public Bike construct() {
this.buildFrame();
this.BuildSeat();
return this.createBike();
}
}
建造者模式分析
首先我們給出建造者模式的主要適用場景:
- 創建的物件較復雜,由多個部件構成,各部件面臨著復雜的變化,但構件間的建造順序是穩定的,
- 創建復雜物件的演算法獨立于該物件的組成部分以及它們的裝配方式,即產品的構建程序和最終的表示是獨立的,
然后我們給出建造者模式的優點:
- 建造者模式的封裝性很好,使用建造者模式可以有效的封裝變化,在使用建造者模式的場景中,一般產品類和建造者類是比較穩定的,因此,將主要的業務邏輯封裝在指揮者類中對整體而言可以取得比較好的穩定性,
- 在建造者模式中,客戶端不必知道產品內部組成的細節,將產品本身與產品的創建程序解耦,使得相同的創建程序可以創建不同的產品物件,
- 可以更加精細地控制產品的創建程序 ,將復雜產品的創建步驟分解在不同的方法中,使得創建程序更加清晰,也更方便使用程式來控制創建程序,
- 建造者模式很容易進行擴展,如果有新的需求,通過實作一個新的建造者類就可以完成,基本上不用修改之前已經測驗通過的代碼,因此也就不會對原有功能引入風險,符合開閉原則,
最后我們給出建造者模式的缺點:
- 造者模式所創建的產品一般具有較多的共同點,其組成部分相似
- 如果產品之間的差異性很大,則不適合使用建造者模式,因此其使用范圍受到一定的限制,
建造者模式擴展
建造者模式的另一個營業場景也包括:
- 當一個類構造器需要傳入很多引數時,如果創建這個類的實體,代碼可讀性會非常差,而且很容易引入錯誤
- 此時就可以利用建造者模式進行重構,
我們給出一個簡單例子:
/* 原版代碼 */
public class Phone {
private String cpu;
private String screen;
private String memory;
private String mainboard;
public Phone(String cpu, String screen, String memory, String mainboard) {
this.cpu = cpu;
this.screen = screen;
this.memory = memory;
this.mainboard = mainboard;
}
public String getCpu() {
return cpu;
}
public void setCpu(String cpu) {
this.cpu = cpu;
}
public String getScreen() {
return screen;
}
public void setScreen(String screen) {
this.screen = screen;
}
public String getMemory() {
return memory;
}
public void setMemory(String memory) {
this.memory = memory;
}
public String getMainboard() {
return mainboard;
}
public void setMainboard(String mainboard) {
this.mainboard = mainboard;
}
@Override
public String toString() {
return "Phone{" +
"cpu='" + cpu + '\'' +
", screen='" + screen + '\'' +
", memory='" + memory + '\'' +
", mainboard='" + mainboard + '\'' +
'}';
}
}
public class Client {
public static void main(String[] args) {
//構建Phone物件
Phone phone = new Phone("intel","三星螢屏","金士頓","華碩");
System.out.println(phone);
}
}
/* 建造者模式代碼 */
public class Phone {
private String cpu;
private String screen;
private String memory;
private String mainboard;
private Phone(Builder builder) {
cpu = builder.cpu;
screen = builder.screen;
memory = builder.memory;
mainboard = builder.mainboard;
}
public static final class Builder {
private String cpu;
private String screen;
private String memory;
private String mainboard;
public Builder() {}
public Builder cpu(String val) {
cpu = val;
return this;
}
public Builder screen(String val) {
screen = val;
return this;
}
public Builder memory(String val) {
memory = val;
return this;
}
public Builder mainboard(String val) {
mainboard = val;
return this;
}
public Phone build() {
return new Phone(this);}
}
@Override
public String toString() {
return "Phone{" +
"cpu='" + cpu + '\'' +
", screen='" + screen + '\'' +
", memory='" + memory + '\'' +
", mainboard='" + mainboard + '\'' +
'}';
}
}
public class Client {
public static void main(String[] args) {
Phone phone = new Phone.Builder()
.cpu("intel")
.mainboard("華碩")
.memory("金士頓")
.screen("三星")
.build();
System.out.println(phone);
}
}
結束語
關于創建者模式我們就介紹到這里,后面我會繼續更新二十三種設計模式,希望能給你帶來幫助~
附錄
該文章屬于學習內容,具體參考B站黑馬程式員的Java設計模式詳解
這里附上視頻鏈接:22.設計模式-創建型模式-單例設計模式概述_嗶哩嗶哩_bilibili
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/542641.html
標籤:設計模式
下一篇:訊息中間件RabbitMQ
