首页 > 技术文章 > ios设计模式--抽象工厂

sjzlovecj 2015-08-24 15:42 原文

一、定义


 

抽象工厂:提供一个创建一系列相关或相互依赖对象的接口,而无需指定他们具体的类。

 

在软件设计中,如果客户端想手工创建一个类的对象,那么客户端需要首先知道这个类的细节。一组相关的独享可以在运行时按不同的标准创建的不一样,此时客户端就必须知道全部的细节才能创建它们。这时,就需要用到抽象工厂模式。

抽象工厂提供一个固定的接口,用于创建一系列有关联或相依存的对象,而不必指定其具体类或其创建的细节。客户端与从工厂得到的具体对象直接没有耦合。

 

 二、抽象工厂与工厂方法的不同


 

  抽象工厂 工厂方法
1 通过对象组合创建抽象产品 工厂方法通过类继承创建抽象方法
2 创建多系列产品 创建一种产品
3 必须修改父类的接口才能支持新的产品 子类化创建者并重载工厂方法以创建新产品

抽象工厂模式很有趣的一点是,很多时候它都用工厂方法模式来实现。

也就是说,我们已经在外部生成了相应的产品的类(大多用工厂方法模式),然后我们再在我们的抽象工厂类里面把这些相关联的对象组合在一起。

 

三、优缺点


 

优点:

封装性,每个产品的实现类不是高层模块要关系的,要关心的是什么?是接口,是抽象,它不关心对象是如何创建出来,这由谁负责呢?工厂类,只要知道工厂类是谁,我就能创建出一个需要的对象,省时省力,优秀设计就应该如此。

缺点:

抽象工厂模式的最大缺点就是产品族扩展非常困难,因为当我们增加一种产品时,所有的抽象工厂都要增加该产品,程序需要改动的地方太大来。

 

电脑最重要由主机和显示器这两部分组成。
 首先,我们通过类继承,我们来创建屏幕类和主机类。
屏幕类:(基类)
 1 #import <Foundation/Foundation.h>
 2 
 3 @interface screen : NSObject
 4 
 5 @property (nonatomic, strong) NSString * screenType;
 6 
 7 @end
 8 
 9 
10 #import "screen.h"
11 
12 @implementation screen
13 
14 - (instancetype)init
15 {
16     self = [super init];
17     if(self){
18         self.screenType = @"screen";
19     }
20     
21     return self;
22 }
23 
24 @end

宏基屏幕:

 1 #import <Foundation/Foundation.h>
 2 #import "screen.h"
 3 
 4 @interface acerScreen : screen
 5 
 6 @end
 7 
 8 
 9 #import "acerScreen.h"
10 
11 @implementation acerScreen
12 
13 - (instancetype)init
14 {
15     self = [super init];
16     
17     if(self){
18         self.screenType = @"acerScreen";
19     }
20     
21     return self;
22 }
23 
24 @end

联想屏幕:

 1 #import "screen.h"
 2 
 3 @interface lenovoScreen : screen
 4 
 5 @end
 6 
 7 
 8 
 9 #import "lenovoScreen.h"
10 
11 @implementation lenovoScreen
12 
13 - (instancetype)init
14 {
15     self = [super init];
16     
17     if(self){
18         self.screenType = @"lenovoScreen";
19     }
20     
21     return self;
22 }
23 
24 @end

 

主机基类:

 1 #import <Foundation/Foundation.h>
 2 
 3 @interface host : NSObject
 4 
 5 @property (nonatomic, strong) NSString * hostType;
 6 
 7 @end
 8 
 9 
10 
11 #import "host.h"
12 
13 @implementation host
14 
15 - (instancetype)init
16 {
17     self = [super init];
18     if(self){
19         self.hostType = @"host";
20     }
21     return self;
22 }
23 
24 @end

宏基主机:

 1 #import "host.h"
 2 
 3 @interface acerHost : host
 4 
 5 @end
 6 
 7 
 8 #import "acerHost.h"
 9 
10 @implementation acerHost
11 
12 - (instancetype)init
13 {
14     self = [super init];
15     if(self){
16         self.hostType = @"acerHost";
17     }
18     
19     return self;
20 }
21 
22 @end

联想主机:

 1 #import "host.h"
 2 
 3 @interface lenovoHost : host
 4 
 5 @end
 6 
 7 
 8 #import "lenovoHost.h"
 9 
10 @implementation lenovoHost
11 
12 - (instancetype)init
13 {
14     self = [super init];
15     if(self){
16         self.hostType = @"lenovoHost";
17     }
18     
19     return self;
20 }
21 
22 @end

 

抽象工厂基类:

 1 #import <Foundation/Foundation.h>
 2 #import "screen.h"
 3 #import "host.h"
 4 
 5 @interface factory : NSObject
 6 
 7 - (screen *)createScreen;
 8 - (host *)createHost;
 9 
10 @end
11 
12 
13 #import "factory.h"
14 
15 @implementation factory
16 
17 - (screen *)createScreen
18 {
19     return [[screen alloc] init];
20 }
21 
22 - (host *)createHost
23 {
24     return [[host alloc] init];
25 }
26 
27 @end

宏基工厂:

#import "factory.h"

@interface acerFactory : factory

@end



#import "acerFactory.h"
#import "acerScreen.h"
#import "acerHost.h"

@implementation acerFactory

- (screen *)createScreen
{
    return [[acerScreen alloc] init];
}

- (host *)createHost
{
    return [[acerHost alloc] init];
}

@end

联想工厂:

 1 #import "factory.h"
 2 
 3 @interface lenovoFactory : factory
 4 
 5 @end
 6 
 7 
 8 
 9 #import "lenovoFactory.h"
10 #import "lenovoHost.h"
11 #import "lenovoScreen.h"
12 
13 @implementation lenovoFactory
14 
15 - (screen *)createScreen
16 {
17     return [[lenovoScreen alloc] init];
18 }
19 
20 - (host *)createHost
21 {
22     return [[lenovoHost alloc] init];
23 }
24 
25 @end

用工厂方法模式来生成工厂类:

 1 #import <Foundation/Foundation.h>
 2 #import "factory.h"
 3 
 4 @interface createFactory : NSObject
 5 
 6 - (factory *)createFactory:(NSInteger)num;
 7 
 8 @end
 9 
10 
11 
12 #import "createFactory.h"
13 #import "acerFactory.h"
14 #import "lenovoFactory.h"
15 
16 @implementation createFactory
17 
18 - (factory *)createFactory:(NSInteger)num
19 {
20     if(num == 1){
21         return [[acerFactory alloc] init];
22     }else{
23         return [[lenovoFactory alloc] init];
24     }
25     
26     return nil;
27 }
28 
29 @end

 

调用:

 1         factory * fac = [[[createFactory alloc] init] createFactory:1];
 2         screen * scr = [fac createScreen];
 3         host * hos = [fac createHost];
 4         NSLog(@"%@--%@", scr.screenType, hos.hostType);
 5         
 6         
 7         factory * lenovo = [[[createFactory alloc] init] createFactory:2];
 8         screen * lenovoscr = [lenovo createScreen];
 9         host * lenvoohost = [lenovo createHost];
10         NSLog(@"%@--%@", lenovoscr.screenType, lenvoohost.hostType);    

生成:

 
 当现有的抽象工厂需要支持新产品时,需要向父类添加相应的新工厂方法,这意味着也要修改其子类以支持新产品的新工厂方法。
 
 

推荐阅读