工厂模式

Objective-C编程之道 iOS设计模式解析
iOS设计模式解析-工厂模式
iOS设计模式解析-抽象工厂模式
iOS设计模式解析-外观模式
iOS设计模式解析-中介者模式
iOS设计模式解析-观察者模式
iOS设计模式解析-装饰模式
iOS设计模式解析-责任链模式
iOS设计模式解析-模板方法
iOS设计模式解析-策略模式
iOS设计模式解析-享元模式
iOS设计模式解析-代码地址

何为工厂方法模式

工厂方法也称为虚构造器,它适用于这种情况:一个类无法预期需要生产哪个类的对象,想让其子类来指定所生成的对象。

工厂方法模式:定义创建对象的接口,让子类决定实例化哪一个类,工厂方法使得一个类的实例化延迟到其子类。

何时使用工厂方法

在以下情形,自然会考虑使用这一模式。

  • 编译时无法准确预期要创建的对象的类。
  • 类想让其子类决定在运行时创建什么。
  • 类有若干辅助类为其子类,而你想将返回哪个子类这一信息局部化。

画布的实例:

最上层的CanvasView定义了任意CanvasView类型的默认行为,其子类用不同图像在屏幕上展现各种纹理并展现其他可能的特定行为,PaperCanvasViewClothCanvasView的代码段如下

PaperCanvasView
#import "CanvasView.h"

@interface PaperCanvasView : CanvasView

@end
#import "PaperCanvasView.h"

@implementation PaperCanvasView

- (id)initWithFrame:(CGRect)frame
{
    if(self = [super initWithFrame:frame]){
        UIImage *backgroundImage = [UIImage imageNamed:@"paper"];
        UIImageView *backgroundView = [[UIImageView alloc]initWithImage:backgroundImage];
        [self addSubview:backgroundView];
        NSLog(@"paper");
    }
    return self;
}

@end

注意:@"paper"是纸纹理的图像的名字,它被赋给 UIImageView 的实例 backgroundView 然后 backgroundView 作为子视图添加到主内容视图,以显示纸的图像

ClothCanvasView
#import "CanvasView.h"

@interface ClothCanvasView : CanvasView

@end
#import "ClothCanvasView.h"

@implementation ClothCanvasView

- (id)initWithFrame:(CGRect)frame
{
    if(self = [super initWithFrame:frame]){
        UIImage *backgroundImage = [UIImage imageNamed:@"cloth"];
        UIImageView *backgroundView = [[UIImageView alloc]initWithImage:backgroundImage];
        [self addSubview:backgroundView];
        NSLog(@"cloth");
    }
    return self;
}
@end

PaperCanvasViewClothCanvasView的实现非常易懂,它们继承了CanvasView类中定义的默认行为,现在我们定义好了产品,还需要为它们各自定义一个生成器。

画布生成器

CanvasViewGenerator
#import 
#import "CanvasView.h"

@interface CanvasViewGenerator : NSObject

- (CanvasView *)canvasViewWithFrame:(CGRect)aFrame;

@end
#import "CanvasViewGenerator.h"

@implementation CanvasViewGenerator

- (CanvasView *)canvasViewWithFrame:(CGRect)aFrame
{
    return [[CanvasView alloc]initWithFrame:aFrame];
}

@end

注意:CanvasViewGenerator有一个方法canvasViewWithFrame:(CGRect)aFrame,这个方法的默认实现只是创建并返回无图案的CanvasView,这个生成器的子类需要重载这个方法,返回CanvasView的实际具体类型

PaperCanvasViewGenerator
#import "CanvasViewGenerator.h"
#import "PaperCanvasView.h"

@interface PaperCanvasViewGenerator : CanvasViewGenerator

- (CanvasView *)canvasViewWithFrame:(CGRect)aFrame;

@end
#import "PaperCanvasViewGenerator.h"

@implementation PaperCanvasViewGenerator

- (CanvasView *)canvasViewWithFrame:(CGRect)aFrame
{
    return [[PaperCanvasView alloc]initWithFrame:aFrame];
}

@end

PaperCanvasViewGenerator重载canvasViewWithFrame:方法,返回PaperCanvasView的实例。

ClothCanvasViewGenerator
#import "CanvasViewGenerator.h"
#import "ClothCanvasView.h"

@interface ClothCanvasViewGenerator : CanvasViewGenerator

- (CanvasView *)canvasViewWithFrame:(CGRect)aFrame;

@end
#import "ClothCanvasViewGenerator.h"

@implementation ClothCanvasViewGenerator

- (CanvasView *)canvasViewWithFrame:(CGRect)aFrame
{
    return [[ClothCanvasView alloc]initWithFrame:aFrame];
}
@end

使用画布

ViewController现在使用原来的CanvasView。为了在运行时加以改变,需要在调用的时候添加一个方法,通过CanvasViewGenerator取得CanvasView的实例

注意:CanvasViewGenerator defaultGenerator = [[PaperCanvasViewGenerator alloc]init]
此时编译时
defaultGeneratorCanvasViewGenerator类型,运行时的类型由真正初始化的对象(PaperCanvasViewGenerator)*决定

- (void)viewDidLoad {
    [super viewDidLoad];
    CanvasViewGenerator *defaultGenerator = [[CanvasViewGenerator alloc]init];
    [self loadCanvasViewWithGenerator:defaultGenerator];
    
}

- (void)loadCanvasViewWithGenerator:(CanvasViewGenerator *)generator
{
    [self.canvasView removeFromSuperview];//移除
    CGRect aFrame = CGRectMake(0, 0, 320, 436);
    CanvasView *aCanvasView = [generator canvasViewWithFrame:aFrame];
    self.canvasView = aCanvasView;
    [self.view addSubview:self.canvasView];
}

因此,以后用户选择特定的画布类型时,应用程序会把具体生成器的实例传给loadCanvasViewWithGenerator:方法,原来的画布将被新画布所替换。

//PaperCanvasViewGenerator生成器
CanvasViewGenerator *defaultGenerator = [[PaperCanvasViewGenerator alloc]init];
//ClothCanvasViewGenerator生成器
CanvasViewGenerator *defaultGenerator = [[ClothCanvasViewGenerator alloc]init];

你可能感兴趣的:(工厂模式)