iOS 简单工厂,工厂模式,抽象工厂的通俗理解

此文章只是个人理解,比较简单通俗,适合不太了解这类模式的童鞋。
如果我有一家早餐店,我卖油条和豆浆。这是我的两个产品。(油条配豆浆更搭哦)
我卖的油条和豆浆是给顾客吃的,所以油条和豆浆是产品。因为我的早餐店能提供这两个产品,所以我的店就是工厂,抽象产品就是早餐,具体产品就是油条和豆浆。

简单工厂

顾名思义,简单工厂就很简单,我的店是工厂,顾客到我店里说我要吃油条或者豆浆,只需要跟服务员说一声,就可以吃上早餐了。这个生产油条或者豆浆的过程全是在我的早餐店的后厨发生的。顾客不需要看到这个过程,只需要点餐即可。

我的早餐店,只卖卖油条和豆浆
SFactory.h
#import "SOperation.h"
typedef enum : NSUInteger {
 SFactoryProductTypeYoutiao,
 SFactoryProductTypeDoujiang,
} SFactoryProductType;
@interface SFactory : NSObject
+ (SOperation *)operationWithType:(SFactoryProductType)type;
@end
厨师们按顾客点的餐在后厨做早餐
SFactory.m
#import "SFactory.h"
#import "SOperationYoutiao.h"
#import "SOperationDoujiang.h"
@implementation SFactory
+ (SOperation *)operationWithType:(SFactoryProductType)type{
 switch (type) {
     case SFactoryProductTypeYoutiao:
         return [[SOperationYoutiao alloc] init];
         break;
     case SFactoryProductTypeDoujiang:
         return [[SOperationDoujiang alloc] init];
         break;
         
     default:
         break;
 }
}
@end
顾客们吃的早餐是啥子
SOperation.h
@interface SOperation : NSObject
- (void)getProductName;
@end
SOperation.m
#import "SOperation.h"
@implementation SOperation
- (void)getProductName{
 
}
@end
下面是油条的产品类,告诉顾客吃的是油条,豆浆就不列出了,毕竟独家秘方。
SOperationYoutiao.h
#import "SOperationYoutiao.h"
@implementation SOperationYoutiao
- (void)getProductName{
   NSLog(@"__%s__",__FUNCTION__);
}
@end
 //简单工厂
 SOperation *soperationYoutiao = [SFactory operationWithType:SFactoryProductTypeYoutiao];
 [soperationYoutiao getProductName];
 SOperation *soperationDoujiang = [SFactory operationWithType:SFactoryProductTypeDoujiang];
 [soperationDoujiang getProductName];

通过代码可知,只需要告诉工厂,我想要xx产品,就可以得到具体产品,而内部实现过程没有暴露出来。

优缺点:
1.也是所有工厂模式的优点(下面就不在提了),客户只需要通过工厂类给出的接口请求产品即可,并不需要知道实现细节。
2.所有的产品实现细节都在一个工厂类中,如果产品较多,逻辑复杂,可拓展性较低。

工厂模式

由于我的早餐店味道可口,价格公道,物美价廉,所以整个市的人都来我的店吃早餐,而且他们抗议不能只有油条,豆浆,还要有粽子,油饼,包子,小米粥等等等。
我是良心卖家,同意了他们的请求,但是我的早餐店的后厨有点小。百十号人在里面乱跑。身为管理者,我看不下去。于是给他们分了分组。分别给他们一个屋子,生产相应的早餐。有做包子的,做油条的,做豆浆的,做粽子的等等。哪个早餐出问题了,就去找谁训话,井井有条。这一个个屋子就相当于一个个具体工厂,我的早餐店是抽象工厂,这样顾客仍然不知道他们吃的早餐是如何做出来的。
这种模式下,我的早餐店是抽象工厂,我的每个屋子(可能不太恰当)是具体工厂,我卖的早餐是抽象产品,我的油条和豆浆具体产品。
下面看下代码

我的早餐店
FFactory.h
#import "FOperation.h"
@interface FFactory : NSObject
- (FOperation *)createOperation;
@end
FFactory.m
@implementation FFactory
- (FOperation *)createOperation{
    return nil;
}
@end
生产油条的小屋子
FFactoryYoutiao.h
#import "FFactory.h"
@interface FFactoryYoutiao : FFactory
@end
生产油条的屋子只能生产油条(具体工厂实现抽象工厂定义的方法)
FFactoryYoutiao.m
#import "FFactoryYoutiao.h"
#import "FOperationYoutiao.h"
@implementation FFactoryYoutiao
- (FOperation *)createOperation{
    return [[FOperationYoutiao alloc] init];
}
@end

上面是油条的工厂类,只能生产油条,豆浆就不列出了,毕竟独家秘方。

这俩工厂生产的油条和豆浆都是我的早餐店生产出来的。因为我是个负责人的良心卖家,所以不论我内部整改前后,生产的产品都是一样的。所以产品类代码不列出了。

    //工厂模式
    FFactory *ffactoryYoutiao = [[FFactoryYoutiao alloc] init];
    FOperation *foperationYoutiao = [ffactoryYoutiao createOperation];
    [foperationYoutiao getProductName];
    FFactory *ffactoryDoujiang = [[FFactoryDoujiang alloc] init];
    FOperation *foperationDoujiang = [ffactoryDoujiang createOperation];
    [foperationDoujiang getProductName];

优缺点:
1.通过继承,将"共性"抽离出来,拓展性强,减少内部逻辑逻辑的复杂度。(这里我店里的油条和豆浆都属于早餐)。
2.可以通过各个子工厂进行"个性"调整。
3.想多生产一个产品,就需要多建一个工厂。

抽象工厂模式

后来,全市的老少爷们都来我店里吃,但是众口难调啊,他们又抗议,为了发扬节俭的传统美德,有的人想吃大个的,大碗的,有的想吃小个的,小碗的。我作为负责任的企业家,满足他们。我把我店里的产品升级下。现在有四个产品,大油条,小油条,大碗豆浆,小碗豆浆。为此我店里有了大屋子,和小屋子2个屋子,为啥这样,因为节约成本,不然我得用4个屋子。

这种模式下,我的早餐店是抽象工厂,我的每个屋子是具体工厂,我卖的早餐是抽象产品,我的大油条,小油条,大碗豆浆和小碗豆浆是具体产品。
下面看代码

AFactory.h
#import "AOperationYoutiao.h"
#import "AOperationDoujiang.h"
@interface AFactory : NSObject
- (AOperationYoutiao *)getYoutiao;
- (AOperationDoujiang *)getDoujiang;
@end
AFactory.m
#import "AFactory.h"
@implementation AFactory
- (AOperationYoutiao *)getYoutiao{
    return nil;
}
- (AOperationDoujiang *)getDoujiang{
    return nil;
}
@end
我的大屋子,它生产大油条和大碗豆浆
AFactoryBig.h
#import "AFactory.h"
@interface AFactoryBig : AFactory
@end
AFactoryBig.m
#import "AFactoryBig.h"
#import "AOperationBigYoutiao.h"
#import "AOperationBigDoujiang.h"
@implementation AFactoryBig
- (AOperationBigYoutiao *)getYoutiao{
    return [[AOperationBigYoutiao alloc] init];
}
- (AOperationBigDoujiang *)getDoujiang{
    return [[AOperationBigDoujiang alloc] init];
}
@end
我的小屋子,它生产小油条和小碗豆浆
AFactory.h
#import "AFactory.h"
@interface AFactorySmall : AFactory
@end
AFactorySmall.h
#import "AFactorySmall.h"
#import "AOperationSmallYoutiao.h"
#import "AOperationSmallDoujiang.h"
@implementation AFactorySmall
- (AOperationYoutiao *)getYoutiao{
    return [[AOperationSmallYoutiao alloc] init];
}
- (AOperationDoujiang *)getDoujiang{
    return [[AOperationSmallDoujiang alloc] init];
}
@end
AOperationYoutiao.h
#import "AOperationYoutiao.h"
@interface AOperationYoutiao : NSObject
- (void)getProductName;
@end
AOperationYoutiao.m
#import "AOperationYoutiao.h"
@implementation AOperationYoutiao
- (void)getProductName{
    
}
@end
这是生产的大油条
#import "AOperationYoutiao.h"
@interface AOperationBigYoutiao : AOperationYoutiao
@end
AOperationBigYoutiao
#import "AOperationBigYoutiao.h"
@implementation AOperationBigYoutiao
- (void)getProductName{
    NSLog(@"__%s__",__FUNCTION__);
}
@end
AOperationSmallYoutiao.h
#import "AOperationYoutiao.h"
@interface AOperationSmallYoutiao : AOperationYoutiao
@end
这是生产的小油条
#import "AOperationSmallYoutiao.h"
@implementation AOperationSmallYoutiao
- (void)getProductName{
    NSLog(@"__%s__",__FUNCTION__);
}
@end
//抽象工厂模式
    AFactory *afactoryBig = [[AFactoryBig alloc] init];
    AOperationYoutiao *aoperationYoutiao = [afactoryBig getYoutiao];
    AOperationDoujiang *aoperationDoujiang = [afactoryBig getDoujiang];
    [aoperationYoutiao getProductName];
    [aoperationDoujiang getProductName];
    
    //AFactory *afactorySmall = [[AFactorySmall alloc] init];
    //AOperationYoutiao *aoperationYoutiao = [afactorySmall getYoutiao];
    //AOperationDoujiang *aoperationDoujiang = [afactorySmall getDoujiang];
    //[aoperationYoutiao getProductName];
    //[aoperationDoujiang getProductName];

现在我的早餐店能提供4种产品了,由于我的这次内部整改,只需要用到两个屋子,假如不整改,就会用到4个屋子。如果产品再多,我需要的屋子就会需要的更多。
首先解释下族和产品等级:


temp.jpg

我的店里有两种产品油条和豆浆,它们是一个产品族,可以理解为一个套餐。产品大小就是产品等级。
抽象工厂是指一个工厂等级结构可以创建出分属于不同产品等级结构的一个产品族中的所有对象,抽象工厂与工厂方法的区别也在于此。
工厂方法:具体工厂一般只生产一个或几个对象
抽象工厂:具体工厂生产的是一族对象。

我将上方AFactoryBig替换成AFactorySmall, 就和注释掉的部分一样。生产出来的产品就完全不相同,而客户并不需要做其他操作。
优缺点:
1.显而易见,有非常大的灵活性,切换产品族的时候,只要提供不同的抽象工厂实现就可以了。
2.不太容易扩展新的产品,如果需要给整个产品族添加一个新的产品,那么就需要修改所有的工厂实现类。(比如我要多上一款包子,这所有的工厂类都需要改)。

相关代码链接:https://github.com/CodeGideon/FactoryPattern
以上是基于本人的理解,用最通俗的话写出来。如果有大佬发现错误,请指出一起交流。

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

推荐阅读更多精彩内容