美文网首页
抽象工厂模式

抽象工厂模式

作者: 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