设计模式:抽象工厂模式(C#、JAVA、JavaScript、C++、Python、Go、PHP)

上一篇《工厂方法模式》                                                              下一篇《单例模式》

简介:

抽象工厂模式,它是所有形态的工厂模式中最为抽象和最具一般性的一种形态。它用于处理当有多个抽象角色时的情况。抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体情况下创建多个产品组中的产品对象。这种模式根据里氏替换原则,任何接受父类型的地方都应当能够接受子类型。实际上,系统所需要的仅仅是类型与这些抽象产品角色相同的一些实例。

抽象工厂模式的创建步骤如下:
1、创建抽象工厂类,定义具体工厂的公共接口。
2、创建抽象产品族类,定义抽象产品的公共接口。
3、创建抽象产品类(继承抽象产品族类),定义具体产品的公共接口。
4、创建具体产品类(继承抽象产品类)&定义生产的具体产品。
5、创建具体工厂类(继承抽象工厂类),定义创建对应具体产品实例的方法。
6、客户端通过实例化具体的工厂类,并调用其创建不同目标产品的方法创建不同具体产品类的实例。

抽象工厂模式的优点,主要包括:
1、隔离了具体类的生产:使得客户并不需要知道什么被创建,降低了客户端与具体产品的耦合度。
2、保证同一产品族的使用:当一个产品族中的多个对象被设计成一起工作时,抽象工厂模式能保证客户端始终只使用同一个产品族中的对象。
3、易于扩展:增加新的具体工厂和产品族很方便,无须修改已有系统,符合“开闭原则”。
4、提供更高层次的抽象:抽象工厂模式能够提供更高层次的抽象,同时也能够更好地管理不同产品族之间的关系,从而使得系统更加灵活和易于扩展。
5、符合单一职责原则:每个具体工厂只负责创建一组具体产品,不会与其他产品产生耦合。

抽象工厂模式的缺点,主要包括:
1、增加新的产品等级结构麻烦:需要对原有系统进行较大的修改,甚至需要修改抽象层代码,这可能会违背开闭原则。
2、抽象工厂模式需要识别和定义所有的抽象产品类和具体产品类,这会增加系统的复杂性。
3、在客户端代码中需要显式地指定使用哪个具体工厂,这会增加客户端代码的复杂性。
4、如果出现异常情况,很难确定是哪一个工厂或者是哪一个产品出现问题,因为它们都是独立的对象。
5、实现抽象工厂模式需要消耗较多的时间和精力,因为需要分离出抽象工厂类和具体工厂类,并且需要针对每个具体工厂类编写对应的客户端代码。


示例:

在实际应用中,工厂的创建和产品的生产可能会更加复杂,并且可能会有更多的具体工厂和产品类。


一、C#抽象工厂模式

以下是一个示例,展示了如何在C#中实现抽象工厂模式:

//首先,定义一个接口来表示工厂:
public interface IFactory {  Product CreateProduct();  
}
//接下来,实现具体工厂类,它们分别创建具体产品对象:
public class ConcreteFactoryA : IFactory {  public Product CreateProduct() {  return new ConcreteProductA();  }  
}  public class ConcreteFactoryB : IFactory {  public Product CreateProduct() {  return new ConcreteProductB();  }  
}
//然后,定义一个抽象产品接口和具体产品类来实现该接口:
public interface Product {  void Use();  
}  public class ConcreteProductA : Product {  public void Use() {  Console.WriteLine("Using Product A");  }  
}  public class ConcreteProductB : Product {  public void Use() {  Console.WriteLine("Using Product B");  }  
}
//最后,编写客户端代码来使用抽象工厂模式创建产品对象:
public class Client {  public void UseProduct(IFactory factory) {  Product product = factory.CreateProduct();  product.Use();  }  
}
//在主程序中,可以创建客户端对象并使用不同的工厂对象来创建产品对象:
static void Main() {  Client client = new Client();  IFactory factoryA = new ConcreteFactoryA();  client.UseProduct(factoryA); // Output: Using Product A  IFactory factoryB = new ConcreteFactoryB();  client.UseProduct(factoryB); // Output: Using Product B  
}


二、java抽象工厂模式模式

抽象工厂模式通常通过以下方式实现:

//抽象工厂接口:这是一个工厂的抽象接口,它定义了创建对象的方法,但并不实现。
public interface AbstractFactory {  ProductA createProductA();  ProductB createProductB();  
} //具体工厂类:这些类实现了抽象工厂接口,并知道如何创建特定类型的对象。
public class ConcreteFactory1 implements AbstractFactory {  @Override  public ProductA createProductA() {  return new ProductA1();  }  @Override  public ProductB createProductB() {  return new ProductB1();  }  
}  public class ConcreteFactory2 implements AbstractFactory {  @Override  public ProductA createProductA() {  return new ProductA2();  }  @Override  public ProductB createProductB() {  return new ProductB2();  }  
}//抽象产品接口:这些接口定义了产品的规范,即产品应具有的通用方法。
public interface ProductA {  void use();  
}  public interface ProductB {  void use();  
}//具体产品类:这些类实现了抽象产品接口,并提供了具体的实现。
public class ProductA1 implements ProductA {  @Override  public void use() {  System.out.println("Using product A1");  }  
}  public class ProductA2 implements ProductA {  @Override  public void use() {  System.out.println("Using product A2");  }  
}  //最后,在客户端代码中,我们通常会使用一个“提供者”类(如名称“Provider”)来获取工厂对象,然后使用这些工厂对象来创建产品。这样可以让客户端代码与工厂的具体实现解耦。
public class Client {  private AbstractFactory factory;  public Client(AbstractFactory factory) {  this.factory = factory;  }  public void useProducts() {  ProductA productA = factory.createProductA();  productA.use();  ProductB productB = factory.createProductB();  productB.use();  }  
}
//主程序    
public static void main(String[] args) {  Client client = new Client();  AbstractFactory factory1 = new ConcreteFactory1();  client.UseProduct(factory1); // Output: Using Product A  AbstractFactory factory2 = new ConcreteFactory2();  client.UseProduct(factory2); // Output: Using Product B  
}


三、javascript抽象工厂模式

在JavaScript中,抽象工厂模式通常可以通过构造函数和对象字面量的组合来实现。

// 抽象工厂接口  
function AbstractFactory() {  this.createProduct = function() {  throw new Error("This method is abstract and has to be implemented");  };  
}  // 具体工厂类1  
function ConcreteFactory1() {}  
ConcreteFactory1.prototype.createProduct = function() {  return new Product1();  
};  // 具体工厂类2  
function ConcreteFactory2() {}  
ConcreteFactory2.prototype.createProduct = function() {  return new Product2();  
};  // 产品接口  
function Product() {}  
Product.prototype.use = function() {  throw new Error("This is an abstract method and has to be implemented");  
};  // 产品类1  
function Product1() {}  
Product1.prototype = Object.create(Product.prototype);  
Product1.prototype.constructor = Product1;  
Product1.prototype.use = function() {  console.log("Using product 1");  
};  // 产品类2  
function Product2() {}  
Product2.prototype = Object.create(Product.prototype);  
Product2.prototype.constructor = Product2;  
Product2.prototype.use = function() {  console.log("Using product 2");  
};  // 客户端代码  
function Client() {  var factory;  this.setFactory = function(f) {  factory = f;  };  this.useFactory = function() {  var product = factory.createProduct();  product.use();  };  
}  var client = new Client();  
client.setFactory(new ConcreteFactory1());  
client.useFactory(); // Outputs: Using product 1  
client.setFactory(new ConcreteFactory2());  
client.useFactory(); // Outputs: Using product 2

四、C++抽象工厂模式

以下是在C++中实现抽象工厂模式:

#include <iostream>  
#include <string>  // 抽象产品接口  
class Product {  
public:  virtual void use() = 0;  
};  // 具体产品类1  
class ProductA : public Product {  
public:  void use() {  std::cout << "Using Product A" << std::endl;  }  
};  // 具体产品类2  
class ProductB : public Product {  
public:  void use() {  std::cout << "Using Product B" << std::endl;  }  
};  // 抽象工厂接口  
class Factory {  
public:  virtual Product* createProduct() = 0;  
};  // 具体工厂类1  
class FactoryA : public Factory {  
public:  Product* createProduct() {  return new ProductA();  }  
};  // 具体工厂类2  
class FactoryB : public Factory {  
public:  Product* createProduct() {  return new ProductB();  }  
};  int main() {  // 创建抽象工厂对象  Factory* factory = nullptr;  // 创建具体工厂类1的对象,并赋值给抽象工厂对象  FactoryA factoryA;  factory = &factoryA;  // 使用抽象工厂对象创建产品对象,并使用产品对象  Product* product = factory->createProduct();  product->use();  // 创建具体工厂类2的对象,并赋值给抽象工厂对象  FactoryB factoryB;  factory = &factoryB;  // 使用抽象工厂对象创建产品对象,并使用产品对象  product = factory->createProduct();  product->use();  return 0;  
}


五、python抽象工厂模式

以下是在python中实现抽象工厂模式:

#定义抽象产品接口,抽象产品接口定义了产品对象的通用方法。
class Product:  def use(self):  raise NotImplementedError("This method is abstract and has to be implemented")#实现具体产品类
class ProductA(Product):  def use(self):  print("Using Product A")  class ProductB(Product):  def use(self):  print("Using Product B")#定义抽象工厂接口,抽象工厂接口定义了创建产品对象的通用方法。
class Factory:  def createProduct(self):  raise NotImplementedError("This method is abstract and has to be implemented")#实现具体工厂类,具体工厂类继承抽象工厂接口并实现createProduct方法
class FactoryA(Factory):  def createProduct(self):  return ProductA()  class FactoryB(Factory):  def createProduct(self):  return ProductB()#创建客户端代码,客户端代码使用抽象工厂接口创建产品对象并使用它们。
factory = Factory()  # 创建抽象工厂对象  
product = factory.createProduct()  # 使用抽象工厂对象创建产品对象  
product.use()  # 使用产品对象


六、go抽象工厂模式

以下是一个示例,展示了如何在go中实现抽象工厂模式:

//定义接口:首先,定义出需要创建对象的接口,这个接口规定了对象的共有方法。
type Product interface {  Use()  
}  type ConcreteProductA struct{}  func (p *ConcreteProductA) Use() {  fmt.Println("Using Product A")  
}  type ConcreteProductB struct{}  func (p *ConcreteProductB) Use() {  fmt.Println("Using Product B")  
}//定义抽象工厂接口:接下来,定义出抽象工厂接口,这个接口规定了创建对象的方法。
type Factory interface {  CreateProduct() Product  
}  type ConcreteFactoryA struct{}  func (f *ConcreteFactoryA) CreateProduct() Product {  return &ConcreteProductA{}  
}  type ConcreteFactoryB struct{}  func (f *ConcreteFactoryB) CreateProduct() Product {  return &ConcreteProductB{}  
}//实现客户端代码:现在可以写客户端代码了,这个代码使用抽象工厂接口来创建产品对象。
func main() {  factoryA := &ConcreteFactoryA{}  productA := factoryA.CreateProduct()  productA.Use() // Output: Using Product A  factoryB := &ConcreteFactoryB{}  productB := factoryB.CreateProduct()  productB.Use() // Output: Using Product B  
}


七、PHP抽象工厂模式

以下是一个示例,展示了如何在PHP中实现抽象工厂模式:

// 抽象产品接口  
interface Product {  public function operation();  
}  // 具体产品类实现抽象接口  
class ConcreteProductA implements Product {  public function operation() {  echo "Product A operation\n";  }  
}  class ConcreteProductB implements Product {  public function operation() {  echo "Product B operation\n";  }  
}  // 抽象工厂接口  
interface Factory {  public function createProduct();  
}  // 具体工厂类实现抽象工厂接口,创建具体产品对象  
class ConcreteFactoryA implements Factory {  public function createProduct() {  return new ConcreteProductA();  }  
}  class ConcreteFactoryB implements Factory {  public function createProduct() {  return new ConcreteProductB();  }  
}  // 客户端代码使用抽象工厂对象创建具体产品对象  
class Client {  public function useProduct(Factory $factory) {  $product = $factory->createProduct();  $product->operation();  }  
}  // 示例用法  
$client = new Client();  
$factoryA = new ConcreteFactoryA();  
$client->useProduct($factoryA); // Output: Product A operation  $factoryB = new ConcreteFactoryB();  
$client->useProduct($factoryB); // Output: Product B operation

《完结》

上一篇《工厂方法模式》​​​​​​​                                                              下一篇《单例模式》

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/116364.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

1024发博客!

1024发博客&#xff01;

Spring和SpringBoot学习

Spring和SpringBoot学习 Spring中常用注解及其作用 Spring中常用注解及其作用 SpringBoot注解扫描范围 SpringBoot | ComponentScan()注解默认扫描包范围分析 spring boot的包扫描范围 springBoot的自动扫描包范围 SpringBoot中new对象不能自动注入对象 SpringBoot中new对…

Linux备份Docker的mysql数据并传输到其他服务器保证数据级容灾

目录 简介什么是容灾 &#xff1f;容灾的分类容灾和备份有什么连系 &#xff1f; 数据级容灾备份步骤1、scp命令&#xff1a;用于Linux之间复制文件和目录2、编写备份数据库脚本3、crontab定时任务执行脚本4、测试 应用级容灾业务级容灾 简介 为了防止客户系统的数据丢失&…

【Python爬虫】安装requests库解决报错问题

requests 确保pip的安装命令行下安装出现的问题以及解决办法换镜像源安装验证安装为什么使用requests库呢 废话不多说了&#xff0c;直接进入正题 确保pip的安装 首先要想安装requests库&#xff0c;第一点就是要确保pip已经安装。这个pip在Python高级版本中已经默认安装了。…

Maxon Cinema 4D 2024:打造独一无二的视觉效果 模拟模块大更新

在视觉效果和3D建模领域&#xff0c;Maxon的Cinema 4D一直以其卓越的性能和创新的功能引领着时代潮流。今天&#xff0c;我们很高兴地宣布推出最新版本——Maxon Cinema 4D 2024&#xff08;C4D 2024&#xff09;&#xff0c;它将再次提升行业标准&#xff0c;为设计师提供更强…

基于蝗虫算法的无人机航迹规划-附代码

基于蝗虫算法的无人机航迹规划 文章目录 基于蝗虫算法的无人机航迹规划1.蝗虫搜索算法2.无人机飞行环境建模3.无人机航迹规划建模4.实验结果4.1地图创建4.2 航迹规划 5.参考文献6.Matlab代码 摘要&#xff1a;本文主要介绍利用蝗虫算法来优化无人机航迹规划。 1.蝗虫搜索算法 …

进阶JAVA篇-深入了解 List 系列集合

目录 1.0 List 类的说明 1.1 List 类的常用方法 1.2 List 集合的遍历方式 2.0 ArrayList 集合的底层原理 2.1 从 ArrayList 集合的底层原理来了解具有该特性的原因&#xff1a; 2.2 ArrayList 集合的优缺点 3.0 LinkedList 集合的底层原理 3.1 从 LinkedList 集合的底层原理来了…

中心胖AP(AD9430DN)+远端管理单元RU(R240D)+出口网关,实现组网

适用于&#xff1a;V200R008至V200R019C00版本的万兆中心胖AP&#xff08;AD9431DN-24X&#xff09;。 组网规划 RU管理&#xff1a;VLAN 100&#xff0c;网段为192.168.100.0/24。 无线业务&#xff1a;VLAN 3&#xff0c;SSID为“wlan-net”&#xff0c;密码为“88888888”…

无法获取下载文件名的无奈之举

最近&#xff0c;领导又让我发挥余热&#xff0c;开发些网页操作工具。其中涉及到需要下载文件&#xff0c;以前也研究过webbrower截获下载并接管下载&#xff0c;不过太麻烦了&#xff0c;而且我只是针对特定网页拦截下载&#xff0c;重新刮资料&#xff0c;从这里&#xff08…

根据Lambda表达式获取实体字段

代码 package com.shunneng.platform.web.rest.util;import javax.persistence.Column; import java.io.Serializable; import java.lang.invoke.SerializedLambda; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.r…

怎么下载微信视频号视频?

你是否曾经在浏览视频号时看到了一些精彩的视频号&#xff0c;希望能够保存下来&#xff0c;但却不知道如何下载&#xff1f;别担心&#xff01;本篇文章将为你介绍一个方便易用的视频号下载工具&#xff0c;让你轻松保存喜欢的视频号视频&#xff01;犀牛下载是一款专门为微信…

05 | 类型匹配:怎么切除臃肿的强制转换

Java 的模式匹配是一个新型的、而且还在持续快速演进的领域。类型匹配是模式匹配的一个规范。类型匹配这个特性&#xff0c;首先在 JDK 14 中以预览版的形式发布。在 JDK 15 中&#xff0c;改进的类型匹配再次以预览版的形式发布。最后&#xff0c;类型匹配在 JDK 16 正式发布。…

电子画册如何制作,教你几分钟简单上手制作?

电子画册不同于纸质画册&#xff0c;它可以不受时间、空间及地域的限制&#xff0c;以更直观、新颖的形式展示在读者面前&#xff0c;还能快速传播效益。所以&#xff0c;当下&#xff0c;越来越多人想要用电子画册来传递内容信息。 如何制作电子画册&#xff1f;其实只要使用…

Python 框架学习 Django篇 (五) Session与Token认证

我们前面经过数据库的学习已经基本了解了怎么接受前端发过来的请求&#xff0c;并处理后返回数据实现了一个基本的登录登出效果&#xff0c;但是存在一个问题&#xff0c;我们是将所有的请求都直接处理了&#xff0c;并没有去检查是否为已经登录的管理员发送的&#xff0c;如果…

Kotlin Lambda表达式与标准库中的高阶函数

在Kotlin中&#xff0c;Lambda表达式和标准库中的高阶函数为我们提供了一种简洁而强大的方式来处理集合和执行各种操作。本篇博客将介绍Lambda表达式的基本概念&#xff0c;并结合标准库中的高阶函数示例&#xff0c;展示它们的用法和功能。 Lambda表达式的基本概念 Lambda表…

WebAPI项目在Linux服务器上部署记录

对已有的WebAPI项目进行发布 发布流程 需要把publish的文件夹直接上传至linux服务器 在Linux服务器上部署环境 检查是否安装了dotnet环境 直接命令行输入 dontnet&#xff0c;如果弹出的是下面的语句&#xff0c;说明没有安装dotnet环境 -bash: dotnet:command not found…

React 框架

1、React 框架简介 1.1、介绍 CS 与 BS结合&#xff1a;像 React&#xff0c;Vue 此类框架&#xff0c;转移了部分服务器的功能到客户端。将CS 和 BS 加以结合。客户端只用请求一次服务器&#xff0c;服务器就将所有js代码返回给客户端&#xff0c;所有交互类操作都不再依赖服…

点云从入门到精通技术详解100篇-双目鱼眼系统的畸变校正及目标重建(续)

目录 3.3双目鱼眼系统标定 3.4基于光束平差法的标定结果优化 3.5标定实验结果与分析

elementUI 中 date-picker 的使用的坑(vue3)

目录 1. 英文显示2. format 与 value-format 无效3. date-picker 时间范围4. 小结 1. 英文显示 <el-date-pickerv-model"dateValue"type"date"placeholder"选择日期"></el-date-picker>解决方案&#xff1a; 引用 zhCn <script&g…

ARM CoreSight相关模块简介

最近在学习ARM CPU软硬件开发&#xff0c;对于CoreSight看到很多模块&#xff0c;简单总结了下。 1. DAP ARM DAP (Debug Access Port) 的主要作用是为调试工具提供直接访问 ARM 处理器和其它相关硬件的途径。DAP 是 ARM CoreSight 调试和追踪技术的一部分&#xff0c;它允许…