iOS設計模式之工廠模式


一,什么是工廠模式

  • 模式定義:
    “專門定義一個類來負責創建其他類的實例,被創建的實例通常具有共同的父類。”
    世界上就是由一個工廠類,根據傳入的參數,動態地決定創建出哪一個產品類的實例。
  • 需求場景:
    簡單工廠的生活場景,賣水果的小販,他給你提供蘋果,橘子等水果,小販就是一個工廠,他為你提供蘋果,橘子等水果

二,適配器的結構圖

  • 實現過程  
    • 創建工廠類,及定義產品類型
    • 創建工廠協議,規范接口實現
    • 創建基類,實現接口協議,便於子類繼承重寫
    • 創建子類,並重寫協議的實現
    • 在工廠中,根據輸入類型,用父類指針執行子類的實現對象,返回目標類。
    • 在目標類,輸入類型,調用對象,完成具體子類對協議方法實現的調用。  
  • 結構圖

 

 

 

 

 

 

 

 

 

 

 

 

 

 

三,代碼示例

  • DeviceCreator(工廠類)
    • DeviceCreator.h
      #import <Foundation/Foundation.h>
      #import "DeviceProtocol.h"
      #import "iPhoneDevice.h"
      #import "AndroidDevice.h"
      #import "WindowsDevice.h"
      
      typedef enum : NSUInteger {
          
          kAndroid,
          kiPhone,
          kWindows,
          
      } DeviceType;
      
      @interface DeviceCreator : NSObject
      
      /**
       *  根據標簽創建手機
       *
       *  @param deviceType 手機標簽
       *
       *  @return 對應的手機
       */
      + (BaseDevice *)deviceCreatorWithDeviceType:(DeviceType)deviceType;
      
      @end
    • DeviceCreator.m  
      #import "DeviceCreator.h"
      #import "BaseDevice.h"
      
      @implementation DeviceCreator
      
      + (BaseDevice *)deviceCreatorWithDeviceType:(DeviceType)deviceType {
      
          if (deviceType == kiPhone) {
              
              return [iPhoneDevice new];
              
          } else if (deviceType == kAndroid) {
          
              return [AndroidDevice new];
              
          } else if (deviceType == kWindows) {
          
              return [WindowsDevice new];
              
          } else {
          
              return [BaseDevice new];
          }
      }
      
      @end
    • DeviceProtocol.h
      #import <Foundation/Foundation.h>
      
      @protocol DeviceProtocol <NSObject>
      
      /**
       *  打電話
       */
      - (void)phoneCall;
      
      /**
       *  系統信息
       *
       *  @return 返回系統描述信息
       */
      - (NSString *)systemInfomation;
      
      @end
  • BaseDevice(產品基類)
    • BaseDevice.h
      #import <Foundation/Foundation.h>
      #import "DeviceProtocol.h"
      
      @interface BaseDevice : NSObject <DeviceProtocol>
      
      @end
    • BaseDevice.m
      #import "BaseDevice.h"
      
      @implementation BaseDevice
      
      - (void)phoneCall {
          NSLog(@"... BaseDevice ...");
      }
      
      - (NSString *)systemInfomation {
          return @"BaseDevice";
      }
      
      @end
  • (Devices)產品類
    • iPhoneDevice
      • iPhoneDevice.h
        #import "BaseDevice.h"
        @interface iPhoneDevice : BaseDevice
        @end
      • iPhoneDevice.m
        #import "iPhoneDevice.h"
        @implementation iPhoneDevice
        - (void)phoneCall {
            NSLog(@"... iPhone ...");
        }
        
        - (NSString *)systemInfomation {
            return @"iPhone";
        }
        
        @end
    • AndroidDevice
      • AndroidDevice.h
        #import "BaseDevice.h"
        @interface AndroidDevice : BaseDevice
        @end
      • AndroidDevice.m
        #import "AndroidDevice.h"
        @implementation AndroidDevice
        - (void)phoneCall {
            NSLog(@"... Android ...");
        }
        - (NSString *)systemInfomation {   
            return @"Android";
        }
        @end
    • WindowsDevice
      • WindowsDevice.h
        #import "BaseDevice.h"
        @interface WindowsDevice : BaseDevice
        @end
      • WindowsDevice.m
        #import "WindowsDevice.h"
        @implementation WindowsDevice
        - (void)phoneCall {   
            NSLog(@"... Windows ...");
        }
        - (NSString *)systemInfomation {   
            return @"Windows";
        }
        @end
  • ViewController
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        BaseDevice *iPhone = [DeviceCreator deviceCreatorWithDeviceType:kiPhone];
        [iPhone phoneCall];
        NSLog(@"%@", [iPhone systemInfomation]);
        
        BaseDevice *android = [DeviceCreator deviceCreatorWithDeviceType:kAndroid];
        [android phoneCall];
        NSLog(@"%@", [android systemInfomation]);
        
        BaseDevice *windows = [DeviceCreator deviceCreatorWithDeviceType:kWindows];
        [windows phoneCall];
        NSLog(@"%@", [windows systemInfomation]);
    }
  • 打印結果:
    2019-09-07 19:52:38.880148+0800 FactoryPattern[17028:6661564] ... IOSDevice ...
    2019-09-07 19:52:38.880303+0800 FactoryPattern[17028:6661564] IOSDevice
    2019-09-07 19:52:38.880424+0800 FactoryPattern[17028:6661564] ... AndriodDevice ...
    2019-09-07 19:52:38.880518+0800 FactoryPattern[17028:6661564] AndriodDevice
    2019-09-07 19:52:38.880611+0800 FactoryPattern[17028:6661564] ... WXDevice ...
    2019-09-07 19:52:38.880690+0800 FactoryPattern[17028:6661564] WXDevice

四,優缺點

  從上面的介紹可以看出,簡單工廠模式的

  • 優點
    客戶端可以直接消費產品,而不必關心具體產品的實現,消除了客戶端直接創建產品對象的責任,實現了對責任的分割。
    簡單點說就是客戶端調用簡單明了,不需要關注太多的邏輯。
  • 缺點
    工廠類集中了所有產品的創建邏輯,一旦不能正常工作,整個系統都會受到影響,而且當產品類別多結構復雜的時候,把所有創建工作放進一個工廠來,會使后期程序的擴展較為困難。產品類本身是符合開閉原則的,對擴展開放對修改關閉,但是工廠類卻違反了開閉原則,因為每增加一個產品,工廠類都需要進行邏輯修改和判斷,導致耦合度太高。例如增加一個BananaFruit,在工廠類FruitFactory就要新增加一個枚舉FruitTypeBanana。
  • 開閉原則
    一個軟件實體(如類、模塊、函數)應當對擴展開放,對修改關閉。
    開放-封閉原則的思想就是設計的時候,盡量讓設計的類做好后就不再修改,如果有新的需求,通過新加類的方式來滿足,而不去修改現有的類(代碼)。

 五,demo
  工廠模式


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM