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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

抽象工厂+反射=反射工厂

發布時間:2025/6/15 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 抽象工厂+反射=反射工厂 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在我的上一篇文章(疑惑?改良?從簡單工廠到工廠方法)中,詳細論述了創建模式中簡單工廠到工廠方法的演變過程,并試圖結合工廠方法的設計以及.net中的反射機制之所長,改良出一種新型的工廠—反射工廠,這當然不是我的首創,經典的PetShop 中便有此工廠的身影。本文嘗試按照前篇文章的思路,借著工廠方法到抽象工廠的演變過程而繼續對抽象工廠進行改良,文章中的思想僅代表了作者當時的觀點,有欠妥的地方,還請各位不吝賜教。

工廠模式

前面的文章提到了簡單工廠和工廠方法其實是一碼事,他們完成了將客戶對產品功能的使用與創建具體產品職責的分割,不同的只不過是他們實現方式上的差異,工廠方法利用更加優雅的多態性取代了相對ugly的switch case…語句,從而很好的體現了設計原則中的OCP原則,此文章將不再強調這種實現上的差異性,而更多的強調兩者之間設計思路上的共性,并將這種共性統稱成為工廠模式,從而進一步與抽象工廠進行對比。

工廠的使用,選擇的過程

工廠模式的使用,實際上是客戶(產品的消費者)對于產品選擇的過程,對于實現了相同功能的產品來講,客戶更加關心的是產品間的差異性,而工廠的作用則是將產品的生產過程封裝,根據客戶的要求直接返回客戶需要的產品。注意,工廠只是隱藏了產品的生產過程,但是并沒有剝奪客戶選擇的權利,那么客戶的這個選擇過程又是如何體現的呢?在簡單工廠中,客戶通過參數的形式告訴工廠需要什么樣的產品,而在工廠方法中,客戶通過對工廠的選擇代替了直接對產品的選擇,注意到工廠方法中一個工廠只有一個Create方法,也就是說一個工廠只負責生產一種產品,那么你選擇了相應的工廠也就等同于你選擇了對應的產品。就連改良后的反射工廠也沒有消去對產品的選擇,只不過是將這種選擇外化(外化到配置文件中,從而使得對代碼的改動最小)。可以說,正是由于產品間的差異性帶給了客戶選擇的權利,這種權利是不應當被工廠取代的,那么工廠模式的價值又在哪里呢?答案是抽象與封裝,工廠模式將由于客戶的不同選擇而可能導致的對已知事物的影響降到最低,途徑是通過抽象產品取代具體產品,使得客戶依賴于抽象(越抽象的東西越穩定),同時將客戶的選擇封裝到一處,隔離與具體產品間的依賴。

工廠模式與抽象工廠

前面說了這么多無關的,為得是做好鋪墊,更加有益于對下文的理解,OK,終于該說說從工廠模式到抽象工廠的轉變了,先來對比兩張類圖:
?工廠方法(Factory Method)

抽象工廠(Abstract Factory)

從圖中我們能夠看到哪些差異?

最明顯的一點就是在工廠方法的類關系圖中只有一類產品,他們實現了一個統一的接口,而抽象工廠有多個類別的產品,他們分別實現了不同的功能(多個接口)。其次的一點差別就是工廠本身所具有的方法數量不同,這點差異其實也是由第一點所導致的,工廠需要有生產不同類別產品的功能,如果抽象工廠中的產品的功能簡化到一個,也便成為了工廠方法。

引出類別的概念,類別是指具有相同功能的一類產品的總稱。

再來看選擇的過程,在工廠方法中,客戶關心的只不過是實現同一樣功能的不同產品間的差異,這是一個一維選擇的過程

1?????????????IFactory?factory?=?new?FactoryA();?//選擇了工廠即選擇了產品
2?????????????IProduct?productA?=?factory.Create();?//工廠只有一個Create方法,只能生產一種產品

而在抽象工廠中,客戶首先要考慮的是需要哪一樣功能,其次要考慮才是產品間的差異。也就是說這是一個二維選擇的過程。

1?????????????IFactory?factory?=?new?FactoryA();?//選擇了某個具體工廠
2?????????????IProduct?productA?=?factory.CreateProductA();?//工廠具有多個Create方法,這里選擇了其中的一個

由于產品類別的增加而導致客戶在考慮產品間差異的同時還要考慮產品間功能的差異,這種二維選擇的過程才是工廠方法與抽象工廠之間的本質區別。

舉個肯德基與麥當勞的例子,假設原來只有一家快餐店叫做麥當勞,提供的食物(具體產品)有漢堡、可樂、薯條,它們都可以滿足你吃東西(抽象接口)的需求,那么你想吃快餐的時候,唯一的選擇就在于吃什么,是一維選擇,現在又開了一家快餐店叫做肯德基,同樣供應漢堡、可樂和薯條,那么現在你若打算吃快餐,除了考慮吃什么外,還要考慮去哪里吃--肯德基還是麥當勞?這便是二維的選擇。通過橫向與縱向的選擇才能最終鎖定你要的產品。?

引入系列的概念,相互間具有差異的同一類別的產品稱為不同的系列,如肯德基和麥當勞就是兩個不同的系列。

這種選擇的區別帶來的另外一個后果就是產品間的差異(系列間的差異)變為客戶的次要選擇,而客戶主要的精力放在了功能的選擇上(類別的選擇)。

我們結合實例來看看抽象工廠的一般設計及實現


客戶調用代碼

1?????????????AbstractFactory?factory?=?new?McDFactory();?//選擇去麥當勞吃
2?????????????IHamburger?hamburger?=?factory.CreateHamburger();?//選擇吃漢堡

可以看到系列間的選擇由工廠的選擇來替代,而類別間的選擇實際上就是工廠內不同類別產品創建方法的選擇。那么如此這般設計是否有依據呢?我們為什么不將工廠設計成為漢堡工廠,可樂工廠和薯條工廠呢?這其實是剛接觸抽象工廠的人經常陷入的誤區,這個問題的關鍵在于需求!需求是來自于客戶的,工廠的設計取決于客戶怎樣使用產品。在這個例子中,之所以要將漢堡、可樂和薯條設計為類別而不是系列,首先是因為他們對于客戶有不同的功能,例如漢堡可以充饑,薯條可以解饞、可樂可以解渴,任何一個客戶希望走進一家店(無論是肯德基還是麥當勞)都能夠得到上面的這三種功能,這才是客戶真正的需求!如果客戶選擇走進了麥當勞,那么他就永遠不會吃到肯德基的食品。這里有點繞可能需要多想一下,再舉個例子幫助理解,比如星際爭霸游戲,里面有三個種族,每個種族的兵營都能生產三種兵,如何選定類別與系列?拋開游戲的設計來講,從用戶的角度出發,我們還是會把系列對應成種族,那是因為任何一個玩家進入游戲后,都希望能夠體驗三個不同的兵種所具有的不同能力,而不是希望擁有一個能夠制造出所有三個種族一級兵的兵營。反過來講,用戶每次進入游戲只可能選擇一個種族,如果他這次選擇了蟲族,那么他就永遠不可能生產出機槍兵。

最后再將上面提到的種種概念進行一下總結

類別 = 接口 = 抽象產品 = 具體產品所具有的共同功能,通過采用工廠的某個具體方法來體現選擇。

系列 = 抽象工廠 = 同一類別間不同產品的差異,通過對實例化某個具體工廠來體現選擇。

反射機制實現選擇邏輯,關于工廠的工廠

有人的地方就有恩怨,有恩怨的地方就有江湖,人就是江湖,你怎么退出?

有選擇的地方就有工廠,由工廠的地方就有反射,選擇就是反射,你怎么設計?

呵呵… 開個玩笑,其實上面所寫的幾段廢話就是為了論證這一個觀點,有選擇的地方就可以反射。看看我是如何把工廠方法改良成反射工廠的,既然工廠方法是一維的選擇可以反射,那么對于抽象工廠這個二維的選擇自然更不在話下,仔細觀察工廠的選擇過程。

1?????????????AbstractFactory?factory?=?new?McDFactory();?//選擇去麥當勞吃
2?????????????IHamburger?hamburger?=?factory.CreateHamburger();?//選擇吃漢堡

發現選擇分別是針對工廠的選擇以及方法的選擇,然而對于工廠內部方法的選擇不適用于反射機制,因為不同的方法實現了不同的功能,相互間沒有統一的接口,何談反射,那么反射自然就只能放在對于工廠的選擇上--它們都繼承自抽象工廠。于是我們建立一個反射工廠用來動態生成需要的具體工廠,即工廠的工廠。話說起來別扭,還是看圖。

?

這里新添加的FFactory就是反射工廠 ,對于反射工廠來說,Abstract Factory就是抽象產品,FactoryA和FactoryB是相應的具體產品。

1?????<appSettings>
2?????????<add?key="factoryName"?value="FactoryA"/>
3?????</appSettings>

反射工廠

1?????????public?static?IFactory?CreateFactory()
2?????????{?
3?????????????//從配置文件中讀取需要實例化的工廠
4?????????????string?factoryName?=?ConfigurationSettings.AppSettings["factoryName"].ToString();
5?
6?????????????AbstractFactory?factory;
7?????????????factory?=?(AbstractFactory)Assembly.Load("Abstract?Factory").CreateInstance("Abstract_Factory.ImproveFactory."?+?factoryName);
8?????????????return?factory;
9?????????}

?客戶使用

1?????????public?void?Run()
2?????????{
3?????????????AbstractFactory factory?=?FFactory.CreateFactory();//生產工廠的工廠,采用反射機制
4?????????????IProduct1?product1?=?factory.CreateProduct1();?
5?????????????IProduct2?product2?=?factory.CreateProduct2();?
6?????????????
7?????????????product1.DoTask1();
8?????????????product2.DoTask2();
9?????????}

補充

抽象工廠的使用除了對多系列多類別的應用外,還有一點很重要的原則,即它的一系列的產品總是在一起使用的,只有這樣才更能體現出抽象工廠的價值,關于這點我會在下一篇中通過與Builder模式作對比來闡述兩者間的相同與異同。

總結

以上是生活随笔為你收集整理的抽象工厂+反射=反射工厂的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。