抽象工厂模式--创建型模式

1、描述

抽象工厂模式是一种创建型设计模式, 它能创建一系列相关的对象, 而无需指定其具体类。

什么是 “系列对象”? 例如有这样一组的对象: ​ 运输工具引擎控制器 。 它可能会有几个变体:

  1.   汽车内燃机方向盘
  2.   飞机喷气式发动机操纵杆

如果你的程序中并不涉及产品系列的话, 那就不需要抽象工厂。

优点:封装性,每个产品的实现类不是高层模块要关心的,它要关心的是什么?是接口,是抽象,它不关心对象是如何创建出来。

缺点:抽象工厂模式的最大缺点是产品族扩展非常困难。它严重违反了开闭原则。

2、结构图

  • 抽象产品(AbstractProduct)为构成系列产品的一组不同但相关的产品声明接口。
  • 具体产品(ConcreteProduct)是抽象产品的多种不同类型实现。
  • 抽象工厂(AbstractFactory)接口声明了一组创建各种抽象产品的方法。
  • 具体工厂(ConcreteFactory)实现抽象工厂的构建方法。每个具体工厂都对应特定产品变体,且仅创建此产品变体。

3、C++代码

#include <string>
#include <iostream>

// 系列产品中的特定产品必须有一个基础接口。所有产品变体都必须实现这个接口。
class AbstractProductA {
 public:
  virtual ~AbstractProductA(){};
  virtual std::string UsefulFunctionA() const = 0;
};

// 具体产品由相应的具体工厂创建。
class ConcreteProductA1 : public AbstractProductA {
 public:
  std::string UsefulFunctionA() const override {
    return "The result of the product A1.";
  }
};
class ConcreteProductA2 : public AbstractProductA {
  std::string UsefulFunctionA() const override {
    return "The result of the product A2.";
  }
};

// 这是另一个产品的基础接口。所有产品都可以互动,但是只有相同具体变体的产
// 品之间才能够正确地进行交互。
class AbstractProductB {
  
 public:
  virtual ~AbstractProductB(){};

  //产品B可以做自己的事情
  virtual std::string UsefulFunctionB() const = 0;

  //。。但它也可以和产品A配合。抽象工厂确保它创建的所有产品都是相同的变体,因此是兼容的。
  virtual std::string AnotherUsefulFunctionB(const AbstractProductA &collaborator) const = 0;
};

// 具体产品由相应的具体工厂创建。
class ConcreteProductB1 : public AbstractProductB {
 public:
  std::string UsefulFunctionB() const override {
    return "The result of the product B1.";
  }

  //产品B1只能和产品A1一起正常工作。然而,它接受AbstractProductA的任何实例作为参数。
  std::string AnotherUsefulFunctionB(const AbstractProductA &collaborator) const override {
    const std::string result = collaborator.UsefulFunctionA();
    return "The result of the B1 collaborating with ( " + result + " )";
  }
};

class ConcreteProductB2 : public AbstractProductB {
 public:
  std::string UsefulFunctionB() const override {
    return "The result of the product B2.";
  }

  //产品B2只能和产品A2一起正常工作。然而,它接受AbstractProductA的任何实例作为参数。
  std::string AnotherUsefulFunctionB(const AbstractProductA &collaborator) const override {
    const std::string result = collaborator.UsefulFunctionA();
    return "The result of the B2 collaborating with ( " + result + " )";
  }
};

// 抽象工厂接口声明了一组能返回不同抽象产品的方法。这些产品属于同一个系列
// 且在高层主题或概念上具有相关性。同系列的产品通常能相互搭配使用。系列产
// 品可有多个变体,但不同变体的产品不能搭配使用。
class AbstractFactory {
 public:
  virtual AbstractProductA *CreateProductA() const = 0;
  virtual AbstractProductB *CreateProductB() const = 0;
};

// 具体工厂可生成属于同一变体的系列产品。工厂会确保其创建的产品能相互搭配
// 使用。具体工厂方法签名会返回一个抽象产品,但在方法内部则会对具体产品进
// 行实例化。
class ConcreteFactory1 : public AbstractFactory {
 public:
  AbstractProductA *CreateProductA() const override {
    return new ConcreteProductA1();
  }
  AbstractProductB *CreateProductB() const override {
    return new ConcreteProductB1();
  }
};

// 每个具体工厂中都会包含一个相应的产品变体。
class ConcreteFactory2 : public AbstractFactory {
 public:
  AbstractProductA *CreateProductA() const override {
    return new ConcreteProductA2();
  }
  AbstractProductB *CreateProductB() const override {
    return new ConcreteProductB2();
  }
};

// 客户端代码仅通过抽象类型使用工厂和产品。这让你无需修改任何工厂或产品子类就能将其传递给客户端代码。
void ClientCode(const AbstractFactory &factory) {
  const AbstractProductA *product_a = factory.CreateProductA();
  const AbstractProductB *product_b = factory.CreateProductB();
  std::cout << product_b->UsefulFunctionB() << "\n";
  std::cout << product_b->AnotherUsefulFunctionB(*product_a) << "\n";
  delete product_a;
  delete product_b;
}

int main() {
  std::cout << "Client: Testing client code with the first factory type:\n";
  ConcreteFactory1 *f1 = new ConcreteFactory1();
  ClientCode(*f1);
  delete f1;
  std::cout << std::endl;
  std::cout << "Client: Testing the same client code with the second factory type:\n";
  ConcreteFactory2 *f2 = new ConcreteFactory2();
  ClientCode(*f2);
  delete f2;
  return 0;
}

参考:

https://refactoringguru.cn/

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值