<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          【JS】708- 創(chuàng)建對(duì)象的最佳方式是什么?

          共 5730字,需瀏覽 12分鐘

           ·

          2020-09-08 09:38

          在現(xiàn)實(shí)生活中,工廠是負(fù)責(zé)生產(chǎn)產(chǎn)品的,比如牛奶、面包或禮物等,這些產(chǎn)品滿足了我們?nèi)粘5纳硇枨蟆?strong style="color: rgb(89, 89, 89);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;font-size: 15px;letter-spacing: 0.75px;text-align: left;white-space: normal;">(文末有精彩送書活動(dòng)喲)

          作為一名 Web 軟件開發(fā)工程師,在軟件系統(tǒng)的設(shè)計(jì)與開發(fā)過程中,我們可以利用設(shè)計(jì)模式來提高代碼的可重用性、可擴(kuò)展性和可維護(hù)性。在眾多設(shè)計(jì)模式當(dāng)中,有一種被稱為工廠模式的設(shè)計(jì)模式,它提供了創(chuàng)建對(duì)象的最佳方式。

          工廠模式可以分為:簡單工廠模式、工廠方法模式和抽象工廠模式。本文阿寶哥將詳細(xì)介紹抽象工廠模式,不過在介紹該模式之前,我們先來回顧一下簡單工廠模式和工廠方法模式。

          一、簡單工廠模式

          1.1 簡單工廠模式簡介

          簡單工廠模式又叫 靜態(tài)方法模式,因?yàn)楣S類中定義了一個(gè)靜態(tài)方法用于創(chuàng)建對(duì)象。簡單工廠讓使用者不用知道具體的參數(shù)就可以創(chuàng)建出所需的 ”產(chǎn)品“ 類,即使用者可以直接消費(fèi)產(chǎn)品而不需要知道產(chǎn)品的具體生產(chǎn)細(xì)節(jié)。

          對(duì)于剛接觸簡單工廠模式的小伙伴來說,看到以上的描述可能會(huì)覺得有點(diǎn)抽象。因此為了讓小伙伴更好地理解簡單工廠模式,阿寶哥以用戶買車為例,來介紹一下 BMW 工廠如何使用簡單工廠模式來生產(chǎn)小汽車。

          在上圖中,阿寶哥模擬了用戶購車的流程,小王和小秦分別向 BMW 工廠訂購了 BMW730 和 BMW840 型號(hào)的車型,接著工廠會(huì)先判斷用戶選擇的車型,然后按照對(duì)應(yīng)的模型進(jìn)行生產(chǎn)并在生產(chǎn)完成后交付給用戶。接下來,我們來看一下如何使用簡單工廠來描述 BMW 工廠生產(chǎn)指定型號(hào)車子的過程。

          class?BMWFactory?{
          ??public?static?produceBMW(model:?"730"?|?"840"):?BMW?{
          ????if?(model?===?"730")?{
          ??????return?new?BMW730();
          ????}?else?{
          ??????return?new?BMW840();
          ????}
          ??}
          }

          const?bmw730?=?BMWFactory.produceBMW("730");
          const?bmw840?=?BMWFactory.produceBMW("840");

          在以上代碼中,我們定義一個(gè) BMWFactory 類,該類提供了一個(gè)靜態(tài)的 produceBMW() 方法,用于根據(jù)不同的模型參數(shù)來創(chuàng)建不同型號(hào)的車子??赐暌陨系拇a,相信很多小伙伴會(huì)覺得很熟悉,因?yàn)樵谝恍╉?xiàng)目中就使用了簡單工廠模式。該模式很簡單,在滿足以下條件下可以考慮使用簡單工廠模式:

          • 工廠類負(fù)責(zé)創(chuàng)建的對(duì)象比較少:由于創(chuàng)建的對(duì)象比較少,不會(huì)造成工廠方法中業(yè)務(wù)邏輯過于復(fù)雜。
          • 客戶端只需知道傳入工廠類靜態(tài)方法的參數(shù),而不需要關(guān)心創(chuàng)建對(duì)象的細(xì)節(jié)。

          了解完簡單工廠模式的應(yīng)用場景,接下來我們來看一下該模式的優(yōu)缺點(diǎn)。

          1.2 簡單工廠模式優(yōu)缺點(diǎn)

          1.2.1 優(yōu)點(diǎn)
          • 將創(chuàng)建實(shí)例與使用實(shí)例的任務(wù)分開,使用者不必關(guān)心對(duì)象是如何創(chuàng)建的,實(shí)現(xiàn)了系統(tǒng)的解耦;
          • 客戶端無須知道所創(chuàng)建的具體產(chǎn)品類的類名,只需要知道具體產(chǎn)品類所對(duì)應(yīng)的參數(shù)即可。
          1.2.2 缺點(diǎn)
          • 由于工廠類集中了所有產(chǎn)品創(chuàng)建邏輯,一旦不能正常工作,整個(gè)系統(tǒng)都要受到影響。
          • 系統(tǒng)擴(kuò)展困難,一旦添加新產(chǎn)品就不得不修改工廠邏輯,在產(chǎn)品類型較多時(shí),也有可能造成工廠邏輯過于復(fù)雜,不利于系統(tǒng)的擴(kuò)展和維護(hù)。

          在一些實(shí)際的項(xiàng)目中,為了避免簡單工廠模式帶來的問題,我們可以考慮使用工廠方法模式。

          二、工廠方法模式

          2.1 工廠方法模式簡介

          工廠方法模式(Factory Method Pattern)又稱為工廠模式,也叫多態(tài)工廠(Polymorphic Factory)模式,它屬于創(chuàng)建型模式。

          在工廠方法模式中,工廠父類負(fù)責(zé)定義創(chuàng)建產(chǎn)品對(duì)象的公共接口,而工廠子類則負(fù)責(zé)生成具體的產(chǎn)品對(duì)象, 這樣做的目的是將產(chǎn)品類的實(shí)例化操作延遲到工廠子類中完成,即通過工廠子類來確定究竟應(yīng)該實(shí)例化哪一個(gè)具體產(chǎn)品類。

          在上圖中,阿寶哥模擬了用戶購車的流程,小王和小秦分別向 BMW 730 和 BMW 840 工廠訂購了 BMW730 和 BMW840 型號(hào)的車子,接著工廠按照對(duì)應(yīng)的模型進(jìn)行生產(chǎn)并在生產(chǎn)完成后交付給用戶。同樣,我們來看一下如何使用工廠方法來描述 BMW 工廠生產(chǎn)指定型號(hào)車子的過程。

          interface?BMWFactory?{
          ??produceBMW():?BMW;
          }

          class?BMW730Factory?implements?BMWFactory?{
          ??produceBMW():?BMW?{
          ????return?new?BMW730();
          ??}
          }

          class?BMW840Factory?implements?BMWFactory?{
          ??produceBMW():?BMW?{
          ????return?new?BMW840();
          ??}
          }

          const?bmw730Factory?=?new?BMW730Factory();
          const?bmw840Factory?=?new?BMW840Factory();

          const?bmw730?=?bmw730Factory.produceBMW();
          const?bmw840?=?bmw840Factory.produceBMW();

          在以上代碼中,我們分別創(chuàng)建了 BMW730Factory 和 BMW840Factory 兩個(gè)工廠類,然后使用這兩個(gè)類的實(shí)例來生產(chǎn)不同型號(hào)的車子。相比前面的簡單工廠模式,工廠方法模式通過創(chuàng)建不同的工廠來生產(chǎn)不同的產(chǎn)品。下面我們來看一下工廠方法有哪些優(yōu)缺點(diǎn)。

          2.2 工廠方法優(yōu)缺點(diǎn)

          2.2.1 優(yōu)點(diǎn)
          • 在系統(tǒng)中加入新產(chǎn)品時(shí),無須修改抽象工廠和抽象產(chǎn)品提供的接口,只要添加一個(gè)具體工廠和具體產(chǎn)品就可以了。這樣,系統(tǒng)的可擴(kuò)展性也就變得非常好,更加符合 “開閉原則”。而簡單工廠模式需要修改工廠類的判斷邏輯。
          • 符合單一職責(zé)的原則,即每個(gè)具體工廠類只負(fù)責(zé)創(chuàng)建對(duì)應(yīng)的產(chǎn)品。而簡單工廠模式中的工廠類存在一定的邏輯判斷。
          • 基于工廠角色和產(chǎn)品角色的多態(tài)性設(shè)計(jì)是工廠方法模式的關(guān)鍵。它能夠使工廠可以自主確定創(chuàng)建何種產(chǎn)品對(duì)象,而如何創(chuàng)建這個(gè)對(duì)象的細(xì)節(jié)則完全封裝在具體工廠內(nèi)部。工廠方法模式之所以又被稱為多態(tài)工廠模式,是因?yàn)樗械木唧w工廠類都具有同一抽象父類。
          2.2.2 缺點(diǎn)
          • 在添加新產(chǎn)品時(shí),需要編寫新的具體產(chǎn)品類,而且還要提供與之對(duì)應(yīng)的具體工廠類,系統(tǒng)中類的個(gè)數(shù)將成對(duì)增加,在一定程度上增加了系統(tǒng)的復(fù)雜度,有更多的類需要編譯和運(yùn)行,會(huì)給系統(tǒng)帶來一些額外的開銷。
          • 一個(gè)具體工廠只能創(chuàng)建一種具體產(chǎn)品。

          這里我們知道在工廠方法模式中,一個(gè)具體工廠只能創(chuàng)建一種具體產(chǎn)品。很明顯這限制該模式的使用場景,那么我們是否能突破該限制呢?答案是可以的。下面我們來介紹抽象工廠模式。

          三、抽象工廠模式

          3.1 抽象工廠簡介

          抽象工廠模式(Abstract Factory Pattern):提供一個(gè)創(chuàng)建一系列相關(guān)或相互依賴對(duì)象的接口,而無須指定它們具體的類。

          在工廠方法模式中具體工廠負(fù)責(zé)生產(chǎn)具體的產(chǎn)品,每一個(gè)具體工廠對(duì)應(yīng)一種具體產(chǎn)品,工廠方法也具有唯一性,一般情況下,一個(gè)具體工廠中只有一個(gè)工廠方法或者一組重載的工廠方法。但是有時(shí)候我們需要一個(gè)工廠可以提供多個(gè)產(chǎn)品對(duì)象,而不是單一的產(chǎn)品對(duì)象。

          在上圖中,阿寶哥模擬了用戶購車的流程,小王向 BMW 工廠訂購了 BMW730,工廠按照 730 對(duì)應(yīng)的模型進(jìn)行生產(chǎn)并在生產(chǎn)完成后交付給小王。而小秦向 BMW 工廠訂購了 BMW840,工廠按照 840 對(duì)應(yīng)的模型進(jìn)行生產(chǎn)并在生產(chǎn)完成后交付給小秦。接下來,我們來看一下如何使用抽象工廠來描述上述的購車過程。

          3.2 抽象工廠實(shí)戰(zhàn)

          1.定義 BMW 抽象類

          abstract?class?BMW?{
          ??abstract?run():?void;
          }

          2.創(chuàng)建 BMW730 類(BMW 730 Model)

          class?BMW730?extends?BMW?{
          ??run():?void?{
          ????console.log("BMW730?發(fā)動(dòng)咯");
          ??}
          }

          3.創(chuàng)建 BMW840 類(BMW 840 Model)

          class?BMW840?extends?BMW?{
          ??run():?void?{
          ????console.log("BMW840?發(fā)動(dòng)咯");
          ??}
          }

          4.定義 BMWFactory 抽象工廠

          abstract?class?BMWFactory?{
          ??abstract?produce730BMW():?BMW730;
          ??abstract?produce840BMW():?BMW840;
          }

          5.創(chuàng)建 ConcreteBMWFactory 類

          class?ConcreteBMWFactory?extends?BMWFactory?{
          ??produce730BMW():?BMW730?{
          ????return?new?BMW730();
          ??}

          ??produce840BMW():?BMW840?{
          ????return?new?BMW840();
          ??}
          }

          6.生產(chǎn)并發(fā)動(dòng) BMW730 和 BMW840

          const?bmwFactory?=?new?ConcreteBMWFactory();

          const?bmw730?=?bmwFactory.produce730BMW();
          const?bmw840?=?bmwFactory.produce840BMW();

          bmw730.run();
          bmw840.run();

          以上代碼運(yùn)行后的輸出結(jié)果為:

          [LOG]:?BMW730?發(fā)動(dòng)咯?
          [LOG]:?BMW840?發(fā)動(dòng)咯

          通過觀察以上的輸出結(jié)果,我們可以知道我們的 ConcreteBMWFactory 已經(jīng)可以正常工作了。在 ConcreteBMWFactory 類中,阿寶哥定義了 produce730BMW()produce840BMW() 這兩個(gè)方法,它們分別用于生產(chǎn) BMW730 和 BMW840 車子。

          看到這里相信有的小伙會(huì)有疑問 —— 抽象工廠模式與工廠方法模式有什么區(qū)別呢?

          抽象工廠模式與工廠方法模式最大的區(qū)別在于:工廠方法模式針對(duì)的是一個(gè)產(chǎn)品等級(jí)結(jié)構(gòu),而抽象工廠模式則需要面對(duì)多個(gè)產(chǎn)品等級(jí)結(jié)構(gòu),一個(gè)工廠等級(jí)結(jié)構(gòu)可以負(fù)責(zé)多個(gè)不同產(chǎn)品等級(jí)結(jié)構(gòu)中的產(chǎn)品對(duì)象的創(chuàng)建。 當(dāng)一個(gè)工廠等級(jí)結(jié)構(gòu)可以創(chuàng)建出分屬于不同產(chǎn)品等級(jí)結(jié)構(gòu)的一個(gè)產(chǎn)品族中的所有對(duì)象時(shí),抽象工廠模式比工廠方法模式更為簡單、有效率。

          了解完抽象工廠模式與工廠方法模式的區(qū)別,最后我們來一起看一下抽象工廠模式的優(yōu)缺點(diǎn)。

          3.3 抽象工廠優(yōu)缺點(diǎn)

          優(yōu)點(diǎn)
          • 抽象工廠模式隔離了具體類的生成,使得客戶并不需要知道什么被創(chuàng)建。由于這種隔離,更換一個(gè)具體工廠就變得相對(duì)容易。所有的具體工廠都實(shí)現(xiàn)了抽象工廠中定義的那些公共接口,因此只需改變具體工廠的實(shí)例,就可以在某種程度上改變整個(gè)軟件系統(tǒng)的行為。
          • 當(dāng)一個(gè)產(chǎn)品族中的多個(gè)對(duì)象被設(shè)計(jì)成一起工作時(shí),它能夠保證客戶端始終只使用同一個(gè)產(chǎn)品族中的對(duì)象。這對(duì)一些需要根據(jù)當(dāng)前環(huán)境來決定其行為的軟件系統(tǒng)來說,是一種非常實(shí)用的設(shè)計(jì)模式。
          缺點(diǎn)
          • 在添加新的產(chǎn)品對(duì)象時(shí),難以擴(kuò)展抽象工廠來生產(chǎn)新種類的產(chǎn)品,這是因?yàn)樵诔橄蠊S角色中規(guī)定了所有可能被創(chuàng)建的產(chǎn)品集合,要支持新種類的產(chǎn)品就意味著要對(duì)該接口進(jìn)行擴(kuò)展,而這將涉及到對(duì)抽象工廠角色及其所有子類的修改,顯然會(huì)帶來較大的不便。

          四、總結(jié)

          根據(jù)模式是用來完成什么工作來劃分,這種方式可分為 創(chuàng)建型模式、結(jié)構(gòu)型模式和行為型模式 3 種。本文介紹的工廠方法和抽象工廠屬于創(chuàng)建型模式,該模式用于描述 “怎樣創(chuàng)建對(duì)象”,它的主要特點(diǎn)是 “將對(duì)象的創(chuàng)建與使用分離”。

          GoF(Gang of Four)中提供了單例、原型、工廠方法、抽象工廠、建造者等 5 種創(chuàng)建型模式。其中阿寶哥已經(jīng)介紹過單例、工廠方法和抽象工廠,在后續(xù)的文章中阿寶哥將介紹建造者模式及如何基于建造者設(shè)計(jì)模式實(shí)現(xiàn)以下功能,感興趣的小伙伴記得關(guān)注喲。

          let?builder:?QueryBuilder?=?new?QueryBuilder();

          let?query:?Query?=?new?Query();
          builder.query?=?query;
          builder.bool().shouldMatch("lot_number",?307).bool().mustMatch("expiry_date",?"September?2020");
          console.log(query.toString());

          1995 年,艾瑞克·伽馬(ErichGamma)、理査德·海爾姆(Richard Helm)、拉爾夫·約翰森(Ralph Johnson)、約翰·威利斯迪斯(John Vlissides)等 4 位作者合作出版了《設(shè)計(jì)模式:可復(fù)用面向?qū)ο筌浖幕A(chǔ)》(Design Patterns: Elements of Reusable Object-Oriented Software)一書,在本教程中收錄了 23 個(gè)設(shè)計(jì)模式,這是設(shè)計(jì)模式領(lǐng)域里程碑的事件,導(dǎo)致了軟件設(shè)計(jì)模式的突破。這 4 位作者在軟件開發(fā)領(lǐng)域里也以他們的 “四人組”(Gang of Four,GoF)匿名著稱。

          五、參考資源

          • 簡單工廠模式(SimpleFactoryPattern)
          • 工廠方法模式(Factory Method)
          • 抽象工廠模式(Abstract Factory)- 最易懂的設(shè)計(jì)模式解析
          • GoF 的 23 種設(shè)計(jì)模式的分類和功能

          推薦閱讀
          TypeScript 設(shè)計(jì)模式之適配器模式

          TypeScript 設(shè)計(jì)模式之適配器模式

          TypeScript 設(shè)計(jì)模式之模板方法

          TypeScript 設(shè)計(jì)模式之模板方法

          TypeScript 設(shè)計(jì)模式之享元模式

          TypeScript 設(shè)計(jì)模式之享元模式

          聚焦全棧,專注分享 TypeScript、Web API、Deno 等技術(shù)干貨。

          瀏覽 29
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  影音先锋色噜噜av | 久久久久久久久久久网站 | 日韩网站免费在线观看 | 日日日日日日日日日日日日日日日干 | 亚洲无码专区精品 |