一,什么是工厂模式

  • 模式定义:
“专门定义一个类来负责创建其他类的实例,被创建的实例通常具有共同的父类。”
世界上就是由一个工厂类,根据传入的参数,动态地决定创建出哪一个产品类的实例。
  • 需求场景:
简单工厂的生活场景,卖水果的小贩,他给你提供苹果,橘子等水果,小贩就是一个工厂,他为你提供苹果,橘子等水果

二,适配器的结构图

  • 实现过程  
  • 创建工厂类,及定义产品类型
  • 创建工厂协议,规范接口实现
  • 创建基类,实现接口协议,便于子类继承重写
  • 创建子类,并重写协议的实现
  • 在工厂中,根据输入类型,用父类指针执行子类的实现对象,返回目标类。
  • 在目标类,输入类型,调用对象,完成具体子类对协议方法实现的调用。  
  • 结构图

 

 

 

 

 

 

 

 

 

 

 

 

 

三,代码示例

  • 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
  工厂模式