抽象工厂(Abstract Factory)

定义

在软件设计中,如果客户想手动创建一个对象,需要知道对象的详细结构,包括其数据结构以及方法调用,如果运气不好,还可能因为该对象引用了其他对象,导致客户端还得了解其他对象,如此..使得该对象的创建变得复杂起来。之前讲过的工厂方法模式可以解决该类问题,不过工厂方法模式一般用来解决单个对象的创建,对于需要创建多个有关联的对象,那么可能就需要使用抽象工厂模式的方法了。此时,客户端只需要知道抽象出来的工厂以及自己所要的对象即可,不必清楚是谁创建以及怎样创建那些具体的对象。

抽象工厂的具体定义为:抽象工厂提供固定的接口,用于创建一系列有关联的对象,而不必指出其创建的细节。

ABSTRACT FACTORY: Provides an interface for creating families of related or dependent objects without specifying their concrete classes.*

* The original definition appeared in Design Patterns, by the “Gang of Four” (Addison-Wesley,1994).

其类似的类图示意图可能如下所示

上述的类图示意图中,如果客户端想创建产品A和B,他只需要知道抽象工厂的固定接口createProductA和createProductB(当然还得知道AbstractFactory、AbstractProductA和AbstractProductB的存在),这样他就能够直接使用这两个接口创建自己所需要的产品A和B了,而不需要知道产品A和B是谁创建的,在哪创建以及其他细节问题。通过抽象工厂的封装,使得有关联的对象的创建变得透明、简单化。

此外,通过抽象工厂模式的编程方法,你如果后续想添加其他产品,则直接按照定好的抽象工厂接口实现即可,而不需要改变客户端的代码调用。

在这里还得补充一点关于工厂方法和抽象工厂的关系问题,上图中,抽象工厂是有包含工厂方法的设计模式的,其中createProductA和createProductB都属于工厂方法,更多的比较可见下表:

工厂方法和抽象工厂
抽象工厂 工厂方法
通过对象组合创建产品 通过类继承创建产品
创建一类有关联的产品,包括多种产品 创建一种产品
如果新增产品类型,必须修改抽象类的固定接口 子类化创建者并重载工厂方法以创建新产品

代码示例

还是用主题来做个例子吧,这个例子是一个界面主题,该主题包括三部分:主视图,按钮,工具栏,不同的主题,这些元素的样式不一样,其他的是一样的。因此由此可抽象出一个抽象工厂类,该类提供的固定接口是三个创建对象的方法,分别用来创建主视图、按钮和工具栏。主要的关系图如下所示:

抽象类的定义如下所示:

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

@interface BrandFactory : NSObject
+ (BrandFactory*)fatoryWithName:(NSString*)name;
- (UIView*) brandView;
- (UIButton*) brandMainButton;
- (UIToolbar*) brandToolbar;
@end

上述代码定义了三个固定的接口,而类方法fatoryWithName则会根据名字选择对应的工厂。其中三个固定接口在抽象工厂类返回值是nil,而其中的类方法其实现如下所示:

+ (BrandFactory*)fatoryWithName:(NSString*)name
{
    BrandFactory* factory = nil;
    if([name isEqualToString:@"Serra"])
    {
        factory = [[SerraBrandFactory alloc] init];
    }
    else if([name isEqualToString:@"Acme"])
    {
        factory = [[AcmeBrandFactory alloc] init];
    }
    return factory;
}

对应于上图的关系图,实现的两个具体工厂类如下所示:

@implementation SerraBrandFactory
- (UIView*) brandView
{
    UIView* view = [[UIView alloc] init];
    view.backgroundColor = [UIColor redColor];
    return view;
}
- (UIButton*) brandMainButton
{
    UIButton* button = [[UIButton alloc] init];
    [button setTitle:@"Serra" forState:UIControlStateNormal];
    return button;
}
- (UIToolbar*) brandToolbar
{
    UIToolbar* toolbar = [[UIToolbar alloc] init];
    toolbar.barStyle = UIBarStyleBlack;

    UIBarButtonItem* item = [[UIBarButtonItem alloc] init];
    [item setImage:[UIImage imageNamed:@"cat.png"]];

    toolbar.items = [NSArray arrayWithObject:item];

    return toolbar;
}
@end
@implementation AcmeBrandFactory
- (UIView*) brandView
{
    UIView* view = [[UIView alloc] init];
    view.backgroundColor = [UIColor blueColor];
    return view;
}
- (UIButton*) brandMainButton
{
    UIButton* button = [[UIButton alloc] init];
    [button setTitle:@"Acme" forState:UIControlStateNormal];
    return button;
}
- (UIToolbar*) brandToolbar
{
    UIToolbar* toolbar = [[UIToolbar alloc] init];
    toolbar.barStyle = UIBarStyleBlack;

    UIBarButtonItem* item = [[UIBarButtonItem alloc] init];
    [item setImage:[UIImage imageNamed:@"dog.png"]];

    toolbar.items = [NSArray arrayWithObject:item];

    return toolbar;
}
@end

上两个实现分别返回自身定制的产品对象,而且都是通过基类抽象工厂类的固定接口返回的,这样当客户端需要构建这些对象的时候,直接使用抽象工厂提供的接口即可完成对所需的对象的创建,客户端冻得代码调用如下所示:

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    // 客户端加载视图
    BrandFactory* brand = [BrandFactory fatoryWithName:@"Serra"];
    //BrandFactory* brand = [BrandFactory fatoryWithName:@"Acme"];

    UIView* brandView = [brand brandView];
    brandView.frame = self.view.frame;
    [self.view addSubview:brandView];

    UIButton* brandButton = [brand brandMainButton];
    brandButton.frame = CGRectMake(60, 100, 200, 100);
    [self.view insertSubview:brandButton aboveSubview:brandView];

    UIToolbar* brandToolbar = [brand brandToolbar];
    brandToolbar.frame = CGRectMake(0, brandView.frame.size.height-40, brandView.frame.size.width, 40);
    [self.view insertSubview:brandToolbar aboveSubview:brandView];
}

使用抽象工厂的设计模式后,通过工厂的封装,客户端不再需要知道产品的具体细节,实现内部的黑盒透明化,同时,如果新增了产品后,客户端的代码调用改动会很小,只需要指定名字即可。如果不适用抽象工厂,那么常规的方法是这里需要自己手动创建每个产品对象,需要了解产品的具体细节,同时如果要修改为其他产品的话,要修改大量代码,可维护性和代码的重用性大大降低。因此,抽象工厂模式是好的,工厂设计模式是好的。

总结

抽象工厂以及其他的工厂模式是一种比较常见以及简单的编程设计模式,他也是最基本的设计模式,因为他涉及到许多类型对象的创建。在创建对象的时候,最好使用设计模式封装对象,使得对象抽象出来,具体细节得到隐藏。

时间: 2024-10-20 14:00:21

抽象工厂(Abstract Factory)的相关文章

【设计模式】创建型模式之抽象工厂Abstract Factory

抽象工厂Abstract Factory是一种创建型设计模式,目的在于提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类.抽象工厂的类图如下,客户仅与抽象类定义的定义的接口交互,而不使用特定的具体类的接口.一个系统包含多种产品时,AbstractFactory声明创建各种抽象产品对象的操作接口,这些接口是直接暴露给Client的,而具体产品对象的创建则延迟到子类ConcreteFactory,Client面对的产品类是AbstractProduct,无需关系具体产品类是什么.在运

面向对象设计——抽象工厂(Abstract Factory)模式

定义 提供一个创建一系列相关或者相互依赖对象的接口,而无需指定它们具体的类.抽象工厂允许客户使用抽象的接口来创建一组相关的产品,而不需要知道或关心实际产出的具体产品是什么.这样一来,客户就能从具体的产品中被解耦. 适用场景 在以下情况可以使用Abstract Factory模式 一个系统要独立于它的产品的创建.组合和表示时 一个系统要由多个产品系列中的一个来配置时 当你要强调一系列相关的产品对象的设计以便进行联合使用时 当你提供一个产品类库,而只想显示它们的接口而不是实现时 UML图 抽象工厂模

工厂模式[3] 抽象工厂 Abstract Factory

简介 1.简单工厂,或静态工厂,产品接口 定义:专门定义一个类来负责创建其他类的实例,被创建的实例通常具有共同的父类或实现同一接口 优点:客户端可以直接消费产品,而不必关心具体产品的实现(不关心对象的构造方法是怎么new的),消除了客户端直接创建产品对象的责任,实现了对责任的分割. 缺点:工厂类记录了所有产品的创建逻辑,一旦不能正常工作,整个系统都会受到影响:而且当产品种类多.结构复杂的时候,把所有创建工作放进一个工厂中来,会使后期程序的扩展较为困难. 2.工厂方法,工厂接口+产品接口 定义:在

设计模式(一) 抽象工厂(Abstract Factory)

1.定义 抽象工厂是一种常用的对象创建型设计模式.抽象工厂模式提供了一种方式,可以将一组具有统一主题的单独工厂封装起来,它提供一个创建一系列相关或相互依赖对象的接口,而无需制定它们具体的类. 2.结构 抽象工厂的结构图如下所示: AbstractFactory : 声明一个创建抽象产品对象的操作接口 ConcreteFactory : 实现创建具体产品对象的操作 AbstractProduct : 为一个类产品对象声明一个接口 ConcreteProduct : 定义一个将被相应的具体工厂创建产

【设计模式】——抽象工厂Abstract Factory

模式意图 提供对象的使用接口,隐藏对象的创建过程. 模式结构 AbstractFactory 提供创建对象的接口. ConcreteFactory 提供真正创建对象的实现类,用于组合并创建不同的对象,实现一个产品族. AbstractProduct 提供对象的使用接口. ConcreteProduct 提供真正的适用对象,隐藏该对象的创建过程,是工厂创建的对象. Client 使用者,通过抽象工厂接口,使用不同的具体工厂方法创建对象组合,从而直接使用对象,无需关注对象的创建过程. 适合场景 1

Headfirst设计模式的C++实现——抽象工厂(Abstract Factory)

Dough.h 1 #ifndef _DOUGH_H 2 #define _DOUGH_H 3 4 class Dough 5 { 6 }; 7 #endif ThinCrustDough.h 1 #ifndef _THIN_CRUST_DOUGH_H 2 #define _THIN_CRUST_DOUGH_H 3 4 #include "Dough.h" 5 6 class ThinCrustDough : public Dough 7 { 8 }; 9 #endif Sauce.h

设计模式 - 抽象工厂模式(abstract factory pattern) 详解

抽象工厂模式(abstract factory pattern) 详解 本文地址: http://blog.csdn.net/caroline_wendy/article/details/27091671 参考工厂模式: http://blog.csdn.net/caroline_wendy/article/details/27081511 抽象工厂模式: 提供一个接口, 用于创建相关或依赖对象的家族, 而不需要明确指定具体类. 全部代码: http://download.csdn.net/de

设计模式 - 抽象工厂模式(abstract factory pattern) 具体解释

抽象工厂模式(abstract factory pattern) 详细解释 本文地址: http://blog.csdn.net/caroline_wendy/article/details/27091671 參考工厂模式: http://blog.csdn.net/caroline_wendy/article/details/27081511 抽象工厂模式: 提供一个接口, 用于创建相关或依赖对象的家族, 而不须要明白指定详细类. 所有代码: http://download.csdn.net/

一天一个设计模式——Abstract Factory抽象工厂模式

一.模式说明 前面学习了工厂方法(Factory Method)模式.在工厂方法模式中,在工厂方法模式中,父类决定如何生成实例,但并不决定所要生成的具体类,具体的处理交由子类来处理.这里学习的抽象工厂方法模式中,抽象工厂使用抽象的零件组装成抽象的产品.即使用包含特定的方法接口零件,将零件组装成抽象产品. 二.模式类图: 上面的类图中包含两个包:包含抽象工厂,抽象零件,抽象产品的类所在的包以及具体工厂实现类的包. 三.代码示例 1.Item类: package com.designpattern.