設(shè)計(jì)模式之禪——設(shè)計(jì)模式(一)

單例模式

summary
1、只有一個(gè)實(shí)例
2、整個(gè)系統(tǒng)共用這個(gè)實(shí)例

餓漢模式

public class Singleton{
private static final Singleton singleton =new Singleton();
//限制產(chǎn)生多個(gè)對(duì)象
private Singleton(){
}
//獲得實(shí)例的方法
public static Singleton getInstance(){
return singleton;
}
//類中的其他方法,盡量 static
public static void doSomething(){
}
}

懶漢模式
用的時(shí)候,創(chuàng)建實(shí)例。高并發(fā)的時(shí)候,需要在方法前添加synchronize;

public class Singleton{
private static final Singleton singleton =null;
//限制產(chǎn)生多個(gè)對(duì)象
private Singleton(){
}
//獲得實(shí)例的方法
public static Singleton getInstance(){
if(singleton==null){
singleton =new Singleton();
}
return singleton;
}
//類中的其他方法,盡量 static
public static void doSomething(){
}
}

優(yōu)點(diǎn)

1、唯一實(shí)例,避免多次創(chuàng)建,減小內(nèi)存使用。
2、全局共享唯一資源,調(diào)度,管理方便。
3、加鎖后,防止資源文件的同時(shí)讀寫。

缺點(diǎn)

1、擴(kuò)展困難,需要擴(kuò)展么??
2、違背單一職責(zé)原則,單例的實(shí)例一般是一個(gè)混合型的靜態(tài)類。
3、“單例模式對(duì)測(cè)試是不利的。在并行開發(fā)環(huán)境中,如果單例模式?jīng)]有完成,是不能進(jìn)行測(cè)試的,沒有接口也不能使用mock的方式虛擬一個(gè)對(duì)象。”

摘錄來自: 秦小波. “設(shè)計(jì)模式之禪(第2版)”。

擴(kuò)展:多例模式

利用一個(gè)list進(jìn)行實(shí)例管理,考慮到同步問題,可以采用vector;

public class Singleton{
private static int maxNumber =2;
private static List<Singleton> singletonList =new ArrayList<>();
private static final Singleton singleton =null;

static{
  for(int i =0;i<maxNumber;i++){
  singletonList.add(new Singleton() );
  }
}


//限制產(chǎn)生多個(gè)對(duì)象
private Singleton(){
}
//獲得實(shí)例的方法
public static Singleton getInstance(){
Random random = new Random();
return singletonList.get(random.nextInt(maxNumber));
}
//類中的其他方法,盡量 static
public static void doSomething(){
}
}

2.工廠方法模式

  • 定義一個(gè)用于創(chuàng)建對(duì)象的接口,具體實(shí)現(xiàn)類由他的子類決定。工廠方法使一個(gè)類的實(shí)例化延遲到其子類。

優(yōu)點(diǎn)

  • 良好的封裝性,代碼結(jié)構(gòu)清晰。
  • 擴(kuò)展性非常優(yōu)秀,適配新情況,原來的工廠類基本不用修改。
  • 屏蔽產(chǎn)品類。實(shí)例是在工廠類中實(shí)現(xiàn)的,由工廠類負(fù)責(zé)。
  • 工廠模式是典型的解耦合框架。


    image.png

擴(kuò)展

2.1簡(jiǎn)單工程模式(靜態(tài)工廠模式)
  • 去掉工廠模式里的抽象類,將方法改成靜態(tài)方法。調(diào)用的話變得簡(jiǎn)單方便。
  • 缺點(diǎn)擴(kuò)展比較困難??,不符合開閉原則??
2.2多個(gè)工程模式
  • 由原來一個(gè)工廠變成多個(gè)工廠,同時(shí),每個(gè)工廠實(shí)現(xiàn)的方法可以進(jìn)行具體化。
  • 當(dāng)工廠種類比較多的時(shí)候,代碼比較龐大。
2.3工廠模式實(shí)現(xiàn)單例式(針對(duì)惡漢模式)
  • 不通過正常手段實(shí)現(xiàn)實(shí)例,通過添加一個(gè)static代碼塊。并采用反射的方法來創(chuàng)建實(shí)例。(跟工廠有毛線關(guān)系??)
//靜態(tài)代碼塊
 private static Singleton singleton;
 
static{
try{
Class cl =Class.forName(Singleton.class.getName());
//獲得無參構(gòu)造
Constructor constructor  =cl.getDeclaredConstructor();
//設(shè)置無參構(gòu)造是可以訪問的
constructor.setAccessible(true);
//產(chǎn)生一個(gè)實(shí)例對(duì)象
singleton =(Singleton)constructor.newInstance();
}catch(Exception e){
}
}
2.4延遲加載工廠類
  • 簡(jiǎn)單來說,就是創(chuàng)建好實(shí)例后,不馬上釋放掉。而是保存在內(nèi)存之中,留做以后使用。
  • 單多個(gè)對(duì)象需要采用單例模式是,可以把創(chuàng)建一個(gè)工程,用一個(gè)map容器去保存它們。

3.抽象工廠模式

  • 定義:為創(chuàng)建一組相關(guān)或相互依賴的對(duì)象提供的一個(gè)接口,而且無需指定他們的具體類
  • 個(gè)人理解:需要生產(chǎn)出來的東西具有屬性交叉的特性。即A、B產(chǎn)品具有相同的共性,也有不同的特性。為了實(shí)現(xiàn)生產(chǎn),根據(jù)其特性實(shí)現(xiàn)工程,然后創(chuàng)建出具有共性又有特性的產(chǎn)品。


    image.png

    image.png
  • 優(yōu)點(diǎn):封裝性、產(chǎn)品族內(nèi)的約束為非公開狀態(tài)。
  • 缺點(diǎn):擴(kuò)展困難。
  • 場(chǎng)景:當(dāng)一個(gè)對(duì)象族都有相同約束時(shí)候,可以采用這種模式。例如同一個(gè)產(chǎn)品,想要運(yùn)行在ios,和android。那么他就需要有兩個(gè)開發(fā)團(tuán)隊(duì)(工廠)去創(chuàng)建該項(xiàng)目。
  • 代碼地址:
工廠模式和抽象工廠模式的區(qū)別
  • 工廠模式:一個(gè)抽象的產(chǎn)品,通過工廠創(chuàng)建出不同的具體產(chǎn)品。并且,產(chǎn)品的創(chuàng)建過程是在工廠之中的。
  • 抽象工程模式:跟該模式有個(gè)相關(guān)的概念是產(chǎn)品族,抽象模式中有多個(gè)產(chǎn)品族工廠,每個(gè)產(chǎn)品族工廠生產(chǎn)出來的產(chǎn)品跟其他產(chǎn)品族具有相同的產(chǎn)品特性,也有自身產(chǎn)品族的特性。因此,抽象工廠模式添加產(chǎn)品族簡(jiǎn)單,但是增加產(chǎn)品結(jié)構(gòu)缺很蛋疼。因?yàn)樾枰獙?duì)之前的每個(gè)產(chǎn)品族重新修改,連同產(chǎn)品類的結(jié)構(gòu)也要發(fā)生改變。
  • 產(chǎn)品族和產(chǎn)品等級(jí)結(jié)構(gòu):
    假設(shè)羅技公司有低中高三種工廠,他們同時(shí)都生產(chǎn)鼠標(biāo)、鍵盤、攝像頭。
    那么這時(shí)候低級(jí)工廠、中級(jí)工廠等就分別是產(chǎn)品族鼠標(biāo)、鍵盤、攝像頭就分別是產(chǎn)品等級(jí)結(jié)構(gòu)
    ——引自知乎

4.模板方法模式

定義:定義一個(gè)操作中的算法框架,將一些步驟(特性)延遲到子類中。使得子類可以不改變一個(gè)算法的結(jié)構(gòu)即可重定義該算法的某些特定步驟。

自我理解:之前在寫女媧造人的例子中,也用到了模板模式。首先,共性的東西(由抽象類實(shí)現(xiàn))例如人都可以說話、吃飯、走路。特性(由具體類實(shí)現(xiàn))人分男女,這個(gè)東西需要具體到最終的實(shí)現(xiàn)類中實(shí)現(xiàn)。

注意: 為防止惡意的操作,一般模板方法都加上final,不允許復(fù)寫

優(yōu)點(diǎn):封裝不變部分,擴(kuò)展可變部分;提取公共部分代碼,便于維護(hù);行為由父類控制,子類實(shí)現(xiàn);
缺點(diǎn): 子類執(zhí)行結(jié)果影響父類的結(jié)果。

  • 類圖


    image.png

5.建造者模式

  • 將一個(gè)復(fù)雜對(duì)象的構(gòu)建與它的表示分離,使得同樣的構(gòu)建過程可以創(chuàng)建不同的表示。
  • 自我理解(書中的描述跟我的理解有出入),構(gòu)造者模式的特色是能夠讓調(diào)用者根據(jù)自身情況進(jìn)行建造。采用建造模式,還可以讓建造者一目了然的了解的建造的元素結(jié)構(gòu)。


    image.png

代碼地址:https://github.com/cyp206/DesignModeLearning/

最后編輯于
?著作權(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)容