设计模式-(3)抽象工厂

一,抽象工厂模式

在软件设计过程中,如果客户端需要手动创建一个类的对象,那么客户端需要知道这个类的细节。如果一组相关的对象需要在运行时按照不同的标准创建不一样的对象,那么客户端还需要知道全部细节才可以创建。这是恨糟糕的!

这时可以使用抽象工厂模式,提供一个固定的接口,用于创建一系列有关联或者相依存的对象,而不用指定具体类和细节。这样客户端和从工厂得到的对象之间没有发生耦合。

抽象工厂模式关系类图:

图中:

AbstractFactory:抽象工厂

ConcreteFactory1,ConcreteFactory2:具体的工厂

AbstractProductA,AbstractProductB:抽象的产品

ProductA1,ProductA2,ProductB1,ProductB2:具体的产品

图中可以看出,客户端Client只需要知道AbstractFactory和AbstractProduct。在每个工厂类中,结构与实际操作的细节按照黑箱对待。被创建的产品也不清楚谁负责创建自己。只有具体的工厂知道为客户端创建什么,怎么创建。工厂方法把实际创建对象的过程,推迟到子类中进行。

抽象工厂模式,常常和原型模式,单例模式,享元模式一起使用。


二,抽象工厂模式和工厂方法模式

两个模式用于相同的目的:创建对象而不让客户端知道返回了什么具体的对象。

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









软件设计黄金法则:变动需要抽象。


三,代理示例

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

@interface ZGYBrandingFactory : NSObject

+(instancetype)factory;

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

@end
#import "ZGYBrandingFactory.h"

#import "ZGYAcmeBrandingFactory.h"
#import "ZGYSierraBrandingFactory.h"

#define USE_ACME 1

@implementation ZGYBrandingFactory

+(instancetype)factory{
#if defined (USE_ACME)
    return [[ZGYAcmeBrandingFactory alloc]init];
#elif defined (USE_SIERRA)
    return [[ZGYSierraBrandingFactory alloc]init];
#else
    return nil;
#endif
}

- (UIView *)brandedView{
    return nil;
}

- (UIButton *)brandedMainButton{
    return nil;
}

- (UIToolbar *)brandedToolbar{
    return nil;
}

@end
#import "ZGYBrandingFactory.h"

@interface ZGYAcmeBrandingFactory : ZGYBrandingFactory

@end

#import "ZGYAcmeBrandingFactory.h"

#import "ZGYAcmeView.h"
#import "ZGYAcmeMainButton.h"
#import "ZGYAcmeToolBar.h"

@implementation ZGYAcmeBrandingFactory

- (UIView *)brandedView{
    return [[ZGYAcmeView alloc]init];
}

- (UIButton *)brandedMainButton{
    return [[ZGYAcmeMainButton alloc]init];
}

- (UIToolbar *)brandedToolbar{
    return [[ZGYAcmeToolBar alloc] init];
}

@end

#import <UIKit/UIKit.h>

@interface ZGYSierraBrandingFactory : UIToolbar

@end

#import "ZGYSierraBrandingFactory.h"

#import "ZGYSierraView.h"
#import "ZGYSierraMainButton.h"
#import "ZGYSierraToolBar.h"

@implementation ZGYSierraBrandingFactory

- (UIView *)brandedView{
    return [[ZGYSierraView alloc]init];
}

- (UIButton *)brandedMainButton{
    return [[ZGYSierraMainButton alloc]init];
}

- (UIToolbar *)brandedToolbar{
    return [[ZGYSierraToolBar alloc] init];
}

@end

客户端使用代码:

#import "ViewController.h"
#import "ZGYBrandingFactory.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    ZGYBrandingFactory * factory = [ZGYBrandingFactory factory];
    if (factory) {
        NSLog(@"%@",[factory class]);
        NSLog(@"%@",[[factory brandedView]class]);
        NSLog(@"%@",[[factory brandedMainButton]class]);
        NSLog(@"%@",[[factory brandedToolbar]class]);
    }
}

@end

打印结果

2017-10-07 15:06:51.522565+0800 设计模式(抽象工厂模式)[66543:2920566] ZGYAcmeBrandingFactory
2017-10-07 15:06:51.522862+0800 设计模式(抽象工厂模式)[66543:2920566] ZGYAcmeView
2017-10-07 15:06:51.547872+0800 设计模式(抽象工厂模式)[66543:2920566] ZGYAcmeMainButton
2017-10-07 15:06:51.548153+0800 设计模式(抽象工厂模式)[66543:2920566] ZGYAcmeToolBar


四,cocoa touch框架中的抽象工厂

在cocoa Touch框架中,有很多基础类采用了抽象工厂模式,NSNumber,NSString,NSArray,NSDIctory,NSData。

在NSNumber类中,有各种创建对象的类方法,numberWithBool:  numberWithInt:,等等。NSNumber中的各种类工厂方法定义了决定实例化和中具体私有子类的默认行为。这个版本的工厂方法是传统工厂方法的变体,虽然也是返回抽象产品对象,但此处的抽象产品是作为工厂的具体NSNumber子类。NSNumber是抽象工厂方法的一个例子。基础框架中抽象工厂的这个特点被称为“类族”(Class Cluster)



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值