当前位置: 首页 > article >正文

设计模式——工厂方法模式

引言

首先了解一下简单工厂模式:
假如有一个抽象的产品类,然后有很多具体的产品类,一个具体的工厂类根据传入的参数决定生产哪种产品。其优点是将产品的创建和使用分离,客户端不需要关心产品是如何创建的。
代码实例如下:

///
//  Factory.cpp
//  Implementation of the Class Factory
//  Created on:      01-10-2014 18:41:33
//  Original author: colin
///

#include "Factory.h"
#include "ConcreteProductA.h"
#include "ConcreteProductB.h"
Product* Factory::createProduct(string proname){
	if ( "A" == proname )
	{
		return new ConcreteProductA();
	}
	else if("B" == proname)
	{
		return new ConcreteProductB();
	}
	return  NULL;
}

上述模式缺点是如果工厂需要管理的产品非常多,那么实现逻辑很复杂且每次增加新的产品要修改原有的工厂类。

基本思想

于是就有了工厂模式,核心是添加一层抽象工厂类,实现间接引用,符合开闭原则。
工厂模式将创建对象的工作交给了工厂的子类(延迟创建对象),自己只提供需要子类实现的方法。这样,在需要新增的时候就可以不破坏原来的结构。
e.g.富士康(提供场地人员制作方法比如生产、运输、组装) ,富士康里面有苹果的生产线、有华为的生产线。这些生产线来进行具体怎么生产,怎么组装,怎么运输。 创建一个接口,然后再根据不同的需求实现这个接口。

代码实例:

/**
 * The Product interface declares the operations that all concrete products must
 * implement.
 */

class Product {
 public:
  virtual ~Product() {}
  virtual std::string Operation() const = 0;
};

/**
 * Concrete Products provide various implementations of the Product interface.
 */
class ConcreteProduct1 : public Product {
 public:
  std::string Operation() const override {
    return "{Result of the ConcreteProduct1}";
  }
};
class ConcreteProduct2 : public Product {
 public:
  std::string Operation() const override {
    return "{Result of the ConcreteProduct2}";
  }
};

/**
 * The Creator class declares the factory method that is supposed to return an
 * object of a Product class. The Creator's subclasses usually provide the
 * implementation of this method.
 */

class Creator {
  /**
   * Note that the Creator may also provide some default implementation of the
   * factory method.
   */
 public:
  virtual ~Creator(){};
  virtual Product* FactoryMethod() const = 0;
  /**
   * Also note that, despite its name, the Creator's primary responsibility is
   * not creating products. Usually, it contains some core business logic that
   * relies on Product objects, returned by the factory method. Subclasses can
   * indirectly change that business logic by overriding the factory method and
   * returning a different type of product from it.
   */

  std::string SomeOperation() const {
    // Call the factory method to create a Product object.
    Product* product = this->FactoryMethod();
    // Now, use the product.
    std::string result = "Creator: The same creator's code has just worked with " + product->Operation();
    delete product;
    return result;
  }
};

/**
 * Concrete Creators override the factory method in order to change the
 * resulting product's type.
 */
class ConcreteCreator1 : public Creator {
  /**
   * Note that the signature of the method still uses the abstract product type,
   * even though the concrete product is actually returned from the method. This
   * way the Creator can stay independent of concrete product classes.
   */
 public:
  Product* FactoryMethod() const override {
    return new ConcreteProduct1();
  }
};

class ConcreteCreator2 : public Creator {
 public:
  Product* FactoryMethod() const override {
    return new ConcreteProduct2();
  }
};

/**
 * The client code works with an instance of a concrete creator, albeit through
 * its base interface. As long as the client keeps working with the creator via
 * the base interface, you can pass it any creator's subclass.
 */
void ClientCode(const Creator& creator) {
  // ...
  std::cout << "Client: I'm not aware of the creator's class, but it still works.\n"
            << creator.SomeOperation() << std::endl;
  // ...
}

/**
 * The Application picks a creator's type depending on the configuration or
 * environment.
 */

int main() {
  std::cout << "App: Launched with the ConcreteCreator1.\n";
  Creator* creator = new ConcreteCreator1();
  ClientCode(*creator);
  std::cout << std::endl;
  std::cout << "App: Launched with the ConcreteCreator2.\n";
  Creator* creator2 = new ConcreteCreator2();
  ClientCode(*creator2);

  delete creator;
  delete creator2;
  return 0;
}

输出如下:

App: Launched with the ConcreteCreator1.
Client: I'm not aware of the creator's class, but it still works.
Creator: The same creator's code has just worked with {Result of the ConcreteProduct1}

App: Launched with the ConcreteCreator2.
Client: I'm not aware of the creator's class, but it still works.
Creator: The same creator's code has just worked with {Result of the ConcreteProduct2}

工程方法模式很好理解,就是在简单工厂模式上面加了一层抽象,然后把针对具体产品的生成交给不同的工厂去做,客户端通过调用不同的工厂类方法生产不同的产品。

工厂方法模式优缺点

优点:

  • 你可以避免创建者和具体产品之间的紧密耦合。
  • 单一职责原则。 你可以将产品创建代码放在程序的单一位置, 从而使得代码更容易维护。
  • 开闭原则。 无需更改现有客户端代码, 你就可以在程序中引入新的产品类型。
    缺点:
  • 应用工厂方法模式需要引入许多新的子类, 代码可能会因此变得更复杂。 最好的情况是将该模式引入创建者类的现有层次结构中。

http://www.kler.cn/a/452348.html

相关文章:

  • 编码转换(实例)
  • docker commit生成的镜像瘦身
  • git push origin HEAD:refs/for/分支名
  • 聊天社交管理系统 Java 源码,构建个性化社交空间
  • 本科阶段最后一次竞赛Vlog——2024年智能车大赛智慧医疗组准备全过程——12使用YOLO-Bin
  • TORCH_CUDA_ARCH_LIST
  • sqli-labs关卡记录13
  • 代码随想录算法训练营第51期第28天 | 122. 买卖股票的最佳时机 II、55. 跳跃游戏、45. 跳跃游戏 II、1005.K次取反后最大化的数组和
  • 实现用户登录系统的前后端开发
  • 第4章 函数
  • mysql主从同步延迟原因分析
  • 当代体育科技杂志当代体育科技杂志社当代体育科技编辑部2024年第33期目录
  • 【Java-tesseract】OCR图片文本识别
  • 微调 BERT:实现抽取式问答
  • 4G云网络广播系统
  • 替换 Docker.io 的 Harbor 安全部署指南:域名与 IP 双支持的镜像管理解决方案
  • 湖南引力:低代码助力实现智慧养老管理系统
  • Ubuntu重命名默认账户
  • YoloV9改策略:卷积改进|SAC,提升模型对小目标和遮挡目标的检测性能|即插即用
  • 操作系统课程设计
  • 通过opencv加载、保存视频
  • React 脚手架使用指南
  • mac系统升级后Homebrew:Mac os 使用brew工具时报错No remote ‘origin‘
  • linux-21 目录管理(一)mkdir命令,创建空目录
  • 【KV存储(3)】KV引擎详细设计
  • 使用openvino加速部署paddleocr文本检测模型(C++版)