基本设计模式:单例模式和工厂模式代码实现
單例模式
????? 單例模式保證一個類僅有一個實例,并提供一個訪問它的全局訪問點。通常我們可以讓一個全局變量使得一個對象被訪問,但它不能阻止你實例化多個對象。一個最好的辦法是,讓類自身負責保存它的唯一實例。這個類可以保證沒有其他實例可以被創建,并且它可以提供一個訪問該實例的方法。
????? 也就是說,很多時候我們需要全局的對象,如一個工程中,數據庫訪問對象只有一個,這時,可以考慮使用單例模式。單例模式比全局對象好還包括:單例類可以繼承,如下例中的C++代碼。
???? 單例模式的關鍵點在于:構造函數私有,靜態的GetInstance。
???? 另外,在C++中必須注意內存的釋放。C++、Java、C#中還要注意多線程時的同步問題,另外在多線程可以以合適的方式保證共享變量僅初始化一次
?
以下列出懶漢式的單例模式
C++實現:
class Singleton { public: static Singleton * GetInstance() { if(NULL == m_pInstance) m_pInstance = new Singleton(); return m_pInstance; } static void Release() //必須,否則會導致內存泄露 { if(NULL != m_pInstance) { delete m_pInstance; m_pInstance = NULL; } } protected: Singleton() { cout<<"C++ Singleton"<<endl; }; static Singleton * m_pInstance; }; Singleton* Singleton::m_pInstance = NULL; class SingleDraw:public Singleton { public: static SingleDraw* GetInstance() { if(NULL == m_pInstance) m_pInstance = new SingleDraw(); return (SingleDraw*)m_pInstance; } protected: SingleDraw() { cout<<"C++ SingleDraw"<<endl; } }; int main() { SingleDraw* s1 = SingleDraw::GetInstance(); SingleDraw* s2 = SingleDraw::GetInstance(); s2->Release(); return 0; }?
Java實現(這里僅給出類實現部分):
public class Singleton{private static Singleton instance=NULL;private Singleton(){System.out.println("Java Singleton");}public static Singleton getInstance(){if(instance == NULL)instance = new Singleton();return instance;} }
還有另一種形式:?餓漢單例,也就是,類被加載的時候就已經創建好了單例,相比懶漢式只是加載new的地方發生了改變,這里代碼重略
?
餓漢式和懶漢式的比較:
1 餓漢式單例,由于類被加載的時候就將自己實例化,所以,從資源利用的角度來說,餓漢式單例比懶漢式單例效率更差
2 懶漢式單例在實例化的時候,必須處理好多個線程同時引用造成的訪問限制問題.也就是,很有可能有兩個線程同時去調用了這個獲取單例的方法,造成了單例被創建了多次,懶漢式單例模式線程安全問題:假如現在有兩個線程A和線程B,線程A執行到 this.singletonPattern = new SingletonPattern(),正在申請內存分配,可能需要0.001微秒,就在這0.001微秒之內,線程B執行到if(this.singletonPattern == null),你說這個時候這個判斷條件是true還是false?是true,那然后呢?線程B也往下走,于是乎就在內存中就有兩個SingletonPattern的實例了。所以,在編寫懶漢式單例模式時,應注意線程安全問題(由全局變量及靜態變量引起的),這里可以用互斥同步的方式去解決。(面試可考的地方)
3 餓漢式單例類可以在Java 語言內實現, 但不易在C++ 內實現,因為靜態初始化在C++ 里沒有固定的順序,因而靜態的m_instance 變量的初始化與類的加載順序沒有保證,可能會出問題。這就是為什么GoF 在提出單例類的概念時,舉的例子是懶漢式的。他們的書影響之大,以致Java 語言中單例類的例子也大多是懶漢式的
?
工廠模式
首先需要說一下工廠模式。工廠模式根據抽象程度的不同分為三種:簡單工廠模式(也叫靜態工廠模式)、這里所講述的工廠方法模式、以及抽象工廠模式。工廠模式是編程中經常用到的一種模式。它的主要優點有:
- 可以使代碼結構清晰,有效地封裝變化。在編程中,產品類的實例化有時候是比較復雜和多變的,通過工廠模式,將產品的實例化封裝起來,使得調用者根本無需關心產品的實例化過程,只需依賴工廠即可得到自己想要的產品。
- 對調用者屏蔽具體的產品類。如果使用工廠模式,調用者只關心產品的接口就可以了,至于具體的實現,調用者根本無需關心。即使變更了具體的實現,對調用者來說沒有任何影響。
- 降低耦合度。產品類的實例化通常來說是很復雜的,它需要依賴很多的類,而這些類對于調用者來說根本無需知道,如果使用了工廠方法,我們需要做的僅僅是實例化好產品類,然后交給調用者使用。對調用者來說,產品所依賴的類都是透明的。
C++實現:
#include <iostream>using namespace std;class IProduct { public:virtual void productMethod() = 0; };class Product:public IProduct { public:void productMethod() { cout<<"C++ productMethod call"<<endl; } };class IFactory { public:virtual IProduct* CreateProduct() = 0; };
class ConcreateFactory:public IFactory { public:IProduct* CreateProduct(){IProduct* p = new Product();return p;} };int main() {IFactory* pFactory = new ConcreateFactory();IProduct* p = pFactory->CreateProduct();p->productMethod();delete p;return 1; }
Java實現
class Product implements IProduct { public void productMethod() { System.out.println("Java productMethod call"); } }
interface IFactory { public IProduct createProduct(); }
class Factory implements IFactory { public IProduct createProduct() { return new Product(); } }
public class Client { public static void main(String[] args) { IFactory factory = new Factory(); IProduct prodect = factory.createProduct(); prodect.productMethod(); } }
?
?
?
轉載于:https://www.cnblogs.com/biyeymyhjob/archive/2012/07/19/2599136.html
總結
以上是生活随笔為你收集整理的基本设计模式:单例模式和工厂模式代码实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: lipo 制作通用版本 静态库
- 下一篇: Exchange server 2013