1. 程式人生 > >設計模式(單例、代理、工廠)

設計模式(單例、代理、工廠)

一、單例模式

<span style="font-family:Microsoft YaHei;font-size:12px;">主要包括懶漢式,餓漢式,登記式,以及懶漢式的改進型,還有一個關於讀取propertoes配置檔案的例項。</span>
<span style="font-family:Microsoft YaHei;font-size:12px;">單例模式是設計模式中比較簡單的一種。適合於一個類只有一個例項的情況,比如視窗管理器,列印緩衝池和檔案系統,
它們都是原型的例子。典型的情況是,那些物件的型別被遍及一個軟體系統的不同物件訪問,因此需要一個全域性的訪問
指標,這便是眾所周知的單例模式的應用。當然這隻有在你確信你不再需要任何多於一個的例項的情況下。 
單例模式的用意在於前一段中所關心的。通過單例模式你可以: 
一、確保一個類只有一個例項被建立 
二、提供了一個對物件的全域性訪問指標 
三、在不影響單例類的客戶端的情況下允許將來有多個例項
經典的單例模式有三種,懶漢式、餓漢式和 登記式。
懶漢式的特點是延遲載入,比如配置檔案,採用懶漢式的方法,顧名思義,懶漢麼,很懶的,配置檔案的例項直到用到的時候才會載入。</span></span>

餓漢式的特點是一開始就載入了,如果說懶漢式是“時間換空間”,那麼餓漢式就是“空間換時間”,因為一開始就建立了例項,所以每次用到的之後直接返回就好了。

讓我們先看下程式碼:

懶漢式:

[java] view plaincopyprint?
  1. //懶漢式單例模式
  2. publicclass MySingleton {  
  3.     //設立靜態變數
  4.     privatestatic MySingleton mySingleton = null;  
  5.     private MySingleton(){  
  6.         //私有化建構函式
  7.         System.out.println("-->懶漢式單例模式開始呼叫建構函式"
    );  
  8.     }  
  9.     //開放一個公有方法,判斷是否已經存在例項,有返回,沒有新建一個在返回
  10.     publicstatic MySingleton getInstance(){  
  11.         System.out.println("-->懶漢式單例模式開始呼叫公有方法返回例項");  
  12.         if(mySingleton == null){  
  13.             System.out.println("-->懶漢式建構函式的例項當前並沒有被建立");  
  14.             mySingleton = new MySingleton();  
  15.         }else
    {  
  16.             System.out.println("-->懶漢式建構函式的例項已經被建立");  
  17.         }  
  18.         System.out.println("-->方法呼叫結束,返回單例");  
  19.         return mySingleton;  
  20.     }  
  21. }  
看下客戶端的測試程式碼: [java] view plaincopyprint?
  1. publicclass Client {  
  2.     /** 
  3.      * 懶漢式單例模式 
  4.      * MySingleton 
  5.      */
  6.     publicstaticvoid myprint(){  
  7.         System.out.println("-----------------懶漢式單例模式----------------");  
  8.         System.out.println("第一次取得例項(懶漢式)");  
  9.         MySingleton s1 = MySingleton.getInstance();  
  10.         System.out.println("第二次取得例項(懶漢式)");  
  11.         MySingleton s2 = MySingleton.getInstance();  
  12.         if(s1==s2){  
  13.             System.out.println(">>>>>s1,s2為同一例項(懶漢式)<<<<<");  
  14.         }  
  15.         System.out.println();  
  16.     }  
  17.         /** 
  18.      * @param args 
  19.      */
  20.     publicstaticvoid main(String[] args) {  
  21.         // TODO Auto-generated method stub
  22.         //懶漢式
  23.         myprint();  
  24.         //餓漢式
  25.         //myprint2();
  26.         //懶漢式改進
  27.         //myprint2a();
  28.         //登記式
  29.         //myprint3();
  30.     }  
  31. }  

輸出結果為:

-----------------懶漢式單例模式----------------
第一次取得例項(懶漢式)
-->懶漢式單例模式開始呼叫公有方法返回例項
-->懶漢式建構函式的例項當前並沒有被建立
-->懶漢式單例模式開始呼叫建構函式
-->方法呼叫結束,返回單例
第二次取得例項(懶漢式)
-->懶漢式單例模式開始呼叫公有方法返回例項
-->懶漢式建構函式的例項已經被建立
-->方法呼叫結束,返回單例
>>>>>s1,s2為同一例項(懶漢式)<<<<<

可以看出,在第一次呼叫公有方法的時候,並沒有例項,所以我們建立了一個例項,之後再訪問的時候,因為已經有一個已經建立好的例項,所以直接返回了。

餓漢式

[java] view plaincopyprint?
  1. //餓漢式單例模式
  2. publicclass MySingleton2 {  
  3.     //設立靜態變數,直接建立例項
  4.     privatestatic MySingleton2 mySingleton = new MySingleton2();  
  5.     private MySingleton2(){  
  6.         //私有化建構函式
  7.         System.out.println("-->餓漢式單例模式開始呼叫建構函式");  
  8.     }  
  9.     //開放一個公有方法,判斷是否已經存在例項,有返回,沒有新建一個在返回
  10.     publicstatic MySingleton2 getInstance(){  
  11.         System.out.println("-->餓漢式單例模式開始呼叫公有方法返回例項");  
  12.         return mySingleton;  
  13.     }  
  14. }  

看下客戶端的測試程式碼: [java] view plaincopyprint?
  1. /** 
  2.  * 餓漢式單例模式 
  3.  * MySingleton2 
  4.  */
  5. publicstaticvoid myprint2(){  
  6.     System.out.println("-----------------餓漢式單例模式----------------");  
  7.     System.out.println("第一次取得例項(餓漢式)");  
  8.     MySingleton2 s1 = MySingleton2.getInstance();  
  9.     System.out.println("第二次取得例項(餓漢式)");  
  10.     MySingleton2 s2 = MySingleton2.getInstance();  
  11.     if(s1==s2){  
  12.         System.out.println(">>>>>s1,s2為同一例項(餓漢式)<<<<<");  
  13.     }  
  14.     System.out.println();  
  15. }  
[java] view plaincopyprint?
  1. /** 
  2.  * @param args 
  3.  */
  4. publicstaticvoid main(String[] args) {  
  5.     // TODO Auto-generated method stub
  6.     //懶漢式
  7.     //myprint();
  8.     //餓漢式
  9.     myprint2();  
  10.     //懶漢式改進
  11.     //myprint2a();
  12.     //登記式
  13.     //myprint3();
  14. }  

輸出結果為:

-----------------餓漢式單例模式----------------
第一次取得例項(餓漢式)
-->餓漢式單例模式開始呼叫建構函式
-->餓漢式單例模式開始呼叫公有方法返回例項
第二次取得例項(餓漢式)
-->餓漢式單例模式開始呼叫公有方法返回例項
>>>>>s1,s2為同一例項(餓漢式)<<<<<

總結一下,兩種方案的建構函式和公用方法都是靜態的(static),例項和公用方法又都是私有的(private)。但是餓漢式每次呼叫的時候不用做建立,直接返回已經建立好的例項。這樣雖然節省了時間,但是卻佔用了空間,例項本身為static的,會一直在記憶體中帶著。懶漢式則是判斷,在用的時候才載入,會影響程式的速度。最關鍵的是,在併發的情況下,懶漢式是不安全的。如果兩個執行緒,我們稱它們為執行緒1和執行緒2,在同一時間呼叫getInstance()方法,如果執行緒1先進入if塊,然後執行緒2進行控制,那麼就會有兩個例項被建立。

二、代理模式

PROXY—跟MM在網上聊天,一開頭總是“hi,你好”,“你從哪兒來呀?”“你多大了?”“身高多少呀?”這些話,真煩人,寫個程式做為我的Proxy吧,凡是接收到這些話都設定好了自動的回答,接收到其他的話時再通知我回答,怎麼樣,酷吧。 

  代理模式:代理模式給某一個物件提供一個代理物件,並由代理物件控制對源物件的引用。代理就是一個人或一個機構代表另一個人或者一個機構採取行動。某些情況下,客戶不想或者不能夠直接引用一個物件,代理物件可以在客戶和目標物件直接起到中介的作用。客戶端分辨不出代理主題物件與真實主題物件。代理模式可以並不知道真正的被代理物件,而僅僅持有一個被代理物件的介面,這時候代理物件不能夠建立被代理物件,被代理物件必須有系統的其他角色代為建立並傳入。  

/**
 * @author Rollen-Holt 設計模式之 代理模式
 */
interface NetWork{
    public abstract void browser();
}
/**
 * Real 類代表使用者上網的實際動作,比如檢視網頁
 * */
class Real implements NetWork{
    public void browser(){
        System.out.println("上網瀏覽資訊");
    }
}
/**
 * 此處使用代理類來完成中間代理的工作,遮蔽實現代理的細節
 * */
class proxy implements NetWork{
    private NetWork netWork;

    proxy(NetWork netWork){
        this.netWork = netWork;
    }

    public void browser(){
        checkName();
        this.netWork.browser();
    }

    private void checkName(){
        // Other codes
    }
}
class hello{
    public static void main(String[] a){
        new proxy(new Real()).browser();
    }
}

三、工廠模式

一、工廠模式主要是為建立物件提供過渡介面,以便將建立物件的具體過程遮蔽隔離起來,達到提高靈活性的目的。



工廠模式在《Java與模式》中分為三類:
1)簡單工廠模式(Simple Factory):不利於產生系列產品;

2)工廠方法模式(Factory Method):又稱為多形性工廠;

3)抽象工廠模式(Abstract Factory):又稱為工具箱,產生產品族,但不利於產生新的產品;
             這三種模式從上到下逐步抽象,並且更具一般性。
             GOF在《設計模式》一書中將工廠模式分為兩類:工廠方法模式(Factory Method)與抽象工廠模式(Abstract Factory)。將簡單工廠模式(Simple Factory)看為工廠方法模式的一種特例,兩者歸為一類。


相關推薦

關於設計模式模式工廠模式代理模式介面卡模式觀察者設計模式的理解

1):單例模式 package designMode.singleton; /** * 單例模式形成的原因: * * 構造器私有---> 外界無法例項化,就在類內部建立一個例項物件,用static修飾,可以用類名直接呼叫---> 但是,類的一般用法都講究

設計模式代理工廠

一、單例模式 <span style="font-family:Microsoft YaHei;font-size:12px;">主要包括懶漢式,餓漢式,登記式,以及懶漢式的改進型,還有一個關於讀取propertoes配置檔案的例項。</span&g

javaSE (三十八設計模式 設計模式餓漢式/懶漢式簡單工廠模式工廠模式介面卡模式模板方法設計模式

1、單例設計模式(餓漢式/懶漢式): 概念:保證類在記憶體中只有一個物件 思路: 私有構造方法,其他類不能再訪問該構造方法了 建立本類物件(就在本類裡建立),將物件的應用作為成員變數,並私有靜態化(在這裡又分為餓漢式和懶漢式,餓漢式直接引用連線物件,而懶漢式在第二步先建

ThinkPHP筆記5——PHP常用設計模式工廠註冊樹

<?php //單例模式 class Site{ //屬性 public $siteName; //本類的靜態例項 private static $instance = null; //禁用構造方法 private function __construct($siteN

創建型設計模式模式

創建型設計模式 true 自己 singleton span 創建 final 調用 ati 單例模式有以下特點:  1、單例類只能有一個實例。  2、單例類必須自己創建自己的唯一實例。  3、單例類必須給所有其他對象提供這一實例。 一、懶漢式單例 //懶漢式單例類.在第

添磚加瓦:設計模式模式

argv pri 方法 職責 ger 資源管理 存在 優缺點 names   1、單例定義及要素   定義:   保證一個類只有一個實例存在,同時提供能對該實例加以訪問的全局訪問方法(GoF中單例模式的定義)。   要素:   (1)某個類只能有一個實例   (2)必須自行

設計模式——模式

單例模式簡介: 單例模式(Singleton Pattern)是 Java 中最簡單的設計模式之一。這種型別的設計模式屬於建立型模式,它提供了一種建立物件的最佳方式。 這種模式涉及到一個單一的類,該類負責建立自己的物件,同時確保只有單個物件被建立。這個類提供了一種訪問其唯一的物件的

java 設計模式,享元,策略

讀書不覺已春深,一寸光陰一寸金。 java的設計模式大體上分為三大類: 建立型模式(5種):工廠方法模式,抽象工廠模式,單例模式,建造者模式,原型模式。 結構型模式(7種):介面卡模式,裝飾器模式,代理模式,外觀模式,橋接模式,組合模式,享元模式。

Python設計模式模式筆記

版本:Python3.6.1# coding = utf - 8 """ time:2018年4月3日 10:15:02 function:設計模式---單例模式 """ """ 單例模式: 保證物件的唯一性 思路: 在建立物件時,只分配一個記憶體

【JAVA】基礎:設計模式設計模式工廠設計模式

設計模式:解決某一類問題最行之有效的方法。 java中有23種設計模式。 建立型模式(5種):工廠方法模式,抽象工廠模式,單例模式,建造者模式,原型模式。 結構型模式(7種):介面卡模式,裝飾器模式,代理模式,外觀模式,橋接模式,組合模式,享元模式。 行為型模式(11種):策略模式、模板方法

設計模式模式工廠模式,介面卡模式

1:設計模式是什麼? 前人總結的一些經驗和思想,給我們提供了從抽象到具體的方法 總共有23種 分類: 建立型模式: 建立物件。(其實建立物件比較耗記憶體的動作) 結構型模式: 物件的組成。 行為模式: 物件能夠做什

java中幾種設計模式模式,介面卡模式,簡單工廠模式

1、單例模式:也分餓漢式單例模式(建立物件)與懶漢式單例模式(未建立物件)程式碼實現:餓漢式單例模式:懶漢式單例模式:2、介面卡模式:介面:實現介面的類:實現介面某個方法的類:3、簡單工廠模式:介面:類1:類2:工廠類:測試類:

Java---設計模式變形

★ 快取在單例中的使用(“單例+快取”技術) 快取在程式設計中使用很頻繁,有著非常重要的作用,它能夠幫助程式實現以空間換取時間,通常被設計成整個應用程式所共享的一個空間,現要求實現一個用快取存放單例物

原始碼學習之設計模式模式

眾所周知,單例模式分為餓漢式和懶漢式,昨天在看了《spring5核心原理與30個類手寫實戰》之後才知道餓漢式有很多種寫法,分別適用於不同場景,避免反射,執行緒不安全問題。下面就各種場景、採用的方式及其優缺點介紹。 餓漢式 (絕對的執行緒安全) 程式碼示例 1.第一種寫法 ( 定義即初始化) public cl

c++設計模式模式餓漢,懶漢,執行緒安全

單例模式:單例模式,是一種常用的軟體設計模式。在它的核心結構中只包含一個被稱為單例的特殊類。通過單例模式可以保證系統中,應用該模式的類一個類只有一個例項。即一個類只有一個物件例項。如何保證一個類只有一個例項並且這個例項易於被訪問呢?定義一個全域性變數可以確保物件隨時都可以被訪

java設計模式模式列舉靜態內部類

1、靜態內部類 public class InnerClassSingleton implements Serializable

設計模式模式介紹及8種寫法餓漢式懶漢式Double-Check靜態內部類列舉

# 一、餓漢式(靜態常量) 這種餓漢式的單例模式構造的步驟如下: 1. 構造器私有化;(防止用new來得到物件例項) 2. 類的內部建立物件;(因為1,所以2) 3. 向外暴露一個靜態的公共方法;(getInstance) 示例: ```java class Singleton{ //

設計模式模式【內附物件例項化幾種方式實現執行緒安全幾種方式】

繼續來複習常用的設計模式-單例模式,順便回憶一下執行緒安全的幾種實現方式。 一、什麼是單例模式 單例模式,簡單常用的一種設計模式,也很好的體現了程式碼控制物件在記憶體數量的一種方式,主要分2種實現方式: ①餓漢式,執行緒安全 ②懶漢式,執行緒不安全(新增鎖機制,可以實現執行緒安全)

java中的設計模式模式工廠模式

Java中的設計模式            轉載地址:https://www.toutiao.com/i6573486403282272775/ 為什麼要學習設計模式 1)設計模式都是一些相對優秀的解決方案,很多問題都是典型的

19設計模式模式-懶漢式

/** * 懶漢式-單例模式 * 多執行緒模式慎用,單例模式會失效,為解決這一問題,可以在靜態方法上加“synchronized”表明鎖住該類本身,同一時間點只有一個執行緒可以訪問該方法 * 該方法雖然可以解決單例失效的問題,但卻非常的消耗資源 */ public c