美文网首页
抽象工厂模式

抽象工厂模式

作者: iOS扫地僧 | 来源:发表于2018-05-24 15:33 被阅读0次

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

抽象工厂

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

抽象工厂和工厂的比较

抽象工厂

  • 通过对象组合创建抽象产品
  • 创建多系列产品
  • 必须修改父类的接口才能支持新的产品

工厂方法

  • 通过类继承创建抽象产品
  • 创建一种产品
  • 子类话创建者并重载工厂方法以创建新产品

软件设计的黄金法则:变动需要抽象。
如果有多个类共有相同的行为,但实际实现不同,则可能需要某种抽象类型作为其父类被继承。

产品由两个不同的品牌工厂AcmeBrandingFactorySierraBrandingFactory来“生产”,他们各自重载抽象BrandingFactory类中定义的工厂方法brandedViewbrandedMainButtonbrandedToolbar,并根据工厂设计所针对的品牌返回具体产品。

超类的类方法factory是返回具体BrandingFactory的正确版本的工厂方法、其子类不应重载这个方法(尽管子类能够这么做),factory方法根据当前的编译配置返回一个具体品牌工厂的实例(个人理解:可以根据条件不同返回一个具体品牌工厂的实例)

BrandingFactory
#import <Foundation/Foundation.h>
#import<UIKit/UIKit.h>

@interface BrandingFactory : NSObject

+ (BrandingFactory *) factory;

- (UIView *) brandedView;
- (UIButton *) brandedMainButton;
- (UIToolbar *) brandedToolbar;

@end
#import "BrandingFactory.h"
#import "AcmeBrandingFactory.h"
#import "SierraBrandingFactory.h"


@implementation BrandingFactory

+ (BrandingFactory *) factory
{
#if defined (USE_ACME)
    return [[[AcmeBrandingFactory alloc] init] autorelease];
#elif defined (USE_SIERRA)
    return [[[SierraBrandingFactory alloc] init] autorelease];
#else
    return nil;
#endif
}

- (UIView *) brandedView
{
    return nil;
}

- (UIButton *) brandedMainButton
{
    return nil;
}

- (UIToolbar *) brandedToolbar
{
    return nil;
}

@end

factory类方法中,使用预处理器定义告诉编译器让这个方法返回哪个具体工厂。如果定义了宏USE_ACME,那么运行时会使用语句

return [[[AcmeBrandingFactory alloc] init] autorelease];

如果定义了宏USE_SIERRA,那么运行时会使用语句

return [[[SierraBrandingFactory alloc] init] autorelease];

此外的其他情况,此方法会返回nil

AcmeBrandingFactory
#import <Foundation/Foundation.h>
#import "BrandingFactory.h"

@interface AcmeBrandingFactory : BrandingFactory

- (UIView *) brandedView;
- (UIButton *) brandedMainButton;
- (UIToolbar *) brandedToolbar;

@end

AcmeBrandingFactory继承基类BrandingFactory,并重载其工厂方法为此品牌生产正确的UI元素,原始的factory类方法没有被重载,因为它原本用于父类创建具体BrandingFactory的实例,但是我们无法防止类方法被子类重载。

#import "AcmeBrandingFactory.h"
#import "AcmeView.h"
#import "AcmeMainButton.h"
#import "AcmeToolbar.h"


@implementation AcmeBrandingFactory

- (UIView *) brandedView
{
    // returns a custom view for Acme
    return [[AcmeView alloc] init];
}

- (UIButton *) brandedMainButton
{
    // returns a custom main button for Acme
    return [[AcmeMainButton alloc] init];
}

- (UIToolbar *) brandedToolbar
{
    // returns a custom toolbar for Acme
    return [[AcmeToolbar alloc] init];
}

@end

每个工厂方法的实现返回反映实际品牌的Acme*产品的实例。

SierraBrandingFactory
#import <Foundation/Foundation.h>
#import "BrandingFactory.h"

@interface SierraBrandingFactory : BrandingFactory

- (UIView*) brandedView;
- (UIButton*) brandedMainButton;
- (UIToolbar*) brandedToolbar;

@end

#import "SierraBrandingFactory.h"
#import "SierraView.h"
#import "SierraMainButton.h"
#import "SierraToolbar.h"

@implementation SierraBrandingFactory

- (UIView*) brandedView
{
    // returns a custom view for Sierra
    return [[SierraView alloc] init];
}

- (UIButton*) brandedMainButton
{
    // returns a custom main button for Sierra
    return [[SierraMainButton alloc] init];
}

- (UIToolbar*) brandedToolbar
{
    // returns a custom toolbar for Sierra
    return [[SierraToolbar alloc] init];
}

@end

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

调用
- (void)viewDidLoad {
    [super viewDidLoad];
    BrandingFactory * factory = [BrandingFactory factory];
    
    //...
    UIView * view = [factory brandedView];
    //... put the view on a proper location in view
    
    //...
    UIButton * button = [factory brandedMainButton];
    //... put the button on a proper location in view
    
    //...
    UIToolbar * toolbar = [factory brandedToolbar];
}

注意:BrandingFactory * factory = [BrandingFactory factory];
此时调用只有这一句话,在这里要深入理解抽象工厂的定义:提供一个创建一系列相关或相互依赖对象的接口,无需指定它们具体的类

相关文章

网友评论

      本文标题:抽象工厂模式

      本文链接:https://www.haomeiwen.com/subject/gassjftx.html