国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

24種設(shè)計(jì)模式之創(chuàng)建者模式-Java版

這篇具有很好參考價(jià)值的文章主要介紹了24種設(shè)計(jì)模式之創(chuàng)建者模式-Java版。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

軟件設(shè)計(jì)模式是前輩們代碼設(shè)計(jì)經(jīng)驗(yàn)的總結(jié),可以反復(fù)使用。設(shè)計(jì)模式共分為3大類,創(chuàng)建者模式(6種)、結(jié)構(gòu)型模式(7種)、行為型模式(11種),一共24種設(shè)計(jì)模式,軟件設(shè)計(jì)一般需要滿足7大基本原則。下面通過5章的學(xué)習(xí)一起來看看設(shè)計(jì)模式的魅力吧。

創(chuàng)建型模式(6種):本質(zhì)上就是將對(duì)象的創(chuàng)建與使用分離,就是描述怎樣去創(chuàng)建對(duì)象。

包括:單例、簡單工廠、工廠方法、抽象工廠、原型、建造者 模式

創(chuàng)建型模式的對(duì)比:

工廠方法模式VS建造者模式

工廠方法模式更注重對(duì)象的創(chuàng)建方式,建造者模式更注重部件的創(chuàng)建過程。

抽象工廠模式VS建造者模式

抽象工廠模式是對(duì)產(chǎn)品家族的創(chuàng)建,建造者模式是指按照指定的藍(lán)圖建造產(chǎn)品。

目錄

1.1、單例模式

1.2、簡單工廠模式

1.3、工廠方法模式

1.4、抽象工廠模式

1.5、原型模式

1.6、建造者模式


1.1、單例模式

單例模式是最簡單的設(shè)計(jì)模式之一,屬于創(chuàng)建者模式,提供了一種創(chuàng)建對(duì)象的最佳方式,類中只創(chuàng)建一個(gè)實(shí)例對(duì)象,并提供訪問對(duì)象的方式。單例模式是指確保一個(gè)類在任何情況下都只有一個(gè)實(shí)例,并且提供一個(gè)訪問該單例的全局訪問點(diǎn)。

單例模式分為餓漢模式與懶漢模式兩種。餓漢式是線程安全的,但是類加載的時(shí)候就創(chuàng)建實(shí)例對(duì)象,如果后期不使用,會(huì)造成內(nèi)存的浪費(fèi)。

餓漢模式:類加載的時(shí)候,實(shí)例對(duì)象使用之前,就創(chuàng)建了實(shí)例對(duì)象

懶漢模式:類加載的時(shí)候沒創(chuàng)建,使用的時(shí)候,才創(chuàng)建實(shí)例對(duì)象

餓漢模式可以通過靜態(tài)成員變量的方式創(chuàng)建實(shí)例,也可以通過靜態(tài)代碼塊的方式創(chuàng)建實(shí)例。

/**
 * @author nuist__NJUPT
 * @ClassName Singleton
 * @description: 餓漢式-靜態(tài)成員變量
 * @date 2024年01月19日
 */
public class Singleton {
    // 1.私有構(gòu)造方法,避免外界創(chuàng)建帶參數(shù)的實(shí)例化對(duì)象
    private Singleton(){}

    // 2.在本類中創(chuàng)建本類的實(shí)例化對(duì)象
    private static Singleton instance  = new Singleton() ;

    // 3.提供一個(gè)訪問該實(shí)例對(duì)象的方式,讓外界訪問
    public static Singleton getInstance(){
        return instance ;
    }

}
/**
 * @author nuist__NJUPT
 * @ClassName Singleton1
 * @description: 餓漢模式-靜態(tài)代碼塊
 * @date 2024年01月19日
 */
public class Singleton1 {

    private Singleton1(){}

    private static Singleton1 instance ;

    {
     instance = new Singleton1() ;
    }

     public static Singleton1 getInstance() {
        return instance;
    }


}

通過測試類可以發(fā)現(xiàn)創(chuàng)建的兩個(gè)實(shí)例對(duì)象是同一個(gè)對(duì)象,即單例。

/**
 * @author nuist__NJUPT
 * @ClassName Client
 * @description: 測試類
 * @date 2024年01月19日
 */
public class Client {
    public static void main(String[] args) {
        Singleton instance1 = Singleton.getInstance() ;
        Singleton instance2 = Singleton.getInstance() ;
        System.out.println(instance1 == instance2) ;

        Singleton1 singleton1 = Singleton1.getInstance() ;
        Singleton1 singleton11 = Singleton1.getInstance() ;
        System.out.println(singleton1 == singleton11) ;
    }
}

懶漢模式是類加載的時(shí)候不創(chuàng)建實(shí)例,在使用的時(shí)候才創(chuàng)建,需要使用雙重檢查鎖的機(jī)制保證線程安全,即保證只創(chuàng)建一個(gè)實(shí)例。

/**
 * @author nuist__NJUPT
 * @ClassName Singleton
 * @description: 懶漢模式-雙重檢查鎖方式
 * @date 2024年01月19日
 */
public class Singleton {
    // 1.私有構(gòu)造方法
    private Singleton(){

    }
    // 2.定義實(shí)例對(duì)象
    // jvm在實(shí)例化對(duì)象會(huì)進(jìn)行優(yōu)化和指令重排序操作,故使用雙重檢測瑣在多線程可能會(huì)出現(xiàn)空指針問題
    // 使用volatile關(guān)鍵字可以保證可見性和有序性
    private static volatile Singleton instance ;

    //3.對(duì)外提供訪問方式

    /**
     * 雙重檢查鎖瑣的方式保證線程安全
     * @return 實(shí)例對(duì)象
     */
    public static Singleton getInstance() {
        // 如果instance不為空,不需要搶占瑣,直接返回對(duì)象
        if(instance == null){
            synchronized (Singleton.class) {
               // 搶到瑣之后再次判斷是否為空
               if(instance == null){
                   instance = new Singleton() ;
               }
            }

        }
        return instance;
    }
}

序列化與反序列化、以及反射的方式會(huì)破壞單例模式,需要進(jìn)一步解決相應(yīng)的問題。

JDK源碼中Runtime類對(duì)象是單例模式,餓漢式的方式實(shí)現(xiàn)。

單例模式應(yīng)用的場景一般發(fā)現(xiàn)在以下條件下:

 ?。?)資源共享的情況下,避免由于資源操作時(shí)導(dǎo)致的性能或損耗等。如日志文件,應(yīng)用配置。

 ?。?)控制資源的情況下,方便資源之間的互相通信。如線程池等。

日志系統(tǒng):在應(yīng)用程序中,通常只需要一個(gè)日志系統(tǒng),以避免在多個(gè)地方創(chuàng)建多個(gè)日志對(duì)象,并降低資源消耗。
數(shù)據(jù)庫連接池:在應(yīng)用程序中,數(shù)據(jù)庫連接池是一個(gè)非常重要的資源,單例模式可以確保在應(yīng)用程序中只有一個(gè)數(shù)據(jù)庫連接池實(shí)例,避免資源浪費(fèi)。
配置文件管理器:在應(yīng)用程序中,通常只需要一個(gè)配置文件管理器來管理應(yīng)用程序的配置文件,單例模式可以確保在整個(gè)應(yīng)用程序中只有一個(gè)配置文件管理器實(shí)例。
緩存系統(tǒng):在應(yīng)用程序中,緩存系統(tǒng)是一個(gè)重要的組件,單例模式可以確保在整個(gè)應(yīng)用程序中只有一個(gè)緩存實(shí)例,以提高應(yīng)用程序的性能。
GUI組件:在圖形用戶界面(GUI)開發(fā)中,單例模式可以確保在整個(gè)應(yīng)用程序中只有一個(gè)GUI組件實(shí)例,以確保用戶界面的一致性和穩(wěn)定性。
?

1.2、簡單工廠模式

簡單工廠模式:簡單工廠模式可以理解為一種編程習(xí)慣,簡單工廠包含如下三個(gè)角色:

01.抽象產(chǎn)品:定義產(chǎn)品的規(guī)范,主要包括產(chǎn)品的功能與特性。

02.具體產(chǎn)品:實(shí)現(xiàn)或者繼承抽象產(chǎn)品。

03.具體工廠:提供創(chuàng)建產(chǎn)品的方法,調(diào)用者通過該方法來獲取產(chǎn)品。

優(yōu)點(diǎn):要實(shí)現(xiàn)新產(chǎn)品直接修改工廠類代碼即可,避免客戶端代碼修改,更容易擴(kuò)展。

缺點(diǎn):增加新產(chǎn)品還是需要修改工廠類,在一定程度上違反了開閉原則。

1.我們看個(gè)案例,定義一個(gè)抽象產(chǎn)品咖啡,定義兩個(gè)具體產(chǎn)品美式咖啡和拿鐵咖啡。

/**
 * @author nuist__NJUPT
 * @ClassName Coffee
 * @description: 咖啡類-抽象產(chǎn)品
 * @date 2024年01月19日
 */
public abstract class Coffee {

    public abstract String getName() ;

    public void addSugar(){
        System.out.println("加糖");
    }

    public void addMilk(){
        System.out.println("加奶");
    }

}
/**
 * @author nuist__NJUPT
 * @ClassName LatteCoffee
 * @description: 拿鐵咖啡-具體產(chǎn)品
 * @date 2024年01月19日
 */
public class LatteCoffee extends Coffee{

    @Override
    public String getName() {
        return "拿鐵咖啡";
    }
}
/**
 * @author nuist__NJUPT
 * @ClassName AmericanCoffee
 * @description: 美式咖啡-具體產(chǎn)品
 * @date 2024年01月19日
 */
public class AmericanCoffee extends Coffee {

    @Override
    public String getName() {
        return "美式咖啡";
    }

}

2.定義一個(gè)coffee工廠進(jìn)行咖啡生產(chǎn),解耦咖啡店和具體咖啡的關(guān)系。

/**
 * @author nuist__NJUPT
 * @ClassName SimpleCoffeeFactory
 * @description: 簡單coffee工廠
 * @date 2024年01月19日
 * @version: 1.0
 */
public class SimpleCoffeeFactory {

    /**
     * 生產(chǎn)coffee方法
     * @param type 咖啡類型
     * @return 咖啡
     */
    public Coffee createCoffee(String type){
        Coffee coffee = null ;
        if(type.equals("american")){
            coffee = new AmericanCoffee() ;
        }else if(type.equals("latte")){
            coffee = new AmericanCoffee() ;
        }else {
            throw new RuntimeException("沒有您要的coffee") ;
        }
        return coffee ;
    }

}

3.咖啡店直接調(diào)用簡單咖啡工廠進(jìn)行咖啡生產(chǎn)。這樣咖啡店不需要直接與具體的咖啡交互,只需要和工廠交互,工廠完成具體的咖啡生產(chǎn)管理,可以實(shí)現(xiàn)模塊之間的解耦。

/**
 * @author nuist__NJUPT
 * @ClassName CoffeeStore
 * @description: coffee店
 * @date 2024年01月19日
 */
public class CoffeeStore {
    /**
     * 生產(chǎn)coffee方法
     * @param type 咖啡類型
     * @return 咖啡
     */
    public Coffee createCoffee(String type){
        SimpleCoffeeFactory simpleCoffeeFactory = new SimpleCoffeeFactory() ;
        Coffee coffee = simpleCoffeeFactory.createCoffee(type);
        coffee.addSugar();
        coffee.addMilk();
        return coffee ;
    }
}

4.編寫測試類進(jìn)行測試。

/**
 * @author nuist__NJUPT
 * @ClassName Client
 * @description: 測試類
 * @date 2024年01月19日
 */
public class Client {
    public static void main(String[] args) {
        CoffeeStore coffeeStore = new CoffeeStore() ;
        Coffee latte = coffeeStore.createCoffee("latte");
        System.out.println(latte.getName());

    }
}
1.3、工廠方法模式

工廠方法模式可以避免簡單工廠模式違反開閉原則的問題。

工廠方法模式:定義一個(gè)用于創(chuàng)建對(duì)象的接口(工廠),讓子類對(duì)象決定實(shí)例化哪個(gè)產(chǎn)品對(duì)象,使一個(gè)產(chǎn)品的實(shí)例化延遲到其工廠的子類。

工廠方法模式的主要角色如下:

01.抽象產(chǎn)品:定義產(chǎn)品的規(guī)范,主要包括產(chǎn)品的功能與特性。

02.具體產(chǎn)品:實(shí)現(xiàn)或者繼承抽象產(chǎn)品。

03.具體工廠:實(shí)現(xiàn)抽象工廠中的方法,完成具體產(chǎn)品的創(chuàng)建。

04.抽象工廠:提供創(chuàng)建產(chǎn)品的接口,調(diào)用者通過抽象工廠訪問具體工廠的工廠方法來創(chuàng)建產(chǎn)品。

優(yōu)點(diǎn):封裝性比較好,只需知道具體工廠名字就可以得到產(chǎn)品,無需知道產(chǎn)品的創(chuàng)建過程。另外新增加產(chǎn)品的時(shí)候只需要增加抽象工廠的實(shí)現(xiàn)類即可,原抽象工廠不需要改動(dòng),滿足開閉原則。

缺點(diǎn):只能生產(chǎn)統(tǒng)一等級(jí)的產(chǎn)品,不支持生產(chǎn)多等級(jí)的產(chǎn)品

1.我們使用工廠方法模式改進(jìn)上述的簡單工廠模式,首先定義一個(gè)抽象產(chǎn)品咖啡和兩個(gè)具體產(chǎn)品拿鐵咖啡和美式咖啡類,與上面的一樣。

2.然后我們定義抽象咖啡工廠接口與咖啡工廠接口的實(shí)現(xiàn)類(具體工廠)。

/**
 * @author nuist__NJUPT
 * @InterfaceName CoffeeFactory
 * @description: 抽象工廠接口
 * @date 2024年01月19日
 */
public interface CoffeeFactory {
    // 創(chuàng)建咖啡對(duì)象
    Coffee createCoffee() ;
}
/**
 * @author nuist__NJUPT
 * @ClassName AmericanCoffeeFactory
 * @description: 抽象工廠實(shí)現(xiàn)類
 * @date 2024年01月19日
 */
public class AmericanCoffeeFactory implements CoffeeFactory {

    @Override
    public Coffee createCoffee() {
        return new AmericanCoffee();
    }
}
/**
 * @author nuist__NJUPT
 * @ClassName LatteCoffeeFactory
 * @description: 咖啡工廠實(shí)現(xiàn)類
 * @date 2024年01月19日
 */
public class LatteCoffeeFactory implements CoffeeFactory{


    @Override
    public Coffee createCoffee() {
        return new LatteCoffee();
    }
}

3.接下來就可以在咖啡店中注入抽象工廠,而不是具體工廠。

/**
 * @author nuist__NJUPT
 * @ClassName CoffeeStore
 * @description: coffee店
 * @date 2024年01月19日
 */
public class CoffeeStore {

    private CoffeeFactory coffeeFactory ;

    public void setCoffeeFactory(CoffeeFactory coffeeFactory) {
        this.coffeeFactory = coffeeFactory;
    }

    /**
     * 點(diǎn)coffee方法
     * @return 咖啡
     */
    public Coffee orderCoffee(){
        Coffee coffee = coffeeFactory.createCoffee();
        coffee.addMilk();
        coffee.addSugar();
        return coffee ;
    }
}

4.最后編寫測試類測試點(diǎn)咖啡功能。


/**
 * @author nuist__NJUPT
 * @ClassName Client
 * @description: 測試類
 * @date 2024年01月19日
 */
public class Client {
    public static void main(String[] args) {
        // 實(shí)例化咖啡店
        CoffeeStore coffeeStore = new CoffeeStore() ;
        // 面向抽象工廠接口實(shí)例化具體咖啡工廠
        CoffeeFactory coffeeFactory = new AmericanCoffeeFactory() ;
        // 在咖啡店注入抽象咖啡工廠
        coffeeStore.setCoffeeFactory(coffeeFactory);
        // 調(diào)用方法點(diǎn)咖啡
        Coffee coffee = coffeeStore.orderCoffee();
        System.out.println(coffee.getName());

    }
}
1.4、抽象工廠模式

工廠方法模式是用于生產(chǎn)同一等級(jí)的多種產(chǎn)品,對(duì)于不同等級(jí)的產(chǎn)品,使用抽象工廠生產(chǎn)。

抽象工廠模式:生產(chǎn)多等級(jí)的產(chǎn)品,將一個(gè)具體工廠生產(chǎn)的不同等級(jí)的產(chǎn)品的一組產(chǎn)品成為產(chǎn)品族。

抽象工廠模式的主要角色如下:

01.抽象產(chǎn)品:定義產(chǎn)品的規(guī)范,主要包括產(chǎn)品的功能與特性。

02.具體產(chǎn)品:實(shí)現(xiàn)或者繼承抽象產(chǎn)品。

03.具體工廠:實(shí)現(xiàn)抽象工廠中的方法,完成具體產(chǎn)品的創(chuàng)建。

04.抽象工廠:提供創(chuàng)建產(chǎn)品的接口,包含多個(gè)創(chuàng)建產(chǎn)品的方法,可以創(chuàng)建多個(gè)不同等級(jí)的產(chǎn)品。

優(yōu)點(diǎn):當(dāng)一個(gè)產(chǎn)品族中多個(gè)對(duì)象被設(shè)計(jì)在一起工作的時(shí)候,能保證客戶端始終只使用同一個(gè)產(chǎn)品族的對(duì)象。

缺點(diǎn):當(dāng)產(chǎn)品族中需要增加一個(gè)產(chǎn)品的時(shí)候,所有的工廠類都需要修改。

Java的JDK源碼的迭代器遍歷集合用的就是抽象工廠方法。

24種設(shè)計(jì)模式之創(chuàng)建者模式-Java版,設(shè)計(jì)模式,設(shè)計(jì)模式,java

我們下面看一個(gè)案例,還是咖啡的案例,不過這次加了甜品,屬于同族的產(chǎn)品。

1.首先定義抽象產(chǎn)品咖啡和甜品,然后定義具體的拿鐵咖啡和美式咖啡、以及具體的兩種甜品。

/**
 * @author nuist__NJUPT
 * @ClassName Coffee
 * @description: 咖啡類-抽象產(chǎn)品
 * @date 2024年01月19日
 */
public abstract class Coffee {

    public abstract String getName() ;

    public void addSugar(){
        System.out.println("加糖");
    }

    public void addMilk(){
        System.out.println("加奶");
    }

}
/**
 * @author nuist__NJUPT
 * @ClassName AmericanCoffee
 * @description: 美式咖啡-具體產(chǎn)品
 * @date 2024年01月19日
 */
public class AmericanCoffee extends Coffee {

    @Override
    public String getName() {
        return "美式咖啡";
    }

}
/**
 * @author nuist__NJUPT
 * @ClassName LatteCoffee
 * @description: 拿鐵咖啡-具體產(chǎn)品
 * @date 2024年01月19日
 */
public class LatteCoffee extends Coffee {

    @Override
    public String getName() {
        return "拿鐵咖啡";
    }
}
/**
 * @author nuist__NJUPT
 * @ClassName Dessert
 * @description: 甜品抽象類
 * @date 2024年01月19日
 */
public abstract class Dessert {
    public abstract void show() ;
}
/**
 * @author nuist__NJUPT
 * @ClassName MatchaMousse
 * @description: 抹茶慕斯類
 * @date 2024年01月19日
 */
public class MatchaMousse extends Dessert {

    @Override
    public void show() {
        System.out.println("抹茶慕斯");
    }
}
/**
 * @author nuist__NJUPT
 * @ClassName Trimisu
 * @description: 提拉米蘇類
 * @date 2024年01月19日
 */
public class Trimisu extends Dessert {

    @Override
    public void show() {
        System.out.println("提拉米蘇類");
    }
}

2.定義一個(gè)抽象工廠,用于生產(chǎn)同族產(chǎn)品。

/**
 * @author nuist__NJUPT
 * @InterfaceName DessertFactory
 * @description: 甜品工廠
 * @date 2024年01月19日
 */
public interface DessertFactory {

    // 生產(chǎn)咖啡
    Coffee createCoffee() ;
    // 生產(chǎn)天甜品
    Dessert createDessert() ;

}

3.定義抽象工廠具體的實(shí)現(xiàn)類,用于生產(chǎn)具體的同族產(chǎn)品。

/**
 * @author nuist__NJUPT
 * @ClassName AmericanDessertFactory
 * @description: 美式甜品工廠:即能生產(chǎn)美式咖啡,也能生產(chǎn)抹茶慕斯
 * @date 2024年01月19日
 */
public class AmericanDessertFactory implements DessertFactory{

    @Override
    public Coffee createCoffee() {
        return new AmericanCoffee();
    }

    @Override
    public Dessert createDessert() {
        return new MatchaMousse();
    }
}
/**
 * @author nuist__NJUPT
 * @ClassName ItalyDessertFactory
 * @description: 意大利風(fēng)味的甜品工廠
 * @date 2024年01月19日
 */
public class ItalyDessertFactory implements DessertFactory {

    @Override
    public Coffee createCoffee() {
        return new LatteCoffee();
    }

    @Override
    public Dessert createDessert() {
        return new Trimisu();
    }
}

4.定義測試類,實(shí)例化工廠實(shí)現(xiàn)類,并生產(chǎn)調(diào)用方法生產(chǎn)同族產(chǎn)品。

/**
 * @author nuist__NJUPT
 * @ClassName Client
 * @description: 測試類
 * @date 2024年01月19日
 */
public class Client {
    public static void main(String[] args) {
        // 創(chuàng)建抽象工廠對(duì)象
        // AmericanDessertFactory factory = new AmericanDessertFactory() ;
        ItalyDessertFactory factory = new ItalyDessertFactory() ;
        //生產(chǎn)咖啡和甜品等產(chǎn)品
        Coffee coffee = factory.createCoffee();
        Dessert dessert = factory.createDessert();

        System.out.println(coffee.getName());
        dessert.show();

    }
}
1.5、原型模式

原型模式:用一個(gè)已經(jīng)創(chuàng)建的實(shí)例作為原型,通過復(fù)制該原型對(duì)象創(chuàng)建一個(gè)和該原型對(duì)象相同的對(duì)象。

原型模式包含如下角色:
01.抽象原型類:規(guī)定了具體原型對(duì)象必須實(shí)現(xiàn)的clone()方法

02.具體原型類:實(shí)現(xiàn)抽象原型類的clone()方法,它是可被復(fù)制的對(duì)象

03.訪問類:使用具體原型類的clone()方法來復(fù)制新對(duì)象

深克?。嚎寺』绢愋蛿?shù)據(jù)與其地址

淺克?。翰豢寺〉刂罚豢寺』緮?shù)據(jù)

我們看一個(gè)原型模式的案例,同一個(gè)學(xué)校的三好學(xué)生獎(jiǎng)狀除了學(xué)生名字外其余都相同,我們可以使用原型模式復(fù)制多個(gè)三好學(xué)生的獎(jiǎng)狀,然后修改名字即可。

1.定義原型對(duì)象,實(shí)現(xiàn)Cloneable接口并重寫clone()方法。

/**
 * @author nuist__NJUPT
 * @ClassName Citation
 * @description: 原型對(duì)象
 * @date 2024年01月19日
 */
public class Citation implements Cloneable{

    // 三好學(xué)生的姓名
    private String name ;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void show(){
        System.out.println(name + "同學(xué)獲得三好學(xué)生獎(jiǎng)狀");
    }

    @Override
    protected Citation clone() throws CloneNotSupportedException {
        return (Citation) super.clone();
    }
}

2.定義測試類,實(shí)例化原型對(duì)象,并克隆原型對(duì)象,并調(diào)用原型對(duì)象的方法。

/**
 * @author nuist__NJUPT
 * @ClassName Client
 * @description: 測試類
 * @date 2024年01月19日
 */
public class Client {
    public static void main(String[] args) throws CloneNotSupportedException {
        // 創(chuàng)建原型對(duì)象
        Citation citation = new Citation() ;

        // 克隆出來的原型對(duì)象
        // 對(duì)象的創(chuàng)建比較復(fù)雜的情況下,可以使用原型對(duì)象克隆,而不是創(chuàng)建對(duì)象
        Citation citation1 = citation.clone();

        citation.setName("張三");
        citation1.setName("李四");

        citation.show();
        citation1.show();
        
    }

}

對(duì)于淺克隆克隆的對(duì)象還是同一個(gè)對(duì)象,對(duì)象的地址并沒有改變,會(huì)導(dǎo)致一些問題,java可以通過序列化和反序列化的方式實(shí)現(xiàn)深克隆。

如下定義一個(gè)Student實(shí)體,定義一個(gè)原型類進(jìn)行深克隆,定義測試類通過反序列化實(shí)現(xiàn)深克隆。

import java.io.Serializable;

/**
 * @author nuist__NJUPT
 * @ClassName Student
 * @description: TODO
 * @date 2024年01月19日
 */
public class Student implements Serializable {

    private String name ;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                '}';
    }
}

import java.io.Serializable;

/**
 * @author nuist__NJUPT
 * @ClassName Citation
 * @description: 原型對(duì)象
 * @date 2024年01月19日
 */
public class Citation implements Cloneable, Serializable {

    Student student ;

    public Student getStudent() {
        return student;
    }

    public void setStudent(Student student) {
        this.student = student;
    }

    public void show(){
        System.out.println(student.getName() + "同學(xué)獲得三好學(xué)生獎(jiǎng)狀");
    }

    @Override
    protected Citation clone() throws CloneNotSupportedException {
        return (Citation) super.clone();
    }
}
import java.io.*;

/**
 * @author nuist__NJUPT
 * @ClassName Client
 * @description: 測試類
 * @date 2024年01月19日
 */
public class Client {
    public static void main(String[] args) throws CloneNotSupportedException, IOException, ClassNotFoundException {
        // 創(chuàng)建原型對(duì)象
        Citation citation = new Citation() ;
        Student student = new Student() ;
        student.setName("張三");
        citation.setStudent(student);

        // 克隆出來的原型對(duì)象
        // 對(duì)象的創(chuàng)建比較復(fù)雜的情況下,可以使用原型對(duì)象克隆,而不是創(chuàng)建對(duì)象
        // Citation citation1 = citation.clone();

        // 通過序列化與反序列化的方式進(jìn)行深克隆
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("file.txt")) ;
        oos.writeObject(citation);
        oos.close();
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("file.txt")) ;
        Citation citation1 = (Citation) ois.readObject();
        ois.close();

        citation1.getStudent().setName("李四");

        // 同一個(gè)student對(duì)象,淺克隆導(dǎo)致修改之后會(huì)覆蓋之前的
        citation.show();
        citation1.show();

    }

}
1.6、建造者模式

建造者模式:將復(fù)雜對(duì)象的構(gòu)造與裝配分離,就是將組件與整體進(jìn)行分離,使得同樣的裝配組件的過程可以生產(chǎn)出不同的整體。

建造者模式包含如下幾個(gè)角色:

01.抽象建造者類:該接口規(guī)定了實(shí)現(xiàn)復(fù)雜對(duì)象的那部分創(chuàng)建,并不涉及具體部件對(duì)象的創(chuàng)建。

02.具體建造者類:實(shí)現(xiàn)抽象類接口,完成復(fù)雜對(duì)象的具體創(chuàng)建,提供產(chǎn)品的實(shí)例。

03.產(chǎn)品類:要?jiǎng)?chuàng)建的復(fù)雜對(duì)象。

04.指揮者類:完成具體裝配的過程,不涉及具體的產(chǎn)品信息,只保證對(duì)象各部分的完整創(chuàng)建。

建造者模式的優(yōu)缺點(diǎn)如下:

優(yōu)點(diǎn):封裝性較好,建造過程可以封裝到具體建造者類中,產(chǎn)品與組裝過程解耦,復(fù)雜的步驟可以分解在不同的方法中,易擴(kuò)展,擴(kuò)展的話只需要增加一個(gè)具體建造者類即可,滿足開閉原則 。

缺點(diǎn):如果創(chuàng)建的產(chǎn)品差異性較大不適合使用

建造者模式適用場景:適合于產(chǎn)品組件復(fù)雜但是建造過程的算法相對(duì)穩(wěn)定。

1.下面我們通過共享單車構(gòu)建過程的案例去進(jìn)一步學(xué)習(xí)一下建造者模式。首先我們定義具體的產(chǎn)品類Bike,即需要構(gòu)建的對(duì)象。

/**
 * @author nuist__NJUPT
 * @ClassName Bike
 * @description: 單車產(chǎn)品類
 * @date 2024年01月20日
 */
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;
    }
}

2.下面定義抽象建造者類,在抽象建造者類中定義建造規(guī)則,并定義具體建造者類實(shí)現(xiàn)具體的規(guī)則。


/**
 * @author nuist__NJUPT
 * @ClassName Builder
 * @description: 抽象建造者類
 * @date 2024年01月20日
 */
public abstract class Builder {
    // 聲明Bike類型
    protected Bike bike = new Bike() ;
    // 構(gòu)建車架
    public abstract void buildFrame() ;
    // 構(gòu)建車座
    public abstract void buildSeat() ;
    // 構(gòu)建自行車
    public abstract Bike createBike() ;

}
/**
 * @author nuist__NJUPT
 * @ClassName MobileBuilder
 * @description: 具體的建造者-摩拜單車構(gòu)建者
 * @date 2024年01月20日
 */
public class MobileBuilder extends Builder {

    @Override
    public void buildFrame() {
        bike.setFrame("碳纖維車架");
    }

    @Override
    public void buildSeat() {
        bike.setSeat("假皮車座");
    }

    @Override
    public Bike createBike() {
        return bike ;
    }
}
/**
 * @author nuist__NJUPT
 * @ClassName OfoBuilder
 * @description: Ofo單車建造者
 * @date 2024年01月20日
 */
public class OfoBuilder extends Builder{

    @Override
    public void buildFrame() {
        bike.setFrame("鋁合金車架");
    }

    @Override
    public void buildSeat() {
        bike.setSeat("牛皮車座");
    }

    @Override
    public Bike createBike() {
        return bike;
    }
}

3.定義指揮者類,負(fù)責(zé)指導(dǎo)對(duì)象的建造過程,確保產(chǎn)品的創(chuàng)建。

/**
 * @author nuist__NJUPT
 * @ClassName Director
 * @description: 指揮者類
 * 指揮者類在建造者模式中負(fù)責(zé)指導(dǎo)具體建造者如何建造產(chǎn)品,
 * 控制好調(diào)用的先后順序,并向調(diào)用者返回完整的產(chǎn)品類
 * 在某些場景中可以將指揮者類和抽象建造者類進(jìn)行融合,也就是把construct方法放到Builder類中
 * @date 2024年01月20日
 */
public class Director {
    // 注入建造者
    private Builder builder ;

    public Director(Builder builder) {
        this.builder = builder;
    }

    /**
     *  構(gòu)建單車方法
     * @return 單車
     */
    public Bike construct(){
        builder.buildFrame();
        builder.buildSeat();
        Bike bike = builder.createBike();
        return bike ;
    }
}

4.最后定義測試類進(jìn)行測試是否建造完成,實(shí)例化指揮者類并注入具體的建造者,指揮完成具體產(chǎn)品的建造。

/**
 * @author nuist__NJUPT
 * @ClassName Client
 * @description: 測試類
 * @date 2024年01月20日
 */
public class Client {
    public static void main(String[] args) {
        // 創(chuàng)建指揮者對(duì)象
        Director director = new Director(new MobileBuilder()) ;
        // 指揮者指揮組裝自行車
        Bike construct = director.construct();
        // 打印
        System.out.println(construct.getFrame() + construct.getSeat());

    }
}

我們通過下面一個(gè)案例看一下傳統(tǒng)的構(gòu)造器傳參和利用建造者模式傳參,建造者模式代碼可讀性更好,參數(shù)位置可以在客戶端定義,不需要在構(gòu)造器中寫死,更靈活。

1.傳統(tǒng)的構(gòu)造器傳參,如下:

/**
 * @author nuist__NJUPT
 * @ClassName Phone1
 * @description: 傳統(tǒng)的構(gòu)造傳參
 * @date 2024年01月20日
 */
public class Phone1 {
    private String cpu ;
    private String screen ;
    private String memory ;
    private String mainBoard ;

    public Phone1(String cpu, String screen, String memory, String mainBoard) {
        this.cpu = cpu;
        this.screen = screen;
        this.memory = memory;
        this.mainBoard = mainBoard;
    }

    @Override
    public String toString() {
        return "Phone1{" +
                "cpu='" + cpu + '\'' +
                ", screen='" + screen + '\'' +
                ", memory='" + memory + '\'' +
                ", mainBoard='" + mainBoard + '\'' +
                '}';
    }


}

2.使用建造者模式,利用指揮者控制傳參順序。

/**
 * @author nuist__NJUPT
 * @ClassName Phone
 * @description: 建造者模式改進(jìn)的構(gòu)造器
 * @date 2024年01月20日
 */
public class Phone {
    private String cpu ;
    private String screen ;
    private String memory ;
    private String mainBoard ;

    private Phone(Builder builder){
        this.cpu = builder.cpu ;
        this.screen = builder.screen ;
        this.memory = builder.memory ;
        this.mainBoard = builder.mainBoard ;
    }

    @Override
    public String toString() {
        return "Phone{" +
                "cpu='" + cpu + '\'' +
                ", screen='" + screen + '\'' +
                ", memory='" + memory + '\'' +
                ", mainBoard='" + mainBoard + '\'' +
                '}';
    }

    public static final class Builder{
        private String cpu ;
        private String screen ;
        private String memory ;
        private String mainBoard ;

        public Builder cpu(String cpu){
            this.cpu = cpu ;
            return this ;
        }
        public Builder memory(String memory){
            this.memory = memory ;
            return this ;
        }
        public Builder screen(String screen){
            this.screen = screen ;
            return this ;
        }
        public Builder mainBoard(String mainBoard){
            this.mainBoard = mainBoard ;
            return this ;
        }
        public Phone build(){
            return new Phone(this) ;
        }

    }

}

3.最后定義測試類進(jìn)行測試,觀察兩種傳參方式,可以發(fā)現(xiàn)建造者模式可以改變傳參順序,靈活性強(qiáng),同時(shí)可讀性也更高。文章來源地址http://www.zghlxwxcb.cn/news/detail-813749.html

/**
 * @author nuist__NJUPT
 * @ClassName Client
 * @description: 測試類
 * @date 2024年01月20日
 */
public class Client {
    public static void main(String[] args) {
        // 創(chuàng)建指揮者對(duì)象
        Phone phone = new Phone.Builder()
                .cpu("英特爾CPU")
                .memory("金士頓內(nèi)存")
                .mainBoard("聯(lián)想主板")
                .screen("液晶屏幕").build() ;
        System.out.println(phone);

        // 傳統(tǒng)方法
        Phone1 phone1 = new Phone1("AMD的CPU", "三星顯示屏", "金士頓內(nèi)存", "華為主板") ;
        System.out.println(phone1);
    }

}

到了這里,關(guān)于24種設(shè)計(jì)模式之創(chuàng)建者模式-Java版的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 【設(shè)計(jì)模式】builder 創(chuàng)建者設(shè)計(jì)模式詳解(包含電商應(yīng)用場景及代碼示例)

    在常見的設(shè)計(jì)模式中,“Builder” 通常是指一種設(shè)計(jì)模式,而不是具體的類或方法。Builder 模式是一種創(chuàng)建型設(shè)計(jì)模式,其目的是通過提供一個(gè)獨(dú)立的構(gòu)建器類來構(gòu)建一個(gè)復(fù)雜對(duì)象。 建造者模式 (Builder Pattern) 是一種創(chuàng)建型設(shè)計(jì)模式,它的主要目標(biāo)是為了將一個(gè)復(fù)雜對(duì)象的構(gòu)

    2024年01月21日
    瀏覽(22)
  • 【創(chuàng)建者模式】工廠模式

    【創(chuàng)建者模式】工廠模式

    根據(jù)百科的定義,工廠模式是“工廠是用于創(chuàng)建其他對(duì)象的對(duì)象”。 以咖啡店為例,設(shè)計(jì)一個(gè)咖啡類Coffee,并定義其兩個(gè)子類(美式咖啡AmericanCoffee和拿鐵咖啡LatteCoffee);再設(shè)計(jì)一個(gè)咖啡店類CoffeeStore,咖啡店具有點(diǎn)咖啡的功能。 在上面的示例中,我們沒有使用任何模式并

    2023年04月11日
    瀏覽(23)
  • 【新手上路】如何在Web3時(shí)代成為XR創(chuàng)建者

    【新手上路】如何在Web3時(shí)代成為XR創(chuàng)建者

    目錄 0 XR在Web3里的作用 1 XR的概念、特征、技術(shù)、設(shè)備、平臺(tái)、應(yīng)用和工具 1.1 VR的概念、特征和技術(shù) 1.2 AR的概念、特征和技術(shù) 1.2 XR的設(shè)備、平臺(tái)、應(yīng)用和工具 2 選擇XR的方法 2.1 何時(shí)使用VR 2.2 何時(shí)使用AR 3 開發(fā)XR作品的4個(gè)步驟 4 成為XR構(gòu)建者的路徑 4.1 三種開發(fā)XR作品的方式

    2024年02月10日
    瀏覽(20)
  • 【Java 設(shè)計(jì)模式】創(chuàng)建型之單例模式

    【Java 設(shè)計(jì)模式】創(chuàng)建型之單例模式

    在軟件開發(fā)中,單例模式是一種常見的設(shè)計(jì)模式, 它確保一個(gè)類只有一個(gè)實(shí)例,并提供一個(gè)全局訪問點(diǎn) 。單例模式在需要控制某些資源,如數(shù)據(jù)庫連接池、線程池等共享資源的情況下非常有用。在本文中,我們將介紹 Java 設(shè)計(jì)模式中的單例模式,了解其實(shí)現(xiàn)方式、使用場景

    2024年01月18日
    瀏覽(26)
  • 【Java 設(shè)計(jì)模式】創(chuàng)建型之工廠方法模式

    【Java 設(shè)計(jì)模式】創(chuàng)建型之工廠方法模式

    在軟件開發(fā)中,工廠方法模式是一種常見的創(chuàng)建型設(shè)計(jì)模式, 它提供了一種將對(duì)象的實(shí)例化延遲到子類的方法 。工廠方法模式通過定義一個(gè)創(chuàng)建對(duì)象的接口,但是讓子類決定實(shí)例化哪個(gè)類。在本文中,我們將介紹 Java 設(shè)計(jì)模式中的工廠方法模式,了解其定義、使用場景以及

    2024年01月17日
    瀏覽(26)
  • 【Java 設(shè)計(jì)模式】創(chuàng)建型之抽象工廠模式

    【Java 設(shè)計(jì)模式】創(chuàng)建型之抽象工廠模式

    在軟件開發(fā)中,抽象工廠模式是一種常見的創(chuàng)建型設(shè)計(jì)模式, 它提供了一種創(chuàng)建一系列相關(guān)或相互依賴對(duì)象的接口,而無需指定它們具體的類 。抽象工廠模式的核心思想是將一組相關(guān)的產(chǎn)品組合成一個(gè)工廠,客戶端通過工廠接口創(chuàng)建一系列產(chǎn)品。在本文中,我們將介紹 Jav

    2024年01月17日
    瀏覽(28)
  • 【Java 設(shè)計(jì)模式】創(chuàng)建型之建造者模式

    【Java 設(shè)計(jì)模式】創(chuàng)建型之建造者模式

    在軟件開發(fā)中,建造者模式是一種創(chuàng)建型設(shè)計(jì)模式, 它將一個(gè)復(fù)雜對(duì)象的構(gòu)建與其表示分離,使得同樣的構(gòu)建過程可以創(chuàng)建不同的表示 。建造者模式通常包括一個(gè)指導(dǎo)者(Director)類和多個(gè)建造者(Builder)類,指導(dǎo)者負(fù)責(zé)組織建造者的構(gòu)建過程,而建造者負(fù)責(zé)具體的構(gòu)建步

    2024年01月21日
    瀏覽(20)
  • Java23種設(shè)計(jì)模式-創(chuàng)建型模式之單例模式

    單例模式 (Singleton Pattern):通過單例模式的方法創(chuàng)建的 類在當(dāng)前進(jìn)程中只有一個(gè)實(shí)例 (根據(jù)需要,也有可能一個(gè)線程中屬于單例,如:僅線程上下文內(nèi)使用同一個(gè)實(shí)例),該類負(fù)責(zé) 創(chuàng)建自己的對(duì)象 ,同時(shí) 確保只有單個(gè)對(duì)象 被創(chuàng)建。 注 : 1、單例類 只能 有 一個(gè)實(shí)例 。

    2024年04月26日
    瀏覽(27)
  • [設(shè)計(jì)模式Java實(shí)現(xiàn)附plantuml源碼~創(chuàng)建型] 產(chǎn)品族的創(chuàng)建——抽象工廠模式

    [設(shè)計(jì)模式Java實(shí)現(xiàn)附plantuml源碼~創(chuàng)建型] 產(chǎn)品族的創(chuàng)建——抽象工廠模式

    前言: 為什么之前寫過Golang 版的設(shè)計(jì)模式,還在重新寫 Java 版? 答:因?yàn)閷?duì)于我而言,當(dāng)然也希望對(duì)正在學(xué)習(xí)的大伙有幫助。Java作為一門純面向?qū)ο蟮恼Z言,更適合用于學(xué)習(xí)設(shè)計(jì)模式。 為什么類圖要附上uml 因?yàn)楹芏嗳藢W(xué)習(xí)有做筆記的習(xí)慣,如果單純的只是放一張圖片,那

    2024年01月22日
    瀏覽(23)
  • Java設(shè)計(jì)模式之創(chuàng)建型-原型模式(UML類圖+案例分析)

    Java設(shè)計(jì)模式之創(chuàng)建型-原型模式(UML類圖+案例分析)

    目錄 一、基礎(chǔ)概念 二、UML類圖 三、角色設(shè)計(jì) 四、案例分析? 4.1、通用實(shí)現(xiàn)(淺克?。?4.2、深克隆 五、總結(jié) 原型模式通過復(fù)制已有對(duì)象作為原型,通過復(fù)制該原型來返回一個(gè)新對(duì)象,而不是新建對(duì)象,說白了就是不斷復(fù)制相同的對(duì)象罷了。 角色 描述 抽象原型類 規(guī)定了具

    2024年02月15日
    瀏覽(45)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包