iOS 简单工厂模式

更新:2017.05.24

一、基础(多态)

1.什么是多态

  • 本质是父类指针指向子类指针;
  • 面向对象三大特性之一;
  • 同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果;

2.OC中的多态

这里举一个例子来介绍一下OC中的多态:使用一个父类Animal,动态新建相应的子类Dog、Cat和Sheep


创建一个Animal类

---------- AnimalModel.h ----------
#import <Foundation/Foundation.h>

typedef NS_ENUM(NSInteger, AnimalType) {
    AnimalTypeDog,//狗
    AnimalTypeCat,//猫
    AnimalTypeSheep,//羊
};

@interface AnimalModel : NSObject

//构造器 类初始化(根据不同的枚举类型初始化不同的动物)
+ (AnimalModel *)initWithType:(AnimalType)type;

//动物叫
- (void)shout;

@end

---------- AnimalModel.m ----------
#import "AnimalModel.h"
#import "DogModel.h"
#import "CatModel.h"
#import "SheepModel.h"

@implementation AnimalModel

+ (AnimalModel *)initWithType:(AnimalType)type {
    AnimalModel *model = nil;
    if (type == AnimalTypeDog) {//狗
        model = [[DogModel alloc] init];
    } else if (type == AnimalTypeCat) {
        model = [[CatModel alloc] init];
    } else if (type == AnimalTypeSheep) {
        model = [[SheepModel alloc] init];
    }
    return model;
}

- (void)shout {
    NSLog(@"动物叫");
}

@end

新建Dog类,继承自Animal

---------- DogModel.h ----------
#import "AnimalModel.h"

@interface DogModel : AnimalModel

@end

---------- DogModel.m ----------
#import "DogModel.h"

@implementation DogModel

- (void)shout {
    NSLog(@"汪");
}

@end

新建Cat类,继承自Animal

---------- CatModel.h ----------
#import "AnimalModel.h"

@interface CatModel : AnimalModel

@end

---------- CatModel.m ----------
#import "CatModel.h"

@implementation CatModel

- (void)shout {
    NSLog(@"喵");
}

@end

新建Sheep类,继承自Animal

---------- SheepModel.h ----------
#import "AnimalModel.h"

@interface SheepModel : AnimalModel

@end

---------- SheepModel.m ----------
#import "SheepModel.h"

@implementation SheepModel

- (void)shout {
    NSLog(@"咩");
}

@end

在ViewController中进行使用

#import "ViewController.h"
#import "AnimalModel.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    AnimalModel *dog = [AnimalModel initWithType:AnimalTypeDog];
    [dog shout];
    AnimalModel *cat = [AnimalModel initWithType:AnimalTypeCat];
    [cat shout];
    AnimalModel *sheep = [AnimalModel initWithType:AnimalTypeSheep];
    [sheep shout];
}

@end

得到的打印值为

2017-05-24 16:35:18.333 Demo_GaoQiang[8211:3992590] 汪
2017-05-24 16:35:18.334 Demo_GaoQiang[8211:3992590] 喵
2017-05-24 16:35:18.334 Demo_GaoQiang[8211:3992590] 咩

结论
ViewController中并没有import Dog、Cat或者Sheep(抽象子类),它们本身的对象是通过它们的父类Animal(抽象类)初始化完成,在程序运行时才会确定对象的实际类型。 在父类(抽象类)指针指向不同的对象的时候,通过父类指针调用被重写的方法,会执行该指针所指向的那个对象(抽象子类)的方法。这就是OC中的多态。

二、简单工厂介绍

1.多态和简单工厂方法的关系

第一节介绍了多态,因为简单工厂模式本质上就是基于多态的实现:简单工厂实际上就是在抽象类和抽象子类的两者关系中加入了一个第三者——工厂类Factory,这个Factory将原本在抽象类(父类)中的接口、构造器方法写在了自己内部,从而将抽象类和抽象子类之间的耦合度降低,在需求的更改后,只需要对工厂类进行修改就可以。

2.实现条件

  • 存在继承关系
  • 运用多态的特性

3.优点

  • 比较适合一些简单的、Model中存在大量继承情况的项目
  • 在一定程度上优化了代码,提高了代码的复用性
  • 将大量的操作放到工厂类中去处理,业务类中只负责创建需要的对象,降低了对象初始化和业务类之间逻辑的耦合

4.缺点

  • 必须基于继承关系
  • 工厂类中集中了大量的创建逻辑,但是当所有的子类(抽象子类)不是继承自同一个父类(抽象类)时,它的扩展比较困难

三、简单工厂模式的实现

基于第一节的代码,将AnimalModel中的构造器方法取出,放入新建的工厂类AnimalFactory中(这里只展示有修改的代码,没有修改的代码和原来一样)

---------- AnimalModel.h ----------
#import <Foundation/Foundation.h>

@interface AnimalModel : NSObject

//动物叫
- (void)shout;

@end

---------- AnimalModel.m ----------
#import "AnimalModel.h"

@implementation AnimalModel

- (void)shout {
    NSLog(@"动物叫");
}

@end

新建一个AnimalFactory类

---------- AnimalFactory.h ----------
#import <Foundation/Foundation.h>
@class AnimalModel;

typedef NS_ENUM(NSInteger, AnimalType) {
    AnimalTypeDog,//狗
    AnimalTypeCat,//猫
    AnimalTypeSheep,//羊
};

@interface AnimalFactory : NSObject

//构造器 类初始化(根据不同的枚举类型初始化不同的动物)
+ (AnimalModel *)initWithType:(AnimalType)type;

@end

---------- AnimalFactory.m ----------
#import "AnimalFactory.h"
#import "AnimalModel.h"
#import "DogModel.h"
#import "CatModel.h"
#import "SheepModel.h"

@implementation AnimalFactory

+ (AnimalModel *)initWithType:(AnimalType)type {
    AnimalModel *model = nil;
    if (type == AnimalTypeDog) {//狗
        model = [[DogModel alloc] init];
    } else if (type == AnimalTypeCat) {
        model = [[CatModel alloc] init];
    } else if (type == AnimalTypeSheep) {
        model = [[SheepModel alloc] init];
    }
    return model;
}

@end

在ViewController中进行使用

#import "ViewController.h"
#import "AnimalModel.h"
#import "AnimalFactory.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    AnimalModel *dog = [AnimalFactory initWithType:AnimalTypeDog];
    [dog shout];
    AnimalModel *cat = [AnimalFactory initWithType:AnimalTypeCat];
    [cat shout];
    AnimalModel *sheep = [AnimalFactory initWithType:AnimalTypeSheep];
    [sheep shout];
}

@end

得到的打印值为

2017-05-24 17:17:34.646 Demo_GaoQiang[8337:4159039] 汪
2017-05-24 17:17:34.646 Demo_GaoQiang[8337:4159039] 喵
2017-05-24 17:17:34.646 Demo_GaoQiang[8337:4159039] 咩

结论
注意对比简单工厂模式的实现和多态的实现,两者的区别其实仅仅只是一个工厂类Factory而已

以上就是简单工厂模式,想到其他的再更新吧,有什么理解不对的或者写错的地方,欢迎大家指出,我将在第一时间更新

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,033评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,725评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,473评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,846评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,848评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,691评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,053评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,700评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,856评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,676评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,787评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,430评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,034评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,990评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,218评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,174评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,526评论 2 343

推荐阅读更多精彩内容