1.模式动机

  • 在工厂方法模式中具体工厂负责生产具体的产品,每一个具体工厂对应一种具体产品,工厂方法也具有唯一性,一般情况下,一个具体工厂中只有一个工厂方法或者一组重载的工厂方法。但是有时候我们需要一个工厂可以提供多个产品对象,而不是单一的产品对象。

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

  • 产品等级结构 :产品等级结构即产品的继承结构,如一个抽象类是电视机,其子类有海尔电视机、海信电视机、TCL电视机,则抽象电视机与具体品牌的电视机之间构成了一个产品等级结构,抽象电视机是父类,而具体品牌的电视机是其子类。
  • 产品族 :在抽象工厂模式中,产品族是指由同一个工厂生产的,位于不同产品等级结构中的一组产品,如海尔电器工厂生产的海尔电视机、海尔电冰箱,海尔电视机位于电视机产品等级结构中,海尔电冰箱位于电冰箱产品等级结构中。
  • 当系统所提供的工厂所需生产的具体产品并不是一个简单的对象,而是多个位于不同产品等级结构中属于不同类型的具体产品时需要使用抽象工厂模式。
  • 抽象工厂模式是所有形式的工厂模式中最为抽象和最具一般性的一种形态。
  • 抽象工厂模式与工厂方法模式最大的区别在于,工厂方法模式针对的是一个产品等级结构,而抽象工厂模式则需要面对多个产品等级结构,一个工厂等级结构可以负责多个不同产品等级结构中的产品对象的创建 。当一个工厂等级结构可以创建出分属于不同产品等级结构的一个产品族中的所有对象时,抽象工厂模式比工厂方法模式更为简单、有效率。

2.模式定义

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

3.模式结构

抽象工厂模式包含如下角色:

  • AbstractFactory:抽象工厂

  • ConcreteFactory:具体工厂

  • AbstractProduct:抽象产品

  • Product:具体产品

    https://static.sitestack.cn/projects/design-patterns/c2cea6d12c1ac4fed17e9176bcf0e351.jpeg

4.时序图

在这里插入图片描述

5.代码分析

5.1.c++实现

#include <iostream>
using namespace std;

class AbstractProductA
{
public:
    virtual void user() = 0;
};

class AbstractProductB
{
public:
    virtual void eat() = 0;
};

class ProductA1 : public AbstractProductA
{
public:
    void user()
    {
        cout << "ProductA1::user()" << endl;
    }
};

class ProductA2 : public AbstractProductA
{
public:
    void user()
    {
        cout << "ProductA2::user()" << endl;
    }
};

class ProductB1 : public AbstractProductB
{
public:
    void eat()
    {
        cout << "ProductB1::eat()" << endl;
    }
};

class ProductB2 : public AbstractProductB
{
public:
    void eat()
    {
        cout << "ProductB2::eat()" << endl;
    }
};

class AbstractFactory
{
public:
    virtual void createProduct();
};

class ConcreteFactory1 : public AbstractFactory
{
public:
    AbstractProductA *createProductA()
    {
        return new ProductA1();
    }

    AbstractProductB *createProductB()
    {
        return new ProductB1();
    }
};

class ConcreteFactory2 : public AbstractFactory
{
public:
    AbstractProductA *createProductA()
    {
        return new ProductA2();
    }

    AbstractProductB *createProductB()
    {
        return new ProductB2();
    }
};

5.2.Golang实现

package main

import "fmt"

type AbstractProductA interface {
	user()
}

type ProductA1 struct{}

func (c *ProductA1) user() {
	fmt.Println("ProductA1::user()")
}

type ProductA2 struct{}

func (c *ProductA2) user() {
	fmt.Println("ProductA2::user()")
}

type AbstractProductB interface {
	eat()
}

type ProductB1 struct{}

func (c *ProductB1) eat() {
	fmt.Println("ProductB1::eat()")
}

type ProductB2 struct{}

func (c *ProductB2) eat() {
	fmt.Println("ProductB2::eat()")
}

type AbstractFactory interface {
	createProductA() AbstractProductA
	createProductB() AbstractProductB
}

type ConcreteFactory1 struct{}

func (c *ConcreteFactory1) createProductA() AbstractProductA {
	return new(ProductA1)
}

func (c *ConcreteFactory1) createProductB() AbstractProductB {
	return new(ProductB1)
}

type ConcreteFactory2 struct{}

func (c *ConcreteFactory2) createProductA() AbstractProductA {
	return new(ProductA2)
}

func (c *ConcreteFactory2) createProductB() AbstractProductB {
	return new(ProductB2)
}

6.适用环境

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

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

更多推荐