一,什么是工厂模式
- 模式定义:
“专门定义一个类来负责创建其他类的实例,被创建的实例通常具有共同的父类。”
世界上就是由一个工厂类,根据传入的参数,动态地决定创建出哪一个产品类的实例。
- 需求场景:
简单工厂的生活场景,卖水果的小贩,他给你提供苹果,橘子等水果,小贩就是一个工厂,他为你提供苹果,橘子等水果
二,适配器的结构图
- 实现过程
- 创建工厂类,及定义产品类型
- 创建工厂协议,规范接口实现
- 创建基类,实现接口协议,便于子类继承重写
- 创建子类,并重写协议的实现
- 在工厂中,根据输入类型,用父类指针执行子类的实现对象,返回目标类。
- 在目标类,输入类型,调用对象,完成具体子类对协议方法实现的调用。
- 结构图
三,代码示例
- 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
工厂模式