1. 程式人生 > >iOS架構師_工廠模式

iOS架構師_工廠模式

簡單工廠:

例子:
這裡寫圖片描述

模式圖
這裡寫圖片描述

程式碼示例:
這裡寫圖片描述

建立水果工廠類FruitsFactory

再建立水果類Fruits,以及Fruits的子類Apple,Orange,Banana

FruitsFactory.h

#import <Foundation/Foundation.h>
#import "Fruits.h"
#import "Apple.h"
#import "Orange.h"
#import "Banana.h"

// 由於外面要傳一個型別進來,所以要加一個列舉才行
typedef NS_ENUM(NSInteger) {
    kApple,
    kOrange,
    kBanana
} FruitsType;

@interface
FruitsFactory : NSObject
// 創造水果的工廠 + (Fruits *)fruitsFactory:(FruitsType)type; @end

FruitsFactory.m

#import "FruitsFactory.h"

@implementation FruitsFactory
+ (Fruits *)fruitsFactory:(FruitsType)type {
    // 建立空的物件.在工廠方法裡面進行水果的製造
    Fruits *fruits = nil;

    switch (type) {
        case kApple:
            fruits = [[Apple alloc] init];
            break
; case kOrange: fruits = [[Orange alloc] init]; break; case kBanana: fruits = [[Banana alloc] init]; default: break; } return fruits; } @end

Fruits.h

#import <Foundation/Foundation.h>

@interface Fruits : NSObject
- (void
)sweet; /**< 甜 */ - (void)poorTaste; /**< 不好吃 */ @end

Fruits.m

#import "Fruits.h"

@implementation Fruits

- (void)sweet {}

- (void)poorTaste {}

@end

Apple.h

#import "Fruits.h"
//遵循了開閉原則
@interface Apple : Fruits
- (void)freshApple; /**< 新鮮的蘋果 */   // 開閉原則
@end

Apple.m

#import "Apple.h"

@implementation Apple
// 甜
- (void)sweet {
    NSLog(@"Apple 非常甜");
}

// 不好吃
- (void)poorTaste {
    NSLog(@"Apple 不好吃");
}

// 新鮮的蘋果
- (void)freshApple {
    NSLog(@"Apple 新鮮的蘋果");
}
@end

Orange.h

#import "Fruits.h"

@interface Orange : Fruits
- (void)acidOrange; /**< 酸橘子 */
@end

Orange.m

#import "Orange.h"

@implementation Orange
// 甜
- (void)sweet {
    NSLog(@"Orange 非常甜");
}

// 不好吃
- (void)poorTaste {
    NSLog(@"Orange 不好吃");
}

/**< 酸橘子 */
- (void)acidOrange {
    NSLog(@"Orange 有點酸");
}

@end

Banana.h

#import "Fruits.h"

@interface Banana : Fruits

@end

Banana.m

#import "Banana.h"
//遵循了里氏替換原則
@implementation Banana
// 甜
- (void)sweet {
    NSLog(@"Banana 非常甜");
}

// 不好吃
- (void)poorTaste {
    NSLog(@"Banana 不好吃");
}
@end

ViewController.m呼叫水果工廠類,通過工廠類建立我們需要的物件

#import "ViewController.h"
#import "FruitsFactory.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // 在水果工廠裡面創建出蘋果
    Fruits *fruits = [FruitsFactory fruitsFactory:kApple];
    [fruits sweet];

    // 在水果工廠裡面創建出蘋果, 呼叫私有的方法
    Apple *apple = (Apple *)[FruitsFactory fruitsFactory:kApple];
    [apple freshApple];

    // 在水果工廠裡面創建出橘子, 呼叫私有的方法
    Orange *orange = (Orange *)[FruitsFactory fruitsFactory:kOrange];
    [orange acidOrange];
}

@end

工廠方法

結構圖

這裡寫圖片描述

程式碼示例:
這裡寫圖片描述

建立ColorViewGenerator,並且建立繼承自ColorViewGenerator的子類RedViewGenerator,BlueViewGenerator

建立ColorView類,並且建立繼承自ColorView的子類:RedView,BlueView

ColorViewGenerator.h

#import <Foundation/Foundation.h>
#import "ColorView.h"

@interface ColorViewGenerator : NSObject
- (ColorView *)colorViewWithFrame:(CGRect)frame;
@end

ColorViewGenerator.m

#import "ColorViewGenerator.h"

@implementation ColorViewGenerator
- (ColorView *)colorViewWithFrame:(CGRect)frame {
    return [[ColorView alloc] initWithFrame:frame];
}

@end

Generator 相當於一個工廠

RedViewGenerator.h

#import "ColorViewGenerator.h"
#import "RedView.h"

@interface RedViewGenerator : ColorViewGenerator

@end

RedViewGenerator.m

#import "RedViewGenerator.h"

@implementation RedViewGenerator
- (ColorView *)colorViewWithFrame:(CGRect)frame {
    return [[RedView alloc] initWithFrame:frame];
}
@end

BlueViewGenerator.h

#import "ColorViewGenerator.h"
#import "BlueView.h"

@interface BlueViewGenerator : ColorViewGenerator

@end

BlueViewGenerator.m

#import "BlueViewGenerator.h"

@implementation BlueViewGenerator
- (ColorView *)colorViewWithFrame:(CGRect)frame {
    return [[BlueView alloc] initWithFrame:frame];
}
@end

ColorView.m

#import "ColorView.h"

@implementation ColorView

- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        [self setBackgroundColor:[UIColor grayColor]];
    }
    return self;
}

@end

RedView.m

#import "RedView.h"

@implementation RedView

- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        self.backgroundColor = [UIColor redColor];

        UIImage *backgroundImage = [UIImage imageNamed:@"tupian"];
        UIImageView *backgroundView = [[UIImageView alloc] initWithImage:backgroundImage];
        [self addSubview:backgroundView];
    }
    return self;
}

@end

BlueView.m

#import "BlueView.h"

@implementation BlueView

- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        self.backgroundColor = [UIColor blueColor];

        UIImage *backgroundImage = [UIImage imageNamed:@"tupian2"];
        UIImageView *backgroundView = [[UIImageView alloc] initWithImage:backgroundImage];
        [self addSubview:backgroundView];
    }
    return self;
}


@end

ViewController.m呼叫

#import "ViewController.h"
#import "ColorViewGenerator.h"
#import "RedViewGenerator.h"
#import "BlueViewGenerator.h"


@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    // 1.建立一個工廠類
    ColorViewGenerator *colorGen = [[RedViewGenerator alloc] init];
    CGRect rect = CGRectMake(0, 0, 300, 600);
    ColorView *red = [colorGen colorViewWithFrame:rect];

    // 新增
    [self.view addSubview:red];

    ColorViewGenerator *colorGen2 = [[BlueViewGenerator alloc] init];
    CGRect rect2 = CGRectMake(300, 600, 50, 50);
    ColorView * blue = [colorGen2 colorViewWithFrame:rect2];
    [self.view addSubview:blue];
}

@end

這裡寫圖片描述

工廠方法:對多個產品抽象

抽象工廠

抽象工廠方法:對工廠抽象

抽象工廠UML圖

這裡寫圖片描述

程式碼示例:

這裡寫圖片描述

新建繼承自NSObject的類ColorViewFactory
ColorViewFactory.h

#import <UIKit/UIKit.h>

@interface ColorViewFactory : NSObject
// 生產紅色的View
+ (UIView *)colorView;

// 生產藍色的UIButton
+ (UIButton *)buttonView;
@end

ColorViewFactory.m

#import "ColorViewFactory.h"

@implementation ColorViewFactory
+ (UIView *)colorView {
    return  nil;
}

// 生產藍色的UIButton
+ (UIButton *)buttonView {
    return nil;
}
@end

建立繼承自ColorViewFactory的RedViewFactory和BlueViewFactory

RedViewFactory.m

#import "RedViewFactory.h"
#import "RedButton.h"
#import "RedSubView.h"

@implementation RedViewFactory
+ (UIView *)colorView {
    return [[RedSubView alloc] init];
}

+ (UIButton *)buttonView {
     return [RedButton buttonWithType:UIButtonTypeCustom];
}

@end

子類實現父類的抽象方法

BlueViewFactory.m

#import "BlueViewFactory.h"
#import "BlueButton.h"
#import "BlueSubView.h"

@implementation BlueViewFactory
+ (UIView *)colorView {
    return [[BlueSubView alloc] init];
}

+ (UIButton *)buttonView {
    return [BlueButton buttonWithType:UIButtonTypeCustom];
}
@end

建立繼承自UIView的RedSubView和BlueSubView

RedSubView.h
RedSubView.m

#import "RedSubView.h"

@implementation RedSubView

- (instancetype)init
{
    self = [super init];
    if (self) {
        self.frame = CGRectMake(0, 0, 100, 100);
        self.backgroundColor = [UIColor redColor];
    }
    return self;
}

@end

BlueSubView.h
BlueSubView.m

#import "BlueSubView.h"

@implementation BlueSubView

- (instancetype)init
{
    self = [super init];
    if (self) {
        self.frame = CGRectMake(0, 0, 100, 100);
        self.backgroundColor = [UIColor blueColor];
    }
    return self;
}

@end

建立繼承自UIButton的RedButton和BlueButton

RedButton.h
RedButton.m

#import "RedButton.h"

@implementation RedButton

+ (instancetype)buttonWithType:(UIButtonType)buttonType {
    [super buttonWithType:buttonType];

    RedButton *btn = [[RedButton alloc] initWithFrame:CGRectMake(0, 100, 300, 30)];
    [btn setTitle:@"紅色" forState:UIControlStateNormal];
    btn.titleLabel.backgroundColor = [UIColor redColor];
    btn.titleLabel.textAlignment = NSTextAlignmentCenter;

    return btn;
}

@end

BlueButton.h
BlueButton.m

#import "BlueButton.h"

@implementation BlueButton

+ (instancetype)buttonWithType:(UIButtonType)buttonType {
    [super buttonWithType:buttonType];

    BlueButton *btn = [[BlueButton alloc] initWithFrame:CGRectMake(0, 100, 300, 30)];
    [btn setTitle:@"藍色" forState:UIControlStateNormal];
    btn.titleLabel.backgroundColor = [UIColor redColor];
    btn.titleLabel.textAlignment = NSTextAlignmentCenter;

    return btn;
}

@end

ViewController.m

#import "ViewController.h"
#import "RedViewFactory.h"
#import "BlueViewFactory.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    UIView *red = [RedViewFactory colorView];
    UIButton *btn = [RedViewFactory buttonView];
    [self.view addSubview:btn];
    [self.view addSubview:red];
}

@end

總結:

抽象工廠
1. 通過物件組合建立抽象產品
2. 建立多個系列產品
3. 必須修改父類的接口才能支援新的產品

工廠方法
1.通過類繼承建立抽象產品
2.建立一種產品
3.子類化建立並重寫工廠方法來建立新產品
工廠方法: 多個產品抽象 抽象工廠: 是對工廠抽象