日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 人文社科 > 生活经验 >内容正文

生活经验

设计模式 之美 -- 原型模式

發(fā)布時(shí)間:2023/11/27 生活经验 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 设计模式 之美 -- 原型模式 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章目錄

        • 1. 解決問(wèn)題
        • 2. 應(yīng)用場(chǎng)景
        • 3. 實(shí)現(xiàn)方式
          • C++實(shí)現(xiàn)
          • C語(yǔ)言實(shí)現(xiàn)
        • 4. 缺點(diǎn)
        • 5. 和其他三種創(chuàng)建模式的對(duì)比(單例,工廠,建造者)

1. 解決問(wèn)題

如果對(duì)象的創(chuàng)建成本較大,而同一個(gè)類的不同對(duì)象之間的差別不大(大部分字段相同),在這種情況下,我們可以利用已有對(duì)象(原型)進(jìn)行賦值(拷貝)的方式,創(chuàng)建新的對(duì)象,從而達(dá)到節(jié)省對(duì)象創(chuàng)建時(shí)間的目的。

2. 應(yīng)用場(chǎng)景

  • 需要在運(yùn)行過(guò)程中,動(dòng)態(tài)的拷貝一份對(duì)象
  • 需要某個(gè)對(duì)象在某個(gè)狀態(tài)下的副本
  • 處理一些簡(jiǎn)單對(duì)象時(shí),對(duì)象之間的差別很小,且重建代價(jià)比較大
  • 使用對(duì)象時(shí),如果對(duì)象的構(gòu)造參數(shù)很多,自己又不能完全確定參數(shù)含義,這個(gè)時(shí)候使用該模式就可以省去了解參數(shù)的過(guò)程,直接使用原型模式獲得同樣的對(duì)象即可

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

淺拷貝:只會(huì)復(fù)制對(duì)象中基本數(shù)據(jù)類型數(shù)據(jù)和引用對(duì)象的內(nèi)存地址,不會(huì)遞歸的復(fù)制引用對(duì)象,以及引用對(duì)象的引用對(duì)象。淺拷貝 存在數(shù)據(jù)被修改的風(fēng)險(xiǎn),會(huì)導(dǎo)致場(chǎng)景變得復(fù)雜多變。

深拷貝:得到一份完完全全的獨(dú)立對(duì)象,深拷貝比起淺拷貝更加耗時(shí),耗內(nèi)存。深拷貝更加安全,拷貝出來(lái)的獨(dú)立的對(duì)象不影響其他的對(duì)象。

C++實(shí)現(xiàn)

實(shí)現(xiàn)功能:一個(gè)簡(jiǎn)單的原型模式,clon成員函數(shù) 用來(lái)創(chuàng)建當(dāng)前類的實(shí)例。

#include <iostream>
#include <ctime>
#include <unistd.h>using namespace std;class Create_Prototype{
public:Create_Prototype():value(6){m_time = time((time_t*)NULL);	}Create_Prototype(Create_Prototype &cp){//普通的拷貝構(gòu)造,僅僅拷貝當(dāng)前對(duì)象的基本數(shù)據(jù)類型的數(shù)據(jù)和引用對(duì)象的內(nèi)存地址。(淺拷貝)this -> value=cp.value;this -> m_time = time((time_t*)NULL);}int get_value(){ return this -> value;}Create_Prototype *clon(){return new Create_Prototype(*this);//使用的是new的方式,會(huì)分配新的對(duì)象空間(深拷貝)}time_t m_time;int value;
};int main()
{Create_Prototype *object = new Create_Prototype();cout <<"value is :" << object->value << " time is : " << object->m_time <<endl;sleep(3);/*原型模式創(chuàng)建對(duì)象 -- 深拷貝*/Create_Prototype *cp_object = object->clon();/*普通的拷貝構(gòu)造 -- 淺拷貝*///Create_Prototype *cp_object = object; //最后的輸出會(huì)出現(xiàn)異常cout <<"value is :" << cp_object->value << " time is : " << cp_object->m_time <<endl;cout << "obj address is: " << object << " value address is : " << &(object->value) << endl;cout << "cp_obj address is: " << cp_object << " value address is : " <<&(cp_object->value) << endl;delete object;delete cp_object;return 0;
}

執(zhí)行輸出如下:

淺拷貝會(huì)拋出異常(可以看到如下輸出,兩個(gè)對(duì)象指向同一塊內(nèi)存地址,最終該內(nèi)存區(qū)域會(huì)釋放兩次,導(dǎo)致異常)

value is :6 time is : 1587708400
value is :6 time is : 1587708400
obj address is: 0x1eb7010 value address is : 0x1eb7018
cp_obj address is: 0x1eb7010 value address is : 0x1eb7018
*** Error in `./a.out': double free or corruption (fasttop): 0x0000000001eb7010 ***

深拷貝(原型模式創(chuàng)建的對(duì)象)正常輸出,且每個(gè)對(duì)象有自己獨(dú)立的內(nèi)存地址

value is :6 time is : 1587708436
value is :6 time is : 1587708439
obj address is: 0x14b8010 value address is : 0x14b8018
cp_obj address is: 0x14b8030 value address is : 0x14b8038
C語(yǔ)言實(shí)現(xiàn)

實(shí)現(xiàn)功能:

動(dòng)態(tài)復(fù)制一個(gè)osd信息結(jié)構(gòu)

1、帶有copy功能的 copy函數(shù)指針
2、copy函數(shù)實(shí)現(xiàn)

#include <stdio.h>
#include <string.h>
#include <stdlib.h>typedef struct OSD_INFO{int osd_id;int osd_type;char osd_name[16];struct OSD_INFO *(*copy)(struct OSD_INFO *);//copy函數(shù)指針
}Osd_Info;/*可以使用該原型操作,消耗很短的時(shí)間來(lái)構(gòu)造大量的同類型的對(duì)象*/
struct OSD_INFO *copy_osd_info(struct OSD_INFO *osd_info)
{struct OSD_INFO *tmp_osd_info = (struct OSD_INFO *)malloc(sizeof(struct OSD_INFO));if (tmp_osd_info == NULL){return NULL;}memmove(tmp_osd_info,osd_info,sizeof(struct OSD_INFO));return tmp_osd_info;
}int main()
{struct OSD_INFO osd_info = {0};struct OSD_INFO *other_osd = NULL;osd_info.osd_id = 1;osd_info.osd_type = 0;strcpy(osd_info.osd_name,"osd.1");osd_info.copy = copy_osd_info;other_osd = osd_info.copy(&osd_info);//原型模式 構(gòu)造一個(gè)新的結(jié)構(gòu)體變量printf("osd id is:%d\n",other_osd->osd_id);printf("osd type is:%d\n",other_osd->osd_type);printf("osd name is:%s\n",other_osd->osd_name);if(other_osd != NULL){free(other_osd);}return 0;
}

輸出如下:

osd id is:1
osd type is:0
osd name is:osd.1

4. 缺點(diǎn)

  1. 在有繼承相關(guān)的類圖中,每個(gè)子類都需要實(shí)現(xiàn)一個(gè)clon函數(shù),如果是新類則只需擴(kuò)展接口,但已有的類則需修改內(nèi)部源碼,違反開(kāi)閉原則
  2. 實(shí)現(xiàn)深拷貝的時(shí)候,如果初始化成員列表較多,則實(shí)現(xiàn)會(huì)比較復(fù)雜

5. 和其他三種創(chuàng)建模式的對(duì)比(單例,工廠,建造者)

單例模式:

在特定模式下(日志系統(tǒng)),一個(gè)類僅允許創(chuàng)建一個(gè)實(shí)例

工廠模式:

創(chuàng)建擁有相關(guān)性的不同對(duì)象(繼承同一父類或者接口的子類),由給定的參數(shù)來(lái)決定創(chuàng)建哪一種類的對(duì)象

建造者模式:

創(chuàng)建一種類型的復(fù)雜對(duì)象,通過(guò)設(shè)置不同的可選參數(shù),“定制化”地創(chuàng)建不同的對(duì)象。

原型模式:

快速創(chuàng)建對(duì)象,針對(duì)部分實(shí)例化成本較大的類,且該類需要頻繁實(shí)例化時(shí)使用原型模式更為格式。

總結(jié)

以上是生活随笔為你收集整理的设计模式 之美 -- 原型模式的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。