iOS設計模式—工廠方法(簡單工廠模式,工廠方法模式, 抽象工廠模式)

来源:http://www.cnblogs.com/Samboo/archive/2016/04/26/5435930.html
-Advertisement-
Play Games

1. 簡單工廠模式 如何理解簡單工廠,工廠方法, 抽象工廠三種設計模式? 簡單工廠的生活場景,賣早點的小攤販,他給你提供包子,饅頭,地溝油烙的煎餅等,小販是一個工廠,它生產包子,饅頭,地溝油烙的煎餅。該場景對應的UML圖如下所示: 圖1:簡單工廠模式UML圖 簡單工廠模式的參與者: 工廠(Facto ...


1. 簡單工廠模式


如何理解簡單工廠,工廠方法, 抽象工廠三種設計模式?

 

簡單工廠的生活場景,賣早點的小攤販,他給你提供包子,饅頭,地溝油烙的煎餅等,小販是一個工廠,它生產包子,饅頭,地溝油烙的煎餅。該場景對應的UML圖如下所示:


圖1:簡單工廠模式UML圖


簡單工廠模式的參與者:

 

工廠(Factory)角色:接受客戶端的請求,通過請求負責創建相應的產品對象。

 

抽象產品(Abstract Product)角色: 是工廠模式所創建對象的父類或是共同擁有的介面。可是抽象類或介面。

 

具體產品(ConcreteProduct)對象:工廠模式所創建的對象都是這個角色的實例。

 

簡單工廠模式的演變:

1.當系統中只有唯一的產品時,可以省略抽象產品,如圖1所示。這樣,工廠角色與具體產品可以合併。

 

簡單工廠模式的優缺點:

1.)工廠類含有必要的創建何種產品的邏輯,這樣客戶端只需要請求需要的產品,而不需要理會產品的實現細節。

2.)工廠類只有一個,它集中了所有產品創建的邏輯,它將是整個系統的瓶頸,同時造成系統難以拓展。

3.)簡單工廠模式通常使用靜態工廠方法,這使得工廠類無法由子類繼承,這使得工廠角色無法形成基於繼承的等級結構。


2. 工廠方法模式

工廠方法使用OOP的多態性,將工廠和產品都抽象出一個基類,在基類中定義統一的介面,然後在具體的工廠中創建具體的產品。工廠方法的生活場景,聯合利華要生產“夏士蓮”和“清揚兩款洗髮水,它會建一個生產“夏士蓮的工廠和一個生產“清揚的工廠。


圖2:工廠方法的UML圖

 

工廠方法模式中的參與者:

 

抽象工廠角色:與應用程式無關,任何在模式中創建對象的工廠必須實現這個介面。
具體工廠角色:實現了抽象工廠介面的具體類,含有與引用密切相關的邏輯,並且受到應用程式的調用以創建產品對象。
抽象產品角色:工廠方法所創建產品對象的超類型,也就是產品對象的共同父類或共同擁有的介面。
具體產品角色:這個角色實現了抽象產品角色所聲名的介面。工廠方法所創建的每個具體產品對象都是某個具體產品角色的實例。

 

 

工廠方法的優缺點:

 

1.降低了工廠類的內聚,滿足了類之間的層次關係,又很好的符合了面向對象設計中的單一職責原則,這樣有利於程式的拓展,如圖三所示:

圖3:工廠方法的拓展UML圖

總結:共性提取出來,根據各自的個性建立各自的繼承共性的實現


3. 抽象工廠設計模式

 

所謂抽象工廠是指一個工廠等級結構可以創建出分屬於不同產品等級結構的一個產品族中的所有對象,以創建Unix控制項和Windows控制項為例說明,我們需要一個抽象工廠下麵有兩個子工廠,一個叫做UnixFactory,用於生產Unix族控制項,一個叫做WinFactory,用於生產Win族控制項。抽象工廠與工廠方法的區別是,工廠方法中的具體工廠一般只生產一個或幾個控制項對象,而抽象工廠中的具體工廠生產的是一族控制項對象。如圖4所示。


圖4:抽象工廠設計模式UML圖


 

抽象工廠中的參與者:

抽象工廠(Abstract Factory)角色:擔任這個角色的是工廠方法模式的核心,它是與應用系統商業邏輯無關的。

具體工廠(Concrete Factory)角色:這個角色直接在客戶端的調用下創建產品的實例。這個角色含有選擇合適的產品對象的邏輯,而這個邏輯是與應用系統的商業邏輯緊密相關的。

抽象產品(Abstract Product)角色:擔任這個角色的類是工廠方法模式所創建的對象的父類,或它們共同擁有的介面。

具體產品(Concrete Product)角色:抽象工廠模式所創建的任何產品對象都是某一個具體產品類的實例。這是客戶端最終需要的東西,其內部一定充滿了應用系統的商業邏輯。

 

抽象工廠的使用場景:

  • 一個系統不應當依賴於產品類實例如何被創建、組合和表達的細節,這對於所有形態的工廠模式都是重要的。
  • 這個系統有多於一個的產品族,而系統只消費其中某一產品族。
  • 同屬於同一個產品族的產品是在一起使用的,這一約束必須在系統的設計中體現出來。
  • 系統提供一個產品類的庫,所有的產品以同樣的介面出現,從而使客戶端不依賴於實現。

 

抽象工廠模式與工廠方法模式的區別

 

工廠方法模式:每個抽象產品派生多個具體產品類,每個抽象工廠類派生多個具體工廠類,每個具體工廠類負責一個具體產品的實例創建; 
抽象工廠模式:每個抽象產品派生多個具體產品類,每個抽象工廠派生多個具體工廠類,每個具體工廠負責多個(一系列)具體產品的實例創建。 



//在UIKit框架下,我們用工廠方法和抽象工廠兩種設計模式分別實現了兩份Demo, 不理解兩種設計模式該如何實現的朋友可以到這裡下載:  刷不出來,以後補上!



 

1. 主要區別

 

抽象工廠

工廠方法

通過對像組合創建產品 通過類繼承來創建產品

生成一系列產品(eg:生成某類view,button,或者其他)

生成某一種產品(eg:生成某類view)

必須修改父類介面,才能生成新的產品 子類化創建者並重載工廠方法 以創建新產品



2. 具體的分析(以下代碼引用書上面的例子)

2.1 工廠方法

 

顯然,下麵的例子中PaperCanvasView和ClothCanvasView繼承自CanvasView,通過重載CanvasView的工廠方法而生成了新的一種產品。

 

  1. @interface CanvasViewGenerator : NSObject
複製代碼

 

  1. @implementation PaperCanvasViewGenerator

  2. - (CanvasView *) canvasViewWithFrame:(CGRect) aFrame {

  3.   return [[[PaperCanvasView alloc] initWithFrame:aFrame] autorelease];

  4. }
複製代碼

 

  1. @implementation ClothCanvasViewGenerator


  2. - (CanvasView *) canvasViewWithFrame:(CGRect) aFrame {

  3.   return [[[ClothCanvasView alloc] initWithFrame:aFrame] autorelease];

  4. }
複製代碼

 

工廠方法的應用場景:

 

1. 編譯時無法準備預期要生成的創建的對象的類

 

2. 類需要由子類決定運行時生成什麼。

 

2.2 抽象工廠

 

一樣的先上代碼:

 

  1. @interface BrandingFactory : NSObject

  2. + (BrandingFactory *) factory;

  3. - (UIView *) brandedView;

  4. - (UIButton *) brandedMainButton;

  5. - (UIToolbar *) brandedToolbar;
複製代碼

 

  1. @implementation BrandingFactory

  2. + (BrandingFactory *) factory {

  3.   #if defined (USE_ACME)

  4.     return [[[AcmeBrandingFactory alloc] init] autorelease];

  5.   #elif defined (USE_SIERRA)

  6.     return [[[SierraBrandingFactory alloc] init] autorelease];

  7.   #else

  8.     return nil;

  9.   #endif

  10. }

  11. - (UIView *) brandedView {

  12. return nil;

  13. }

  14. - (UIButton *) brandedMainButton {

  15. return nil;

  16. }

  17. - (UIToolbar *) brandedToolbar{

  18. return nil;

  19. }
複製代碼

顯然這裡有兩個工廠,生成了一系列的產品如 UIView, UIButton,  UIToolbar。而這兩個工廠又是由BrandingFactory產生的。子類需要重寫這三個方法才能生成新的產品。

抽象工廠的應用場景:

 

抽象工廠提供一個固定的介面,用於創建一系列由關聯或者相依存的對象,而不必指定其具體類或其創建細節。

 

(引 用書中的例子:雖然每家店的比薩餅不一樣,同一家比薩餅也有多種口味,但是製作的基本步驟確實一樣的。對於我們,將比薩餅看成一種食物,廚師就像是生成比 薩餅的工廠。但實際的產品的細節會有所不同。所以,廚師們都知道製作比薩餅的“通用的”或“抽象”的基本知識,但他們有自己的“實現”或“具體”,因此產 生的比薩餅不一樣)

 

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 與其他編程語言所不同的是,Swift 並不要求你為自定義類和結構去創建獨立的介面和實現文件。你所要做的是在一個單一文件中定義一個類或者結構體,系統將會自動生成面向其它代碼的外部介面。 註意:通常一個類的實例被稱為對象。然而在Swift 中,類和結構體的關係要比在其他語言中更加的密切,本章中所討論的大 ...
  • 第一種方法:如果使用導航第一個按鈕方法:[self.navigationController pushViewController:secondVC animated:YES];第二個按鈕方法:[self.navigationController popViewControllerAnimated: ...
  • copy與retain的區別: copy是創建一個新對象,retain是創建一個指針,引用對象計數加1。Copy屬性表示兩個對象內容相同,新的對象retain為1 ,與舊有對象的引用計數無關,舊有對象沒有變化。copy減少對象對上下文的依賴。 retain屬性表示兩個對象地址相同(建立一個指針,指針 ...
  • 傳值方式 1 初始化傳值:(順傳) 自定義初始化方法在 UI中,一般在一個界面推送另一個界面的時候,因此要是想用想到既然要用自定義初始化方法,至少要在該方法中去創建該對象.所以這種方式不適合回調. 自定義初始化方法,將需要傳遞的內容作為參數,如需要傳遞多個,則設置多個參數. 在合適的地方進行調用自定 ...
  • 傳值 1 順向傳值 順傳 屬性傳值 運行方式為 A à B 原理: 在B頁面的控制器中,創建需要的屬性,由於控制器是由 A 跳到 B 的,因此可以在 A 中拿到 B 中的屬性,直接賦值.(賦值在控制器跳轉的時候完成) 在 B 中定義一個屬性 在 A 中拿到 B 的非私有屬性 在 A 中直接對 A 拿 ...
  • title: Android學習路線總結,絕對乾貨 tags: Android學習路線,Android學習資料,怎麼學習android grammar_cjkRuby: true 一、前言 不知不覺自己已經做了幾年開發了,由記得剛出來工作的時候感覺自己能牛逼,現在回想起來感覺好無知。懂的越多的時候你 ...
  • 1、今天我們來分析Service中的一個小技巧:前臺服務(Forground Service) 【問題】:我們都知道服務是運行在後臺的,如果系統出現記憶體不足的情況,那麼此時,系統就可能回收後代的服務,那麼我們如何保證服務可以一直運行? 【解決】:在服務中,有一個前臺服務的概念,調用startForg ...
  • 廢話不多說,堅持自己一貫的風格,儘量把代碼寫的最簡單。一上效果圖,二上代碼,註釋都在代碼中。 效果圖是個美女,莫怪,代碼寫著寫著總會意淫一下,,, 一、引入相關包 二、整體佈局 這裡佈局就只有一個RecyclerView。 三、item佈局 這裡也是只有一個TextView。 四、封裝Adapter ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...