偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

設(shè)計(jì)模式 - Prototype 原型模式

開發(fā) 前端
在設(shè)計(jì)模式的系列文章中,我們前面已經(jīng)寫了工廠模式、單列模式、建造者模式,在針對(duì)創(chuàng)建型模式中,今天想跟大家分享的是原型模式。

[[400064]]

前言

在設(shè)計(jì)模式的系列文章中,我們前面已經(jīng)寫了工廠模式、單列模式、建造者模式,在針對(duì)創(chuàng)建型模式中,今天想跟大家分享的是原型模式

其實(shí)原型模式在我們的代碼中是很常見的,但是又容易被我們所忽視的一種模式,那么什么是原型模式呢?

原型模式其實(shí)就是一種克隆對(duì)象的方法,在我們的編碼時(shí)候是很常見的,比如我們常用的的BeanUtils.copyProperties就是一種對(duì)象的淺copy,其實(shí)現(xiàn)在我們實(shí)例化對(duì)象操作并不是特別耗費(fèi)性能,所以在針對(duì)一些特殊場(chǎng)景我們還是需要克隆那些已經(jīng)實(shí)例化的對(duì)象的:

  • 依賴外部資源或硬件密集型操作,比如數(shù)據(jù)庫(kù)查詢,或者一些存在IO操作的場(chǎng)景
  • 獲取相同對(duì)象在相同狀態(tài)的拷貝從而不需要重復(fù)創(chuàng)建獲取狀態(tài)的操作的情況

看下我們的類圖:

在上面的圖中我們可以看出原型模式其實(shí)很簡(jiǎn)單:

  • 第一個(gè)是抽象原型(prototype)聲明clone方法,可以是接口可以是基類,在簡(jiǎn)單的場(chǎng)景下我們都可以不用基類直接具體類就可以了。
  • 第二個(gè)就是具體原型類(concreteprototype)實(shí)現(xiàn)或者擴(kuò)展clone方法,當(dāng)我們?cè)诰唧w的原型類中的對(duì)象方法時(shí),就會(huì)返回一個(gè)基類的抽象原型對(duì)象

針對(duì)上面理論知識(shí),我們還是實(shí)際的舉一個(gè)例子吧!

舉例

假設(shè)現(xiàn)在我們有這么一種場(chǎng)景,公司搞一場(chǎng)活動(dòng)有五萬(wàn)個(gè)商品參加此次活動(dòng),我們需要從后臺(tái)能定時(shí)同步每個(gè)商品的銷量,方便我們?yōu)楹竺娴幕顒?dòng)做商品分析,我們要怎么處理這個(gè)銷量同步問(wèn)題?

首先在這里銷量和庫(kù)存都是屬于熱點(diǎn)數(shù)據(jù),但肯定都是相互隔離的因?yàn)閹?kù)存是要求實(shí)時(shí)性很高的,銷量可以允許有短暫延時(shí),只要能保證數(shù)據(jù)能夠最終一致性就行,所以下單的同時(shí)我們可以根據(jù)一個(gè)MQ去更新我們數(shù)據(jù)庫(kù)里的商品銷量。

在我們?nèi)ゲ榭翠N量的時(shí)候我們不能每次都是去查DB所以我們可以通過(guò)redis緩存來(lái)處理,同時(shí)我們?cè)诰彺嬷杏涗浺幌挛覀儺?dāng)前查詢的更新時(shí)間。

再次查詢時(shí)通過(guò)redis數(shù)據(jù)里面的更新時(shí)間,作為查詢條件去查詢DB中的更新時(shí)間大于我們當(dāng)前redis中的記錄時(shí)間,這樣就減少了SQL的掃表的行數(shù)(更新的數(shù)據(jù)與全量數(shù)據(jù)相比,更新的數(shù)據(jù)量還是占少數(shù)的)

基于上面流程我們開始寫demo了

在這里demo中我們先是創(chuàng)建了一個(gè)ItemSold類,以及一個(gè)SkuSold類同時(shí)ItemSold重寫Cloneable里面的clone方法。然后在最后的測(cè)試類mian方法中我調(diào)用了clone方法,copy一個(gè)新的商品銷量類。

細(xì)心的同學(xué)在看結(jié)果的時(shí)候不知道有沒(méi)有發(fā)現(xiàn)一個(gè)問(wèn)題?在for循環(huán)里面,我分別打印出來(lái)的ItemSold 以及 SkuSold對(duì)象他們的內(nèi)存地址。

復(fù)制出來(lái)的SkuSold的內(nèi)存地址居然和原型地址一樣,ItemSold的復(fù)制就和原型地址不一樣了,針對(duì)這個(gè)問(wèn)題這里我們就要聊聊原型模式的兩種實(shí)現(xiàn)淺拷貝和深拷貝了。

  • 這里說(shuō)明一下我們?cè)趂or循環(huán)里面是做數(shù)據(jù)convert,一般來(lái)說(shuō)我們不會(huì)引用底層模型來(lái)做返回結(jié)果模型,需要做一層轉(zhuǎn)化,來(lái)達(dá)到防腐的效果。為了體現(xiàn)深淺拷貝,所以寫的比較簡(jiǎn)單,具體還是需要自己根據(jù)實(shí)際情況來(lái)做。

淺拷貝和深拷貝

  • 淺拷貝:當(dāng)拷貝對(duì)象只包含簡(jiǎn)單的數(shù)據(jù)類型比如int、float 或者不可變的對(duì)象(字符串)時(shí),就直接將這些字段復(fù)制到新的對(duì)象中。而引用的對(duì)象并沒(méi)有復(fù)制而是將引用對(duì)象的地址復(fù)制一份給克隆對(duì)象
  • 深拷貝:不管拷貝對(duì)象里面簡(jiǎn)單數(shù)據(jù)類型還是引用對(duì)象類型都是會(huì)完全的復(fù)制一份到新的對(duì)象中

舉個(gè)例子這就好比兩兄弟大家買衣服可以一人一套,然后房子大家住在一套房子里(淺拷貝),當(dāng)兩個(gè)人成家立業(yè)了,房子分開了一人一套互不影響(深拷貝)

看完這張圖,大家也就明白了,上面的demo是一個(gè)淺拷貝,那么我們要怎么做才能實(shí)現(xiàn)深拷貝呢?

首先我們先來(lái)看下 Java的提供的Cloneable 接口

看接口上面的解釋大致可以理解為:

  • 一個(gè)類實(shí)現(xiàn)了Cloneable接口,來(lái)實(shí)現(xiàn)這個(gè)類的clone方法從而可以合法地對(duì)該類實(shí)例進(jìn)行按字段復(fù)制,假設(shè)這個(gè)類沒(méi)有實(shí)現(xiàn)Cloneable接口的實(shí)例上調(diào)用Object的clone()方法,則會(huì)導(dǎo)致拋出CloneNotSupporteddException異常。

那么我們這里怎么實(shí)現(xiàn)深拷貝呢?

第一種:在重寫ItemSold里面的clone方法時(shí),再針對(duì)SkuSold也進(jìn)行一次拷貝 (因?yàn)槲覀冞@里時(shí)List對(duì)象,只能是先拿到淺拷貝,再通過(guò)淺拷貝的List對(duì)象進(jìn)行遍歷再調(diào)用引用對(duì)象的clone方法來(lái)實(shí)現(xiàn)深拷貝)

這里如果引用對(duì)象存在多級(jí)情況下我們可能就要考慮用遞歸了實(shí)現(xiàn),但是代碼看上去就會(huì)復(fù)雜很多了。

第二種:通過(guò)序列化把對(duì)象寫入流中再?gòu)牧髦腥〕鰜?lái)

針對(duì)上面的兩種寫法其實(shí)都是可以實(shí)現(xiàn)的,但是不管用哪種方式,深拷貝都比淺拷貝花時(shí)間和空間,所以還是酌情考慮。其實(shí)在現(xiàn)在已經(jīng)有很多針對(duì)淺拷貝和深拷貝的工具類

  • 深拷貝(deep copy):SerializationUtils
  • 淺拷貝(shallow copy):BeanUtils

思考

針對(duì)上面的業(yè)務(wù)場(chǎng)景我們也可以通過(guò)其他的方式統(tǒng)計(jì)商品銷量,可以再通過(guò)一個(gè)MQ去增加銷量的同時(shí)再去更新redis緩存,但是需要我們注意的是在針對(duì)一些核心業(yè)務(wù)數(shù)據(jù)和非核心業(yè)務(wù)數(shù)據(jù)盡量不要共用一個(gè)消費(fèi)者組,防止影響核心數(shù)據(jù)的消費(fèi)速率。同時(shí)我們?cè)谧鲈O(shè)計(jì)的時(shí)候多想想這么做有什么優(yōu)點(diǎn),又有什么缺點(diǎn),開發(fā)成本問(wèn)題等。

其實(shí)在其他的地方我們可以用到原型模式,比如我們?cè)诎l(fā)松活動(dòng)的PUSH通知,針對(duì)平臺(tái)百萬(wàn)、千萬(wàn)、甚至上億的用戶發(fā)送通知的時(shí)候通知的內(nèi)容基本都是一樣的只是推送用戶不一樣或者有些特別字段值的小改動(dòng),那我們這里就可以用原型模式來(lái)做,同時(shí)開啟多線程來(lái)做push,需要注意的是這里的線程安全問(wèn)題,所以在每個(gè)線程內(nèi)部去做copy對(duì)象。

總結(jié)

原型模式使用起來(lái)簡(jiǎn)單,但是在我們每次在clone基類或者有引用對(duì)象的時(shí)候需要我們?nèi)バ薷脑蛯?duì)象的clone方法,這不符合我們開閉原則。

在一般情況下是不建議用這種模式的除非創(chuàng)建的對(duì)象成本特別大,或者在一些特殊場(chǎng)景使用,最后針對(duì)一些不常用的模式我不會(huì)詳細(xì)跟大家分享,但是我會(huì)在后面做個(gè)分享總結(jié),后面開始為大家分享行為型模式。

我是敖丙,你知道的越多,你不知道的越多,我們下期見!

 

責(zé)任編輯:姜華 來(lái)源: 三太子敖丙
相關(guān)推薦

2021-10-28 19:09:09

模式原型Java

2020-10-21 14:29:15

原型模式

2013-11-26 17:00:08

Android設(shè)計(jì)模式

2022-09-21 08:47:05

項(xiàng)目多線程對(duì)象

2023-08-08 20:13:36

設(shè)計(jì)模式原型模式

2021-06-07 09:51:22

原型模式序列化

2020-06-08 08:04:49

設(shè)計(jì)模式結(jié)構(gòu)型接口

2015-06-08 09:05:10

Java原型模式

2020-08-03 08:24:26

原型模式拷貝

2024-12-27 15:10:16

設(shè)計(jì)模式原型模式場(chǎng)景

2025-01-20 09:03:41

項(xiàng)目Error優(yōu)化

2023-07-13 09:28:29

設(shè)計(jì)模式.NET

2016-06-07 14:28:39

Javascript原型

2021-02-01 10:01:58

設(shè)計(jì)模式 Java單例模式

2021-04-19 21:25:48

設(shè)計(jì)模式到元

2020-08-21 07:23:50

工廠模式設(shè)計(jì)

2020-11-04 08:54:54

狀態(tài)模式

2023-04-10 09:20:13

設(shè)計(jì)模式訪客模式

2020-11-03 13:05:18

命令模式

2013-11-26 16:09:34

Android設(shè)計(jì)模式
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)