前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >设计模式:抽象工厂模式

设计模式:抽象工厂模式

作者头像
王强
发布2018-08-09 17:24:17
2850
发布2018-08-09 17:24:17
举报
文章被收录于专栏:Python爬虫实战Python爬虫实战

1 概述

抽象工厂(Abstract Factory)模式提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。抽象工厂模式又称为Kit模式,属于对象创建型模式。

抽象工厂模式是指当有多个抽象角色时,使用的一种工厂模式。抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体的情况下,创建多个产品族中的产品对象。根据里氏替换原则,任何接受父类型的地方,都应当能够接受子类型。因此,实际上系统所需要的,仅仅是类型与这些抽象产品角色相同的一些实例,而不是这些抽象产品的实例。换言之,也就是这些抽象产品的具体子类的实例。工厂类负责创建抽象产品的具体子类的实例。

为了更清晰地理解抽象工厂模式,需要引入两个概念:

  • 产品等级结构: 产品等级结构即产品的继承结构,如一个抽象类是电视机,其子类有海尔电视机、TCL电视机、创维电视机,则抽象电视机与具体品牌的电视机之间构成了一个产品等级结构,抽象电视机是父类,而具体品牌的电视机是其子类。
  • 产品族: 产品族是指同一工厂生产的,位于不同产品等级结构中的一组产品,如海尔电器工厂生产的海尔电视机、海尔电冰箱,海尔电视机位于电视机产品等级结构部中,海尔电冰箱位于电冰箱产品等级结构中。

2 图解

现有两个产品族ProductA和ProductB,A1、A2与ProductA在同一产品等级结构中,B1、B2与ProductB在同一产品等级。现有两个工厂FactoryA与FactoryB,FactoryA可以生产A1、B1,Factory可以生产A2、B2。

如果要生产A1,客户需要知道生产A1的工厂,并且给其特定的参数,FactoryA才可以生产出A1。

图解抽象工厂模式

工厂方法模式包含如下角色:

  • Factory 抽象工厂角色: 声明用于创建抽象产品角色的接口。
  • ConcreteFactory 具体工厂角色(图中的FactoryA、FactoryB) 实现抽象工厂接口的具体工厂类,被应用程序调用以创建具体产品对象。
  • Product 抽象产品角色(图中的ProductA、ProductB): 负责描述其实例的公共接口。
  • ConcreteProduct 具体产品角色(图中的A1、A2、B1、B2): 实现了抽象产品角色所定义的接口 ,由具体工厂角色创建。

3 优缺点

优点:

  • 抽离了具体类的生成,使得客户并不需要知道什么被创建。
  • 可以在类的内部对产品族进行约束。
  • 增加新的具体工厂和产品族很方便,无须修改已有系统,符合“开闭原则”。

缺点:

  • 在添加新的产品对象时,难以扩展抽象工厂来生产新种类的产品。
  • 开闭原则的倾斜性(增加新的工厂和产品族容易,增加新的产品等级结构麻烦)。

4 应用场景

在以下情况下可以使用抽象工厂模式:

  • 一个系统不应当依赖于产品类实例如何被创建、组合和表达的细节,这对于所有类型的工厂模式都是重要的。
  • 系统中有多于一个的产品族,而每次只使用其中某一产品族。
  • 属于同一个产品族的产品将在一起使用,这一约束必须在系统的设计中体现出来。
  • 系统提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于具体实现。

5 实例

FactoryMethodUml

5.1 C++实现

  1. product.h
代码语言:javascript
复制
#ifndef PRODUCT_H
#define PRODUCT_H

#include <iostream>

// 产品基类
class ProductA
{
public:
    ProductA() {}
    virtual ~ProductA(){}

    virtual void detail() const
    {
        std::cout << "This is the base class of productA." << std::endl;
    }
};

class ProductB
{
public:
    ProductB() {}
    virtual ~ProductB(){}

    virtual void detail() const
    {
        std::cout << "This is the base class of productB." << std::endl;
    }
};

// 产品A1
class ProductA1 : public ProductA
{
public:
    ProductA1() {}
    ~ProductA1() {}

    virtual void detail() const
    {
        std::cout << "This is ProductA1." << std::endl;
    }
};

// 产品A2
class ProductA2 : public ProductA
{
public:
    ProductA2() {}
    ~ProductA2() {}

    virtual void detail() const
    {
        std::cout << "This is ProductA2." << std::endl;
    }
};

// 产品B1
class ProductB1 : public ProductB
{
public:
    ProductB1() {}
    ~ProductB1() {}

    virtual void detail() const
    {
        std::cout << "This is ProductB1." << std::endl;
    }
};

// 产品B2
class ProductB2 : public ProductB
{
public:
    ProductB2() {}
    ~ProductB2() {}

    virtual void detail() const
    {
        std::cout << "This is ProductB2." << std::endl;
    }
};

#endif // PRODUCT_H
  1. factory.h
代码语言:javascript
复制
#ifndef FACTORY_H
#define FACTORY_H

#include "product.h"

// 工厂基类
class Factory
{
public:
    Factory(){}
    virtual ~Factory(){}

    static ProductA* produceA()
    {
        return NULL;
    }

    static ProductB* produceB()
    {
        return NULL;
    }
};

// 工厂A
class FactoryA : public Factory
{
public:
    FactoryA();
    virtual ~FactoryA();

    static ProductA* produceA()
    {
        return new ProductA1();
    }

    static ProductB* produceB()
    {
        return new ProductB1();
    }
};

// 工厂B
class FactoryB : public Factory
{
public:
    FactoryB();
    virtual ~FactoryB();

    static ProductA* produceA()
    {
        return new ProductA2();
    }

    static ProductB* produceB()
    {
        return new ProductB2();
    }
};


#endif // FACTORY_H
  1. main.cpp
代码语言:javascript
复制
#include <iostream>

#include "factory.h"

using namespace std;

int main()
{
    cout << "There are what FactoryA produces." << endl;
    ProductA* productA1 = NULL;
    productA1 = FactoryA::produceA();
    productA1->detail();
    cout << "======================" << endl;

    ProductB* productB1 = NULL;
    productB1 = FactoryA::produceB();
    productB1->detail();
    cout << "======================" << endl;

    cout << "There are what FactoryB produces." << endl;
    ProductA* productA2 = NULL;
    productA2 = FactoryB::produceA();
    productA2->detail();
    cout << "======================" << endl;

    ProductB* productB2 = NULL;
    productB2 = FactoryB::produceB();
    productB2->detail();
    cout << "======================" << endl;

    delete productA1;
    delete productB1;
    delete productA2;
    delete productB2;

    return 0;
}

运行结果:

C++运行结果

5.2 Python代码

代码语言:javascript
复制
#-*- coding: utf-8 -*-

'''
  抽象工厂模式
'''

class ProductA:
    '''
    产品A基类
    '''
    def detail(self):   
        print('This is the base class of productA')

class ProductB:
    '''
    产品B基类
    '''
    def detail(self):   
        print('This is the base class of productB')

class ProductA1(ProductA):
    '''
    产品A1
    '''
    def detail(self):   
        print('This is ProductA1.')

class ProductA2(ProductA):
    '''
    产品A2
    '''
    def detail(self):   
        print('This is ProductA2.')

class ProductB1(ProductB):
    '''
    产品B1
    '''
    def detail(self):   
        print('This is ProductB1.')

class ProductB2(ProductB):
    '''
    产品B2
    '''
    def detail(self):   
        print('This is ProductB2.')


class Factory:
    '''
    工厂基类
    '''
    def produceA(self):
        return None

    def produceB(self):
        return None

class FactoryA(Factory):
    '''
    工厂A
    '''
    def produceA(self):
        return ProductA1()

    def produceB(self):
        return ProductB1()

class FactoryB(Factory):
    '''
    工厂B
    '''
    def produceA(self):
        return ProductA2()

    def produceB(self):
        return ProductB2()

def main():
    print('There are what FactoryA produces.')
    fA = FactoryA()
    productA1 = fA.produceA()
    productA1.detail()
    print('======================')
    productB1 =fA.produceB()
    productB1.detail()
    print('======================')

    print('There are what FactoryB produces.')
    fB = FactoryB()
    productA2 = fB.produceA()
    productA2.detail()
    print('======================')
    productB2 =fB.produceB()
    productB2.detail()
    print('======================')

if __name__ == '__main__':
    main()

运行结果:

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-04-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 C与Python实战 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1 概述
  • 2 图解
  • 3 优缺点
  • 4 应用场景
  • 5 实例
    • 5.1 C++实现
      • 5.2 Python代码
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档