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

忘了又看,看了又忘?保姆級(jí)教學(xué),一口氣教你玩轉(zhuǎn)三種高頻設(shè)計(jì)模式!

開(kāi)發(fā) 前端
文通過(guò)具體的示例,教大家如何學(xué)習(xí)設(shè)計(jì)模式,保證你看完這篇文章后,這 3 種常用的設(shè)計(jì)模式,能妥妥掌握!

大家好,我是樓仔呀。

無(wú)論大家工作還是面試,都會(huì)用到設(shè)計(jì)模式,如果不結(jié)合具體的場(chǎng)景,通過(guò)書(shū)本學(xué)到的設(shè)計(jì)模式非常容易忘。

本文通過(guò)具體的示例,教大家如何學(xué)習(xí)設(shè)計(jì)模式,保證你看完這篇文章后,這 3 種常用的設(shè)計(jì)模式,能妥妥掌握!

不 BB,上文章目錄。

圖片

1. 一起打豆豆

有個(gè)記者去南極采訪(fǎng)一群企鵝,他問(wèn)第一只企鵝:“你每天都干什么?”

企鵝說(shuō):“吃飯,睡覺(jué),打豆豆!”

接著又問(wèn)第 2 只企鵝,那只企鵝還是說(shuō):“吃飯,睡覺(jué),打豆豆!”

記者帶著困惑問(wèn)其他的企鵝,答案都一樣,就這樣一直問(wèn)了 99 只企鵝。

當(dāng)走到第 100 只小企鵝旁邊時(shí),記者走過(guò)去問(wèn)它:每天都做些什么啊?

那只小企鵝回答:"吃飯,睡覺(jué)."

記者驚奇的又問(wèn):"你怎么不打豆豆?"

小企鵝撇著嘴巴,瞪了記者一眼說(shuō):"我就是豆豆!"

樓哥,你搞錯(cuò)了吧,這是篇技術(shù)文,你咋講笑話(huà)了?甭著急,繼續(xù)往后面看哈~~

2. 模板&策略模式

2.1 實(shí)現(xiàn)姿勢(shì)

我們會(huì)從簡(jiǎn)單到復(fù)雜,講解代碼正確的實(shí)現(xiàn)姿勢(shì),分別為最 Low 方式、常規(guī)方式、模板模式和策略模式。

2.1.1 最 Low 方式

假如現(xiàn)在有 3 只企鵝,都喜歡 “吃飯,睡覺(jué),打豆豆”:

public class littlePenguin {
public void everyDay(){
System.out.println("吃飯");
System.out.println("睡覺(jué)");
System.out.println("用小翅膀打豆豆");
}
}
public class middlePenguin {
public void everyDay(){
System.out.println("吃飯");
System.out.println("睡覺(jué)");
System.out.println("用圓圓的肚子打豆豆");
}
}
public class bigPenguin {
public void everyDay(){
System.out.println("吃飯");
System.out.println("睡覺(jué)");
System.out.println("拿雞毛撣子打豆豆");
}
}
public class test {
public static void main(String[] args){
System.out.println("littlePenguin:");
littlePenguin penguin_1 = new littlePenguin();
penguin_1.everyDay();

System.out.println("middlePenguin:");
middlePenguin penguin_2 = new middlePenguin();
penguin_2.everyDay();

System.out.println("bigPenguin:");
bigPenguin penguin_3 = new bigPenguin();
penguin_3.everyDay();
}
}

看一下執(zhí)行結(jié)果:

littlePenguin:
吃飯
睡覺(jué)
用小翅膀打豆豆
middlePenguin:
吃飯
睡覺(jué)
用圓圓的肚子打豆豆
bigPenguin:
吃飯
睡覺(jué)
拿雞毛撣子打豆豆

這種方式是大家寫(xiě)代碼時(shí),最容易使用的方式,上手簡(jiǎn)單,也容易理解,目前看項(xiàng)目中陳舊的代碼,經(jīng)常能找到它們的影子,下面我們看怎么一步步將其進(jìn)行重構(gòu)。

2.1.2 常規(guī)方式

“吃飯,睡覺(jué),打豆豆” 其實(shí)都是獨(dú)立的行為,為了不相互影響,我們可以通過(guò)函數(shù)簡(jiǎn)單進(jìn)行封裝:

public class littlePenguin {
public void eating(){
System.out.println("吃飯");
}
public void sleeping(){
System.out.println("睡覺(jué)");
}
public void beating(){
System.out.println("用小翅膀打豆豆");
}
}
public class middlePenguin {
public void eating(){
System.out.println("吃飯");
}
public void sleeping(){
System.out.println("睡覺(jué)");
}
public void beating(){
System.out.println("用圓圓的肚子打豆豆");
}
}
// bigPenguin相同,省略...
public class test {
public static void main(String[] args){
System.out.println("littlePenguin:");
littlePenguin penguin_1 = new littlePenguin();
penguin_1.eating();
penguin_1.sleeping();
penguin_1.beating();
// 下同,省略...
}
}

工作過(guò)一段時(shí)間的同學(xué),可能會(huì)采用這種實(shí)現(xiàn)方式,我們有沒(méi)有更優(yōu)雅的實(shí)現(xiàn)方式呢?

2.1.3 模板模式

定義:一個(gè)抽象類(lèi)公開(kāi)定義了執(zhí)行它的方法的方式/模板,它的子類(lèi)可以按需要重寫(xiě)方法實(shí)現(xiàn),但調(diào)用將以抽象類(lèi)中定義的方式進(jìn)行,屬于行為型模式。

這 3 只企鵝,因?yàn)?“吃飯,睡覺(jué)” 都一樣,所以我們可以直接實(shí)現(xiàn)出來(lái),但是他們 “打豆豆” 的方式不同,所以封裝成抽象方法,需要每個(gè)企鵝單獨(dú)去實(shí)現(xiàn) “打豆豆” 的方式。

最后再新增一個(gè)方法 everyDay(),固定每天的執(zhí)行流程:

public abstract class penguin {
public void eating(){
System.out.println("吃飯");
}
public void sleeping(){
System.out.println("睡覺(jué)");
}
public abstract void beating();
public void everyDay(){
this.eating();
this.sleeping();
this.beating();
}
}

每只企鵝單獨(dú)實(shí)現(xiàn)自己 “打豆豆” 的方式:

public class littlePenguin extends penguin {
@Override
public void beating(){
System.out.println("用小翅膀打豆豆");
}
}
public class middlePenguin extends penguin {
@Override
public void beating(){
System.out.println("用圓圓的肚子打豆豆");
}
}
public class bigPenguin extends penguin {
@Override
public void beating(){
System.out.println("拿雞毛撣子打豆豆");
}
}

最后看調(diào)用方式:

public class test {
public static void main(String[] args){
System.out.println("littlePenguin:");
littlePenguin penguin1 = new littlePenguin();
penguin1.everyDay();
System.out.println("middlePenguin:");
middlePenguin penguin2 = new middlePenguin();
penguin2.everyDay();
System.out.println("bigPenguin:");
bigPenguin penguin3 = new bigPenguin();
penguin3.everyDay();
}
}

樓哥,你這代碼看的費(fèi)勁,能給我畫(huà)一個(gè) UML 圖么?來(lái),安排!

圖片

2.1.4 策略模式

定義:一個(gè)類(lèi)的行為或其算法可以在運(yùn)行時(shí)更改,即我們創(chuàng)建表示各種策略的對(duì)象和一個(gè)行為隨著策略對(duì)象改變而改變的 context 對(duì)象,策略對(duì)象改變 context 對(duì)象的執(zhí)行算法,屬于行為型模式。

我們還是先抽象出 3 個(gè)企鵝的行為:

每只企鵝單獨(dú)實(shí)現(xiàn)自己 “打豆豆” 的方式:

public class littlePenguin extends penguin {
@Override
public void beating(){
System.out.println("用小翅膀打豆豆");
}
}
public class middlePenguin extends penguin {
@Override
public void beating(){
System.out.println("用圓圓的肚子打豆豆");
}
}
public class bigPenguin extends penguin {
@Override
public void beating(){
System.out.println("拿雞毛撣子打豆豆");
}
}

這里就是策略模式的重點(diǎn),我們?cè)倏匆幌虏呗阅J降亩x “我們創(chuàng)建表示各種策略的對(duì)象和一個(gè)行為隨著策略對(duì)象改變而改變的 context 對(duì)象”,那么該 contex 對(duì)象如下:

public class behaviorContext {
private penguin _penguin;

public behaviorContext(penguin newPenguin){
_penguin = newPenguin;
}
public void setPenguin(penguin newPenguin){
_penguin = newPenguin;
}
public void everyDay(){
_penguin.eating();
_penguin.sleeping();
_penguin.beating();
}
}

最后看調(diào)用方式:

public class test {
public static void main(String[] args){
behaviorContext behavior = new behaviorContext(new littlePenguin());
behavior.everyDay();

behavior.setPenguin(new middlePenguin());
behavior.everyDay();

behavior.setPenguin(new bigPenguin());
behavior.everyDay();
}
}

我們可以通過(guò)給 behaviorContext 傳遞不同的對(duì)象,然后來(lái)約定 everyDay() 的調(diào)用方式。

其實(shí)我這個(gè)示例,有點(diǎn)把策略模式講復(fù)雜了,因?yàn)榧兇獾牟呗阅J剑? 個(gè)企鵝只有 beating() 方法不同,所以可以把 beating() 理解為不同的算法即可。

之所以引入 everyDay(),是因?yàn)閷?shí)際的項(xiàng)目場(chǎng)景中,會(huì)經(jīng)常這么使用,也就是把這個(gè)變化的算法 beating(),包裝到具體的執(zhí)行流程里面,所以策略模式就看起來(lái)沒(méi)有那么直觀,但是核心思想是一樣的。

圖片

2.2 模板 vs 策略

我在選擇模板模式和策略模式時(shí),發(fā)現(xiàn)兩者都可以完全滿(mǎn)足我的需求,然后我到網(wǎng)上查閱了很多資料,希望能找到兩種模式在技術(shù)選擇時(shí),能確定告訴我哪些情況需要選擇哪種模式。

說(shuō)來(lái)慚愧,到現(xiàn)在我都沒(méi)有找到,因?yàn)榫W(wǎng)上只告訴我兩種實(shí)現(xiàn)姿勢(shì)的區(qū)別,但是沒(méi)有說(shuō)明如何具體選型。

2.2.1 網(wǎng)上觀點(diǎn)

據(jù)我可以告訴他們是 99% 相同,唯一的區(qū)別是模板方法模式具有抽象類(lèi)作為基類(lèi),而戰(zhàn)略類(lèi)使用由每個(gè)具體戰(zhàn)略類(lèi)實(shí)現(xiàn)的接口,兩者的主要區(qū)別在于具體 algorithm 的 select。

使用 Template 方法模式時(shí),通過(guò)子類(lèi)化模板在編譯時(shí)發(fā)生,每個(gè)子類(lèi)通過(guò)實(shí)現(xiàn)模板的抽象方法提供了一個(gè)不同的具體 algorithm。

當(dāng)客戶(hù)端調(diào)用模板的外部接口的方法時(shí),模板根據(jù)需要調(diào)用其抽象方法(其內(nèi)部接口)來(lái)調(diào)用 algorithm。

相比之下,策略模式允許在運(yùn)行時(shí)通過(guò)遏制來(lái) select algorithm,具體 algorithm 是通過(guò)單獨(dú)的類(lèi)或函數(shù)實(shí)現(xiàn)的,這些類(lèi)或函數(shù)作為 parameter passing 給構(gòu)造函數(shù)或構(gòu)造方法。

上面講的有點(diǎn)抽象,下面直接看具體對(duì)比。

圖片

相似:

  • 策略和模板方法模式都可以用來(lái)滿(mǎn)足開(kāi)閉原則,使得軟件模塊在不改變代碼的情況下易于擴(kuò)展;
  • 兩種模式都表示通用 function 與該 function 的詳細(xì)實(shí)現(xiàn)的分離,不過(guò)它們所提供的粒度有一些差異。

差異:

  • 策略模式:

它基于接口;

客戶(hù)和策略之間的耦合更加松散;

定義不能被子類(lèi)改變的 algorithm 的骨架,只有某些操作可以在子類(lèi)中重寫(xiě);

父類(lèi)完全控制 algorithm ,僅將具體的步驟與具體的類(lèi)進(jìn)行區(qū)分;

綁定是在編譯時(shí)完成的。

  • 模板模式:

它基于框架或抽象類(lèi),甚至可以有一個(gè)具有默認(rèn)實(shí)現(xiàn)的具體類(lèi)。

模塊耦合得更緊密;

它通過(guò)修改方法的行為來(lái)改變對(duì)象的內(nèi)容;

它用于在 algorithm 族之間切換;

它在運(yùn)行時(shí)通過(guò)其他 algorithm 完全 replace 一個(gè)algorithm 來(lái)改變對(duì)象的行為;

綁定在運(yùn)行時(shí)完成。

2.2.2 個(gè)人理解

對(duì)于有強(qiáng)迫癥的我,沒(méi)有找到問(wèn)題的根源,總感覺(jué)哪里不對(duì)勁,我就說(shuō)一下我對(duì)于兩者區(qū)別的理解吧。

說(shuō)實(shí)話(huà),兩種設(shè)計(jì)模式,我也就看到在實(shí)現(xiàn)姿勢(shì)上有所區(qū)別,至于說(shuō)的策略模式要定義統(tǒng)一接口,模板模式不這樣做等,我不太贊同,因?yàn)槲矣袝r(shí)也會(huì)給模板模式定義一個(gè)通用接口。

然后也有人說(shuō),策略模式需要定義一堆對(duì)象,模板模式就不需要,如果有 10 個(gè)不同的企鵝,模板模式不也是需要定義 10 個(gè)不同的企鵝類(lèi),然后再專(zhuān)門(mén)針對(duì)特定的方法去實(shí)現(xiàn)么?

這兩種設(shè)計(jì)模式,我感覺(jué)還沒(méi)有到非此即彼的劃分。

如果我沒(méi)有固定的執(zhí)行流程,比如只去打豆豆,只需要對(duì)一個(gè)方法做具體抽象,我愿意選擇策略模式,因?yàn)檫@個(gè)我感覺(jué)會(huì)讓我需要使用的對(duì)象,更清晰一些。

如果我有固定的執(zhí)行流程,比如 “吃飯、睡覺(jué)、打豆豆”,我更愿意使用模板方法,可能是代碼看多了,也看習(xí)慣了,更愿意用模板方法去規(guī)范代碼固定的執(zhí)行流程。

當(dāng)然,我也可以將兩者結(jié)合起來(lái)使用,比如我們可以用模板方法,去實(shí)現(xiàn)這 3 只企鵝,但是對(duì)于 middlePenguin,可能有分為企鵝少年 A、企鵝少年 B、企鵝少年 C,他們都喜歡隔壁的企鵝妹妹,但是喜歡的方式不同,有暗戀的,有直接表白的,還有霸道總裁的,我可以用策略模式,去指定他們對(duì)企鵝妹妹的表達(dá)方式。

2.3 實(shí)際場(chǎng)景

任何模式,都需要結(jié)合實(shí)際的場(chǎng)景來(lái)講,才能更清晰。

這兩個(gè)模式,可以在你之前做過(guò)的項(xiàng)目中,只要稍微留意一下,應(yīng)該會(huì)發(fā)現(xiàn)它們其實(shí)是大量存在的。

比如很多框架代碼,里面有很多固定的執(zhí)行流程,有些邏輯是可以采用默認(rèn)處理的方式,有些邏輯需要下游自己去實(shí)現(xiàn),然后有些邏輯還需要提前預(yù)留鉤子。

比如在執(zhí)行 process() 流程時(shí),可能需要進(jìn)行 preProcess() 的操作,那么這個(gè) preProcess() 就是你預(yù)留的鉤子,下游可以實(shí)現(xiàn),也可以不實(shí)現(xiàn)。

3. 工廠(chǎng)模式

后面會(huì)結(jié)合模板模式,來(lái)講解工廠(chǎng)模式,實(shí)戰(zhàn)場(chǎng)景非常強(qiáng)。

3.1 問(wèn)題引入

對(duì)于工廠(chǎng)模式,大家可能覺(jué)得會(huì)很 Low,不就是搞個(gè)類(lèi),然后專(zhuān)門(mén)生成一個(gè)具體的對(duì)象嘛,這有什么難的?

是的,工廠(chǎng)模式確實(shí)不難,但是問(wèn)你一下,如果你的代碼中有很多 if...else,你知道怎么通過(guò)工廠(chǎng)模式,把這些 if...else 去掉么?

嗯,工廠(chǎng)模式我會(huì),但是和去掉 if...else 好像沒(méi)有關(guān)系吧?

我舉個(gè)例子,假如你遇到如下代碼:

switch($taskInfo['type_id']) {
//批量?jī)鼋Y(jié)訂單
case 1:
$result = self::batchFrozen($row_key,1);
break;
//批量解凍訂單
case 2:
$result = self::batchFrozen($row_key,0);
break;
//批量允許發(fā)貨
case 3:
$result =self::batchReshipment($row_key);
break;
//批量取消發(fā)貨
case 4:
$result = self::batchCancel($row_key);
break;
// 后面還有幾十個(gè)case,省略...

既然你懂工廠(chǎng)模式,可以把 if...else 簡(jiǎn)單重構(gòu)一下,那就開(kāi)始你的表演吧。

什么?不會(huì)?!你剛才還是自己是會(huì)工廠(chǎng)模式,怎么突然就慫了呢?

既然不會(huì),那就靜下心來(lái),虛心學(xué)習(xí)一下。

3.2 工廠(chǎng)模式

定義:它提供了一種創(chuàng)建對(duì)象的最佳方式,我們?cè)趧?chuàng)建對(duì)象時(shí)不會(huì)對(duì)客戶(hù)端暴露創(chuàng)建邏輯,并且是通過(guò)使用一個(gè)共同的接口來(lái)指向新創(chuàng)建的對(duì)象,屬于創(chuàng)建型模式。

先直接上圖,后面的示例主要通過(guò)該圖展開(kāi):

圖片

其實(shí)設(shè)計(jì)模式一般不會(huì)單一使用,通常會(huì)和其它模式結(jié)合起來(lái)使用,這里我們就將上一篇文章講到的模板模式和工廠(chǎng)模式結(jié)合起來(lái)。

因?yàn)楣S(chǎng)模式,通常會(huì)給這些新創(chuàng)建的對(duì)象制定一個(gè)公共的接口,我們可以通過(guò)抽象類(lèi)定義:

public abstract class penguin {
public void eating(){
System.out.println("吃飯");
}

public void sleeping(){
System.out.println("睡覺(jué)");
}

public abstract void beating();

public void everyDay(){
this.eating();
this.sleeping();
this.beating();
}
}

因?yàn)槲覀兪墙Y(jié)合了模板模式,所以這個(gè)抽象類(lèi)中,可以看到模板模式的影子。

如果你只關(guān)注抽象的接口,比如 beating,那么這個(gè)就是一個(gè)抽象方法,也可以理解為下游需要實(shí)現(xiàn)的方法,其它的接口其實(shí)可以忽略。

看看每個(gè)企鵝具體的實(shí)現(xiàn):

public class littlePenguin extends penguin {
@Override
public void beating(){
System.out.println("用小翅膀打豆豆");
}
}
public class middlePenguin extends penguin {
@Override
public void beating(){
System.out.println("用圓圓的肚子打豆豆");
}
}
public class bigPenguin extends penguin {
@Override
public void beating(){
System.out.println("拿雞毛撣子打豆豆");
}
}

這里是工廠(chǎng)方法的重點(diǎn),需要構(gòu)建一個(gè)工廠(chǎng),專(zhuān)門(mén)用來(lái)拿企鵝:

public class penguinFactory {
private static final Map<String, penguin> map = new HashMap<>();
static {
map.put("littlePenguin", new littlePenguin());
map.put("middlePenguin", new middlePenguin());
map.put("bigPenguin", new bigPenguin());
}
// 獲取企鵝
public static penguin getPenguin(String name){
return map.get(name);
}
}

上面的邏輯很簡(jiǎn)單,就是通過(guò)一個(gè) map 對(duì)象,放入所有的企鵝,這個(gè)工廠(chǎng)就可以通過(guò)企鵝的名字,拿到對(duì)應(yīng)的企鵝對(duì)象,最后我們看使用方式:

public class test {
public static void main(String[] args){
penguin penguin_1 = penguinFactory.getPenguin("littlePenguin");
penguin_1.everyDay();
penguin penguin_2 = penguinFactory.getPenguin("middlePenguin");
penguin_2.everyDay();
penguin penguin_3 = penguinFactory.getPenguin("bigPenguin");
penguin_3.everyDay();
}
}

輸出如下:

吃飯
睡覺(jué)
用小翅膀打豆豆
吃飯
睡覺(jué)
用圓圓的肚子打豆豆
吃飯
睡覺(jué)
拿雞毛撣子打豆豆

樓哥,你這個(gè)例子我看懂了,但是你最開(kāi)始拋的那個(gè)問(wèn)題,能給出答案么?

3.3 問(wèn)題解答

文章開(kāi)頭的這個(gè)示例,其實(shí)也是我最近需要重構(gòu)項(xiàng)目中的一段代碼,我就是用 “工廠(chǎng)模式 + 模板模式” 來(lái)重構(gòu)的。

我首先會(huì)對(duì)每個(gè)方法中的內(nèi)容通過(guò)模板模式進(jìn)行抽象(因?yàn)楸菊轮饕v工廠(chǎng)模式,模板模式的代碼,我就不貼了),然后通過(guò)工廠(chǎng)模式獲取不同的對(duì)象,直接看重構(gòu)后的代碼:

public class TaskFactory {
@Autowired
public static List<AbstractTask> taskList;
private static final Map<String, AbstractTask> map = new HashMap<>();
static {
// 存放任務(wù)映射關(guān)系
map.put(AbstractTask.OPERATOR_TYPE_FROZEN, new BatchFrozenTask());
map.put(AbstractTask.OPERATOR_TYPE_REJECT, new BatchRejectTask());
map.put(AbstractTask.OPERATOR_TYPE_CANCEL, new BatchCancelTask());
}

public static void main(String[] args){
String operatorType = AbstractTask.OPERATOR_TYPE_REJECT;
AbstractTask task = TaskFactory.map.get(operatorType);
ParamWrapper<CancelParams> params = new ParamWrapper<CancelParams>();
params.rowKey = 11111111;
params.data = new CancelParams();
OcApiServerResponse res = task.execute(params);
System.out.println(res.toString());
return;
}
}

3.4 實(shí)際場(chǎng)景

這個(gè)場(chǎng)景就太多了,剛才給大家講解的是去掉 if...else 的場(chǎng)景,然后在小米商城的支付系統(tǒng)中,因?yàn)楹M庥袔资N支付方式,也是通過(guò)這種方式去掉 if...else 的,不過(guò)支付類(lèi)的封裝不是用的模板方法,用的的策略模式,雖然感覺(jué)兩者差不多。

如果你直接 new 一個(gè)對(duì)象就能解決的問(wèn)題,就用不到工廠(chǎng)模式了。

4. 結(jié)語(yǔ)

看完這篇文章,相信這 3 種設(shè)計(jì)模式,已經(jīng)深深刻在你骨子里面了。

大家可以靜下心來(lái)想想,自己之前做過(guò)的項(xiàng)目中,有哪些用到上面這 3 種設(shè)計(jì)模式,然后自己再結(jié)合具體的場(chǎng)景總結(jié)一下,我想你應(yīng)該會(huì)有更深入的理解。

責(zé)任編輯:武曉燕 來(lái)源: 樓仔
相關(guān)推薦

2019-07-18 09:17:19

Kafka消息隊(duì)列服務(wù)器

2020-04-14 13:32:56

@Transacti失效場(chǎng)景

2020-03-31 08:12:25

Kafka架構(gòu)數(shù)據(jù)庫(kù)

2021-06-08 22:43:07

IPC方式Qt

2021-12-06 08:30:49

SpringSpring Bean面試題

2025-05-14 01:55:00

FCMCPAI

2021-03-29 12:22:25

微信iOS蘋(píng)果

2022-05-24 11:50:46

延時(shí)消息分布式

2020-12-21 06:07:35

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

2020-09-24 09:08:04

分布式系統(tǒng)架構(gòu)

2020-10-22 12:30:33

MySQL

2023-12-18 23:09:25

開(kāi)源優(yōu)化引擎

2024-03-26 09:42:27

分片算法應(yīng)用

2020-07-08 07:45:44

OAuth2.0授權(quán)

2020-04-16 12:42:42

附近的人共享單車(chē)App

2020-08-12 09:55:07

附近的人數(shù)據(jù)庫(kù)MySQL

2021-05-18 09:03:16

Gomapslice

2021-01-04 11:23:21

手機(jī)無(wú)線(xiàn)電通訊

2021-03-01 18:52:39

工具在線(xiàn)瀏覽器

2024-01-29 00:29:49

通信技術(shù)行業(yè)
點(diǎn)贊
收藏

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