此文章只是个人理解,比较简单通俗,适合不太了解这类模式的童鞋。
如果我有一家早餐店,我卖油条和豆浆。这是我的两个产品。(油条配豆浆更搭哦)
我卖的油条和豆浆是给顾客吃的,所以油条和豆浆是产品。因为我的早餐店能提供这两个产品,所以我的店就是工厂,抽象产品就是早餐,具体产品就是油条和豆浆。
简单工厂
顾名思义,简单工厂就很简单,我的店是工厂,顾客到我店里说我要吃油条或者豆浆,只需要跟服务员说一声,就可以吃上早餐了。这个生产油条或者豆浆的过程全是在我的早餐店的后厨发生的。顾客不需要看到这个过程,只需要点餐即可。
我的早餐店,只卖卖油条和豆浆
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
以上是基于本人的理解,用最通俗的话写出来。如果有大佬发现错误,请指出一起交流。
网友评论