一,什么是工廠模式
- 模式定義:
“專門定義一個類來負責創建其他類的實例,被創建的實例通常具有共同的父類。” 世界上就是由一個工廠類,根據傳入的參數,動態地決定創建出哪一個產品類的實例。
- 需求場景:
簡單工廠的生活場景,賣水果的小販,他給你提供蘋果,橘子等水果,小販就是一個工廠,他為你提供蘋果,橘子等水果
二,適配器的結構圖
- 實現過程
- 創建工廠類,及定義產品類型
- 創建工廠協議,規范接口實現
- 創建基類,實現接口協議,便於子類繼承重寫
- 創建子類,並重寫協議的實現
- 在工廠中,根據輸入類型,用父類指針執行子類的實現對象,返回目標類。
- 在目標類,輸入類型,調用對象,完成具體子類對協議方法實現的調用。
- 結構圖
三,代碼示例
- 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
- DeviceCreator.h
- 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
- BaseDevice.h
- (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
- iPhoneDevice.h
- 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
- AndroidDevice.h
- 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
- WindowsDevice.h
- iPhoneDevice
- 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
工廠模式