Cowboy Tech

iOS设计模式-工厂

工厂

工厂

  1. 制造产品
  2. 将制造工艺进行了封装

客户

  1. 不参与手机制造流程
  2. 客户需要使用固定的产品(客户提出需求)

简单工厂使用场景

  1. 简化生产流程
  2. 隔离生产产品的细节
  3. 不同类型的产品之间有着一些共同的功能
  4. 一个具体的工厂,工厂自身就是一个具体的对象,是实体类,不是抽象类,是个便利构造器

产品协议规范同一接口

PhoneProtocol

@protocol PhoneProtocol <NSObject>

- (void)phoneCall;

- (void)sendMessage;

产品基类

BaseDevie

@interface BaseDevie : NSObject <PhoneProtocol>

- (void)phoneCall {
}

- (void)sendMessage {
}

具体产品

AndroidDevice

@interface AndroidDevice : BaseDevie

- (void)phoneCall {
NSLog(@"Android phoneCall");
}

- (void)sendMessage {   
NSLog(@"Android sendMessage");
}

//特有功能,需要写在.h文件里
- (void)customTheme {
NSLog(@"Android customTheme");
}

iPhoneDevice

@interface iPhoneDevice : BaseDevie

- (void)phoneCall {
NSLog(@"iPhone phoneCall");
}

- (void)sendMessage {   
NSLog(@"iPhone sendMessage");
}

//特有功能,需要写在.h文件里
- (void)fingerprintIndetification {
NSLog(@"iPhone fingerprintIndetification");
}

NokiaDevice

@interface NokiaDevice : BaseDevie

- (void)phoneCall { 
NSLog(@"Nokia phoneCall");
}

- (void)sendMessage {
NSLog(@"Nokia sendMessage");
}

//特有功能,需要写在.h文件里
- (void)knockWalnut {
NSLog(@"Nokia knockWalnut");
}

工厂

DeviceFactory

typedef enum : NSUInteger {
kiPhone   = 0x11,
kAndroid,
kNokia,

} EDevieType;

//根据用户提交的指令创建出具体的手机
+ (BaseDevie <PhoneProtocol> *)deviceFactoryWithDevieType:(EDevieType)type {

BaseDevie <PhoneProtocol> *device = nil;  

if (type == kiPhone) { 

    device = [[iPhoneDevice alloc] init];

}  else if (type == kAndroid) {

    device = [[AndroidDevice alloc] init];

}  else if (type == kNokia) {

    device = [[NokiaDevice alloc] init];

}

return device;
}

工厂的使用

ViewController

- (void)viewDidLoad {
[super viewDidLoad];

// 工厂中创建出具体产品,如果仅仅是使用通用的功能sendMsg,phoneCall,类型为BaseDevice也可以

iPhoneDevice *iPhone = (iPhoneDevice *)[DeviceFactory deviceFactoryWithDevieType:kiPhone];

// 使用产品的功能
[iPhone fingerprintIndetification];
}

抽象工厂

  1. 工厂是抽象类,需要实例化子类
  2. 抽象工厂使用比简单工厂更加灵活,因为可以动态的切换工厂

产品 Phone

Phone基类

@interface BasePhone : NSObject

@end

Phone子类之Android

@interface Android : BasePhone

@end

Phone子类之iPhone

@interface iPhone : BasePhone

@end

产品 Watch

Whatch产品基类

@interface BaseWatch : NSObject

@end

Whatch产品子类之iWatch

@interface iWatch : BaseWatch

@end

Whatch产品子类之AndroidWatch

@interface AndroidWatch : BaseWatch

@end

工厂

工厂基类

@implementation BaseFactory

- (BasePhone *)createPhone {

return nil;
}

- (BaseWatch *)createWatch {

return nil;
}

工厂子类Apple

@interface AppleFactory : BaseFactory

- (BasePhone *)createPhone {

return [[iPhone alloc] init];
}

- (BaseWatch *)createWatch {

return [[iWatch alloc] init];
}

工厂子类Google

@interface GoogleFactory : BaseFactory

- (BasePhone *)createPhone {

return [[Android alloc] init];
}

- (BaseWatch *)createWatch {

return [[AndroidWatch alloc] init];
}

创建具体工厂

FactoryManager

typedef enum : NSUInteger {

kApple   = 0x11,
kGoogle,

} EFactoryType;

@interface FactoryManager : NSObject

+ (BaseFactory *)factoryWithBrand:(EFactoryType)factoryType {

BaseFactory *factory = nil;

if (factoryType == kApple) {

    factory = [[AppleFactory alloc] init];

} else if (factoryType == kGoogle) {

    factory = [[GoogleFactory alloc] init];
}

return factory;
}

工厂的使用

- (void)viewDidLoad {
[super viewDidLoad];

// 获取工厂
BaseFactory *factory = [FactoryManager factoryWithBrand:kGoogle];

// 创建商品
BasePhone *phone = [factory createPhone];
BaseWatch *watch = [factory createWatch];

NSLog(@"%@ %@", phone, watch);
}

框架级别的工厂类:NSNumber

因为NSNumber是抽象类,所以以下代码结果为null,NSNumber是一个抽象类,其父类NSValue也是

NSLog(@"%@", [[NSNumber alloc] init]);

根据客户需求,制造出相关工厂

NSNumber *number     = [NSNumber numberWithInt:100];
NSNumber *floatValue = [NSNumber numberWithFloat:100.f];

以下结果都为d,产品可以互相转换,因为NSNumber只处理数值型的数据.这是和普通抽象工厂不同的地方

NSLog(@"%c", [number charValue]);
NSLog(@"%c", [floatValue charValue]);

枚举类型的定义

使用枚举定义手机的类型,注意起名字时,用大写的E+名字 = EDevieType

typedef enum : NSUInteger {
kiPhone   = 0x11,
kAndroid,
kNokia,

} EDevieType;