《設計模式整理》

目錄

    • 常見設計模式
    • 如何保證單例模式只有一個實例
    • 單例模式中的懶漢與餓漢模式
    • OOP設計模式的五項原則
    • 單例模式中的懶漢加載,如果并發訪問該怎么做

常見設計模式

單例模式
單例模式主要解決了一個全局使用的類頻繁的創建和銷毀的問題。
單例模式下確保某一個類只有一個實例,并且自行實例化并向整個系統提供這個實例。
單例模式有三要素:
1、某個類只能有一個實例
2、它必須自行創建這個實例
3、它必須自行向整個系統提供這個實例
優點:
1、內存里只有一個實例,減少了內存的開銷,尤其是頻繁的創建和銷毀實例
2、避免了對資源的多重占用。
缺點:
沒有接口,不能繼承,與單一職責原則沖突,一個類應該只關心內部邏輯,而不關心外面怎么來實例化它。
使用場景:
1、要求生產唯一序列號
2、創建一個對象消耗的資源過多,如I/O與數據庫的鏈接等。

工廠模式
主要解決接口選擇的問題。該模式下定義一個創建對象的接口,讓子類自己決定實例化哪一個工廠類,
也就是讓創建過程延遲到子類進行。
工廠模式的優點:
解耦,代碼復用,更改功能容易。

觀察者模式
定義對象間的一種一對多的依賴關系,當一個對象的狀態發生改變時,讓所有依賴于它的對象都得到通知并且自動更新。
觀察者模式中分為觀察者和被觀察者,當被觀察者發生裝填改變時,觀察者會受到通知。
主要是為了解決對象狀態改變給其他對象通知的問題,實現:類似于觀察者在被觀察者那邊注冊了一個回調函數。

裝飾器模式
對于已經存在的某些類進行裝飾,以此來擴展一些功能,從而動態的為一個對象增加新的功能。
裝飾器模式是一種用于代替繼承的技術,無需通過繼承增加子類就能擴展對象的新功能。
優點:裝飾類和被裝飾類可以獨立發展,不會相互耦合,裝飾模式是繼承的一個替代模式,裝飾模式可以動態擴展一個實現類的功能。
缺點:多層裝飾比較復雜
使用場景:1、擴展一個類的功能 2、動態增加功能、動態撤銷功能。

如何保證單例模式只有一個實例

1、將該類的構造方法定義為私有方法,這樣其他處的代碼無法通過調用構造函數來實例化該類的對象,只有通過類提供的靜態方法來得到該類的唯一實例。
2、在該類內部提供一個靜態方法,當調用這個方法時,如果類持有的引用不為空,就返回這個引用。如果類的引用為空,就創建這個類的實例。
C++的實現有兩種,一種通過局部靜態變量,利用其只初始化一次的特點,返回對象。另外一種,則是定義全局的指針,getInstance判斷該指針是否為空,為空時才實例化對象。

單例模式中的懶漢與餓漢模式

懶漢模式:在類加載的時候不被初始化。
像一個懶漢一樣,需要用到創建實例了的程序再去創建實例,不需要創建實例程序就不去創建實例,這是一個時間換空間的做法,同時體現了懶漢本性。

實現方法:定義一個單例類,使用類的私有靜態指針變量指向類的唯一實例,并用一個公有的靜態方法獲取該實例。

#include <iostream>
#include <stdlib.h>
using namespace std;class singleton  //實現單例模式的類
{
private:singleton() //私有的構造函數,這樣就不能再其他地方創建該實例{}static singleton* instance;  //定義一個唯一指向實例的指針,并且是私有的static int b; 
public:static singleton* GetInstance()  //定義一個公有函數,可以獲取這個唯一實例{if (instance == NULL)  //判斷是不是第一次使用instance = new singleton;return instance;}static void show(){cout << b << endl;}
};
int singleton::b = 10; //靜態成員變量在類外進行初始化,它是整個類的一部分并不屬于某個對象
singleton* singleton::instance = NULL;
int main()
{singleton* a1 = singleton::GetInstance();cout << a1 << endl;a1->show();singleton* a2 = singleton::GetInstance();cout << a2 << endl;a2->show();system("pause");return 0;
}

實例的兩個對象的地址都是一樣的
懶漢模式的singleton類有以下特點:

1、 他有一個指向唯一實例的靜態指針,并且是私有的
2、它有一個公有的函數,可以獲取這個唯一的實例,并且在需要的時候創建該實例
3、它的構造函數是私有的,這樣就不能從別處創建該類的實例

但是這存在一個缺點,也就是說它在單線程下是正確的,但是在多線程情況下,如果兩個線程同時首次調用GetInstance()方法,那么就會同時監測到instance為NULL,則兩個線程會同時構造一個實例給instance,這樣就會發生錯誤。
餓漢模式
單例類定義的時候就進行實例化
在餓漢模式中,實例對象儲存在全局數據區,所以要用static來修飾,所以對于餓漢模式來說,是線程安全的,因為在線程創建之前實例就已經創建好了。

#include <iostream>
#include <stdlib.h>
using namespace std;class singleton
{
private:static singleton* instance; //這是我們的單例對象,它是一個類對象的指針singleton(){cout << "創建一個單例對象" << endl;}~singleton(){cout << "析構掉一個單例對象" << endl;}
public:static singleton* getinstance();static void deleteInstance();   //用來銷毀實例
};
//下面這個靜態成員變量在類加載的時候就已經初始化好了
singleton* singleton::instance = new singleton();
singleton* singleton::getinstance()
{return instance;  //直接返回inatance
}void Singleton::deleteInstance(){delete instance;
}
int main()
{cout << "we get the instance" << endl;singleton* a1 = singleton::getinstance();singleton* a2 = singleton::getinstance();singleton* a3 = singleton::getinstance();cout << "we destroy the instance" << endl;Singleton::deleteInstance();system("pause");return 0;
}

全局數據區中,存儲的并不是一個實例對象,而是一個實例對象的指針,它是一個地址而已,我們真正占有資源的實例對象是存在堆中,我們需要手動的去調用delete釋放申請的資源。

餓漢模式:在類加載時就完成了初始化,但是加載比較慢,獲取對象比較快。
餓漢模式是線程安全的,在類創建好一個靜態對象提供給系統使用。

OOP設計模式的五項原則

1、單一職責原則
避免將相同的職責分散到不同的類中。避免一個類承擔太多職責。減少類的耦合,提高類的復用性。
2、接口隔離原則
使用多個專門的接口,而不是使用單一的接口。
3、開放——封閉原則
open:模塊的行為必須是開放的,支持擴展的。
closed:模塊在擴展時不應該影響已有的程序模塊
4、替換原則
子類型必須能夠替換掉他們的父類型、并且出現在父類能夠出現的地方
5、依賴倒置原則
上層模塊不應該依賴于下層模塊,他們應該共同依賴于一個抽象。

單例模式中的懶漢加載,如果并發訪問該怎么做

使用鎖機制,防止多次訪問。
第一次判斷為空不加鎖。
若為空,則進行加鎖判斷是否為空,若為空則生成對象。
在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/377279.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/377279.shtml
英文地址,請注明出處:http://en.pswp.cn/news/377279.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

JSON學習資料整理

1.什么是JSON JSON(JavaScript Object Notation) 是一種輕量級的數據交換格式。它基于JavaScript的一個子集。 JSON采用完全獨立于語言的文本格式&#xff0c;但是也使用了類似于C語言家族的習慣&#xff08;包括C, C, C#, Java, JavaScript, Perl, Python等&#xff09;。這些…

OSI七層模型及其數據的封裝和解封過程

OSI(Open System Interconnection)參考模型把網絡分為七層: 1.物理層(Physical Layer) 物理層主要傳輸原始的比特流,集線器(Hub)是本層的典型設備; 2.數據鏈路層(Data Link Layer) 數據鏈路層負責在兩個相鄰節點間無差錯的傳送以幀為單位的數據,本層的典型設備是交換機(Switch)…

rss聚合模式案例_RSS的完整形式是什么?

rss聚合模式案例RSS&#xff1a;真正簡單的聯合 (RSS: Really Simple Syndication) RSS is an abbreviation of Really Simple Syndication. It is also called Rich Site Summary. It is quality attainment for the syndication of collection of web content and used to di…

《MySQL——38道查詢練習(無連接查詢)》

目錄一、準備數據1、創建數據庫2、創建學生表3、創建教師表4、創建課程表5、創建成績表6、添加數據二、查詢練習1、查詢 student 表的所有行2、查詢 student 表中的 name、sex 和 class 字段的所有行3、查詢 teacher 表中不重復的 department 列4、查詢 score 表中成績在60-80之…

工作經常使用的SQL整理,實戰篇(一)

工作經常使用的SQL整理&#xff0c;實戰篇&#xff08;一&#xff09; 原文:工作經常使用的SQL整理&#xff0c;實戰篇&#xff08;一&#xff09;工作經常使用的SQL整理&#xff0c;實戰篇&#xff0c;地址一覽&#xff1a; 工作經常使用的SQL整理&#xff0c;實戰篇&#xff…

XPth和XSLT的一些簡單用法

&#xff08;目的在于讓大家知道有這個東西的存在&#xff09; XPath:即XML Path語言(Xpath)表達式使用路徑表示法(像在URL中使用一樣)來為XML文檔的各部分尋址&#xff01; 關于XPath如何使用了&#xff0c;我們來看看&#xff01;當然這里面的代碼只是入門&#xff0c;更深層…

isc dhcp_ISC的完整形式是什么?

isc dhcpISC&#xff1a;印度學校證書 (ISC: Indian School Certificate) ISC is an abbreviation of the Indian School Certificate. It alludes to the 12th class examination or higher secondary examination conducted by the Council for the Indian School Certificat…

《MySQL——連接查詢》

內連接&#xff1a; inner join 或者 join 外連接 1、左連接 left join 或 left outer join 2、右連接 right join 或 right outer join 3、完全外連接 full join 或 full outer join 圖示理解 全連接 創建person表和card表 CREATE DATABASE testJoin;CREATE TABLE person (…

win7下 apache2.2 +php5.4 環境搭建

這篇文章很好 沒法復制 把鏈接粘貼來http://www.360doc.com/content/13/0506/13/11495619_283349585.shtml# 現在能復制了&#xff1a; 把任何一篇你要復制、卻不讓復制的文章收藏入收藏夾(直接CtrlD,確定) 2在收藏夾中&#xff0c;右擊剛才收藏的那個網址&#xff0c;點屬性 3…

HDU_1533 Going Home(最優匹配) 解題報告

轉載請注明出自cxb:http://blog.csdn.net/cxb569262726 題目鏈接&#xff1a;http://acm.hdu.edu.cn/showproblem.php?pid1533 說實話&#xff0c;這個題目剛開始還真看不出是完備匹配下的最大權匹配&#xff08;當然&#xff0c;這個也可以用網絡流做。&#xff08;應該是添加…

c#中 uint_C#中的uint關鍵字

c#中 uintC&#xff03;uint關鍵字 (C# uint keyword) In C#, uint is a keyword which is used to declare a variable that can store an integral type of value (unsigned integer) the range of 0 to 4,294,967,295. uint keyword is an alias of System.UInt32. 在C&…

《MySQL——事務》

目錄事務的必要性MySQL中如何控制事務手動開啟事務事務的四大特征事務的四大特征事務開啟方式事務手動提交與手動回滾事務的隔離性臟讀現象不可重復讀現象幻讀現象串行化一些補充使用長事務的弊病commit work and chain的語法是做什么用的?怎么查詢各個表中的長事務&#xff1…

運行在TQ2440開發板上以及X86平臺上的linux內核編譯

一、運行在TQ2440開發板上的linux內核編譯 1、獲取源碼并解壓 直接使用天嵌移植好的“linux-2.6.30.4_20100531.tar.bz2”源碼包。 解壓&#xff08;天嵌默認解壓到/opt/EmbedSky/linux-2.6.30.4/中&#xff09; tar xvjf linux-2.6.30.4_20100531.tar.bz2 -C / 2、獲取默認配置…

ArcCatalog ArcMap打不開

原來是因為&#xff1a; 連接了電信的無線網卡 關掉即可 啟動ArcCatalog之后再開啟無線網卡 沒問題&#xff01;轉載于:https://www.cnblogs.com/ccjcjc/archive/2012/08/21/2649867.html

Python熊貓– GroupBy

Python熊貓– GroupBy (Python Pandas – GroupBy) GroupBy method can be used to work on group rows of data together and call aggregate functions. It allows to group together rows based off of a column and perform an aggregate function on them. GroupBy方法可用…

MySQL索引底層原理理解以及常見問題總結

目錄二叉查找樹為索引紅黑樹為索引B樹作為索引B樹作為索引MyISAM存儲引擎索引實現InnoDB存儲引擎索引實現常見問題聚集索引與非聚集索引InnoDB基于主鍵索引和普通索引的查詢有什么區別&#xff1f;InnoDB主鍵索引為何是整型的自增主鍵何時使用業務字段作為主鍵呢&#xff1f;哈…

Spring之HibernateTemplate 和HibernateDaoSupport

spring提供訪問數據庫的有三種方式&#xff1a; HibernateDaoSupport HibernateTemplate&#xff08;推薦使用&#xff09; jdbcTemplate(我們一般不用&#xff09; 類所在包&#xff1a; HibernateTemplate&#xff1a;org.springframework.orm.hibernate3.HibernateTemplate …

JDOJ-重建二叉樹

這是一道面試題&#xff0c;可以說是數據結構中的基礎題了&#xff0c;由先序遍歷以及中序遍歷生成一棵樹&#xff0c;然后輸出后序遍歷。 一個遞歸函數傳遞5個參數&#xff0c;頂點編號&#xff0c;先序左右區間&#xff0c;中序左右區間&#xff0c;每次進行區間長度判定&…

des算法密碼多長_密碼學中的多個DES

des算法密碼多長This is a DES that was susceptible to attacks due to tremendous advances in computer hardware in cryptography. Hence, it was a very complex or competent algorithm it would be feasible to reuse DES rather than writing an of cryptography. 由于…

《MySQL——索引筆記》

目錄回表覆蓋索引最左前綴原則聯合索引的時候&#xff0c;如何安排索引內的字段順序&#xff1f;索引下推重建索引問題聯合主鍵索引和 InnoDB 索引組織表問題in與between的區別回表 回到主鍵索引樹搜索的過程&#xff0c;我們稱為回表。 覆蓋索引 覆蓋索引就是在這次的查詢中…