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

原文地址:https://www.cnblogs.com/lxlx1798/p/11482802.html