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

創(chuàng)建型模式 主要是用于產(chǎn)生類實(shí)例,也就是new 對(duì)象
共五種:工廠方法模式、抽象工廠模式、單例模式、建造者模式、原型模式。

一.單例模式

1.一句話描述

  • 確保一個(gè)類只會(huì)生成一個(gè)實(shí)例,并提供一個(gè)全局訪問點(diǎn)

2.實(shí)現(xiàn)方式

單例模式可以細(xì)分懶漢模式餓漢模式兩種模式:

(1).懶漢模式

public class Singleton{

    //使用volatile關(guān)鍵字防止重排序,因?yàn)?new 實(shí)例是一個(gè)非原子操作
    private volatile static Singleton singleton; 
    //私有構(gòu)造函數(shù)
    private Singleton(){}

    public static Singleton getSingleton(){
        if(singleton==null){
            //只對(duì)實(shí)例化代碼塊加鎖,提升性能
            synchronized (Singleton.class){   
                if (singleton == null) { //雙重檢查
                    singleton = new Singleton();
                }
            }
        }
        return singleton;
    }
}

在JDK1.4及更早版本的JAVA中,volatile關(guān)鍵字的實(shí)現(xiàn)會(huì)導(dǎo)致雙重檢查加鎖的失效

(2).餓漢模式

public class Singleton{
    private static Singleton singleton = new Singleton(); 
    //私有構(gòu)造函數(shù)
    private Singleton(){}

    public static Singleton getSingleton(){
        return singleton;
    }
}

利用JVM在加載完這個(gè)類時(shí),馬上實(shí)例化唯一的實(shí)例,保證線程安全

實(shí)戰(zhàn)場(chǎng)景:

  • Spring Bean 管理默認(rèn)就是一種單例模式

二、工廠模式

1.一句話描述

  • 定義一個(gè)創(chuàng)建對(duì)象的接口,由子類實(shí)例化具體對(duì)象,一個(gè)具體子類對(duì)應(yīng)一種產(chǎn)品類對(duì)象

2. 實(shí)現(xiàn)方式

(1) 簡(jiǎn)單工廠

class Juice{ }
class AppleJuice extends Juice{}
class PearJuice extends Juice{}

class JuiceStore{  
    public static Juice createJuice(String fruit) {  //簡(jiǎn)單工廠方法, 新增產(chǎn)品類,需要修改工廠方法,不符合開閉原則
        if ("apple".equals(fruit)) {
            return new AppleJuice();
        } else if ("pear".equals(fruit)) {
            return new PearJuice();
        } else {
            return null;
        }
    }
}

(2)工廠 方法

class Juice{ }   //抽象產(chǎn)品類
class AppleJuice extends Juice{} //具體產(chǎn)品類
class PearJuice extends Juice{}

abstract class JuiceStore{   //抽象工廠類
    public abstract Juice createJuice();
}

class AppleStore extends JuiceStore { //具體產(chǎn)品類

    @Override
    public Juice createJuice() {
        return new AppleJuice();
    }
}
class PearStore extends JuiceStore{//具體產(chǎn)品類

    @Override
    public Juice createJuice() {
        return new PearJuice();
    }
}

3. 類圖

image.png

4.總結(jié)

1.工廠模式相比簡(jiǎn)單工廠,加入了"開閉原則", 創(chuàng)建工廠和 產(chǎn)品實(shí)現(xiàn)解耦
2.每增加一個(gè)產(chǎn)品實(shí)現(xiàn)類,要增加一個(gè)工廠創(chuàng)建類
3.工廠模式 是抽象工廠的一個(gè)比較常見的情況

三、抽象工廠模式

1.一句話描述

  • 提供一個(gè)負(fù)責(zé)創(chuàng)建一組產(chǎn)品的接口,接口內(nèi)每個(gè)方法由子類負(fù)責(zé)創(chuàng)建一個(gè)具體產(chǎn)品

2.類圖/實(shí)例

class Juice{}
class AppleJuice extends Juice{}
class IceAppleJuice extends AppleJuice { }
class CommonAppleJuice extends AppleJuice{}

class PearJuice extends Juice{}

class IcePearJuice extends PearJuice { }
class CommonPearJuice extends PearJuice{}
//超級(jí)工廠,包含兩個(gè)工廠方法
abstract class Store{
    public abstract Juice createAppleJuice();
    public abstract Juice createPearJuice();
}

class OneStore extends Store {
    @Override
    public Juice createAppleJuice() {
        return new IceAppleJuice();
    }
    @Override
    public Juice createPearJuice() {
        return new IcePearJuice();
    }
}
class TwoStore extends Store{

    @Override
    public Juice createAppleJuice() {
        return new CommonAppleJuice();
    }
    @Override
    public Juice createPearJuice() {
        return new CommonPearJuice();
    }
}

3.實(shí)戰(zhàn)案例

4.總結(jié)

1.在一個(gè)工廠里聚合多個(gè)同類產(chǎn)品(同類產(chǎn)品的不同系列)
2.簡(jiǎn)化產(chǎn)品族的交換
3.產(chǎn)品族要擴(kuò)展,需要修改所有工廠類,不易擴(kuò)展產(chǎn)品族

四、原型模式

1. 一句話描述

  • 利用原對(duì)象快速?gòu)?fù)制一個(gè)對(duì)象

2.實(shí)戰(zhàn)案例

  • Object 對(duì)象clone方法,本地方法默認(rèn)實(shí)現(xiàn)淺克隆
  • Spring中原型bean的創(chuàng)建,就是原型模式的應(yīng)用

3.實(shí)現(xiàn)方式

分為淺克隆深克隆

  • 淺克?。簞?chuàng)建一個(gè)新對(duì)象,新對(duì)象的屬性和原來對(duì)象完全相同,對(duì)于非基本類型屬性,仍指向原
    有屬性所指向的對(duì)象的內(nèi)存地址, 也就是引用類型指向的是同一個(gè)
// 實(shí)現(xiàn)Cloneable接口
public class InstanceClone implements Cloneable{
    // ...省略
    @Override
    protected Object clone() {
        Object clone = null;
        try {
            clone = super.clone();
        } catch (CloneNotSupportedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        // TODO Auto-generated method stub
        return clone;
    }
}

  • 深克隆:創(chuàng)建一個(gè)新對(duì)象,屬性中引用的其他對(duì)象也會(huì)被克隆,不再指向原有對(duì)象地址。
//通過對(duì)象的序列化實(shí)現(xiàn)
    public Object deepClone() {
        //創(chuàng)建流
        ByteArrayOutputStream bos = null;
        ObjectOutputStream oos = null;
        ByteArrayInputStream bis =null;
        ObjectInputStream ois = null;
        
        try {
            //序列化
            bos = new ByteArrayOutputStream();
            oos = new ObjectOutputStream(bos);
            oos.writeObject(this);//當(dāng)前的對(duì)象以流的方式輸出
            
            //反序列化
            bis = new ByteArrayInputStream(bos.toByteArray());
            ois = new ObjectInputStream(bis);
            InstanceClone deepClone = (InstanceClone )ois.readObject();
            
            return deepClone ;
            
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
            return null;
        }finally {
            try {
                bos.close();
                oos.close();
                bis.close();
                ois.close();
            } catch (Exception e2) {
                // TODO: handle exception
            }
        }
        
    }

也可以通過重寫clone方法來實(shí)現(xiàn)深拷貝,但不推薦

4.總結(jié)

1.原型模式可以快速創(chuàng)建復(fù)雜對(duì)象,同時(shí)提高效率
2.需要在類中實(shí)現(xiàn)克隆方法, 違背了OCP開閉原則

五、建造者模式

1. 一句話描述

  • 對(duì)復(fù)雜對(duì)象的組件創(chuàng)建以及組合進(jìn)行了抽取和拆分

2.類圖

image.png

3. 實(shí)戰(zhàn)場(chǎng)景

  • JDK中 StringBuilder
  • MybatisPlus中的QueryWrapper對(duì)象的構(gòu)建
  • Mybatis中用到的建造者模式:SqlSessionFactoryBuilder、XMLConfigBuilder、XMLMapperBuilder、XMLStatementBuilder、CacheBuilder等

4.總結(jié)

1.將復(fù)雜對(duì)象的創(chuàng)建步驟分解在不同的方法中,使得創(chuàng)建過程更加清晰,對(duì)象創(chuàng)建更加靈活
2.使用方不必知道對(duì)象內(nèi)部組成細(xì)節(jié),對(duì)象本身和對(duì)象創(chuàng)建過程解耦
3.如果對(duì)象內(nèi)部發(fā)生變化, 建造者都要修改,成本較大,適用于對(duì)象組成部分基本相同

最后編輯于
?著作權(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)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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