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

news2024/10/5 12:29:51

大家好!本节主要介绍设计模式中的抽象工厂模式。

简介:

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

抽象工厂模式的创建步骤如下:
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.coloradmin.cn/o/1107109.html

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

相关文章

TCP/IP(十九)TCP 实战抓包分析(三)TCP 第一次握手 SYN 丢包

一 TCP 三次握手异常情况实战分析 说明&#xff1a; 本文是TCP 三次握手异常系列之一 ① 异常场景 接下里我用三个实验案例,带大家一起探究探究这三种异常关注&#xff1a; 如何刻意练习模拟上述场景 以及 wireshark现象 ② 实验环境 ③ 实验一&#xff1a;TCP 第一次握…

STM32F407在RAM中执行程序

STM32F407在flash中执行代码的速度比在ram中执行代码的速度快。因为STM32F407有一颗“自适应实时存储器加速器”&#xff0c;这里不讨论ART Accelerator的加速方案。 把代码放在RAM中执行纯粹是为了学习。 将个别函数的代码放到RAM中运行 使用自己编写的链接脚本(sct文件)。 …

《论文阅读28》OGMM

一、论文 研究领域&#xff1a; 点云配准 | 有监督 部分重叠论文&#xff1a;Overlap-guided Gaussian Mixture Models for Point Cloud Registration WACV 2023 二、概述 概率3D点云配准方法在克服噪声、异常值和密度变化方面表现出有竞争力的性能。本文将点云对的配准问题…

【计算机网络原理】初始网络基础

文章目录 1. 网络发展史1.1 单机时代1.2 网络互连局域网 LAN广域网 WAN 2. 网络通信基础2.1 IP 地址2.2 端口号2.3 协议2.4 五元组2.5 协议分层2.5.1 OSI七层模型2.5.2 TCP/IP五层模型 2.6 封装和分用2.6.1 数据封装(发送方情况)2.6.2 数据分用(接收方情况) 总结 1. 网络发展史…

这是不是你们都在找的免费又好用的配音网站?

随着人工智能技术的不断发展和普及&#xff0c;AI配音软件也越来越多地进入人们的视野。它可以帮助我们快速地将文字转换成语音&#xff0c;让我们的工作变得更加高效和便捷。在本文中&#xff0c;我将介绍一款非常实用而且免费的AI配音网站&#xff0c;超级简单好用&#xff0…

C++string的使用

CSDN的uu们&#xff0c;大家好。这里是C入门的第十六讲。 座右铭&#xff1a;前路坎坷&#xff0c;披荆斩棘&#xff0c;扶摇直上。 博客主页&#xff1a; 姬如祎 收录专栏&#xff1a;C专题 目录 1.构造函数 1.1 string() 1.2 string(const char* s) 1.3 string(const …

Cinema 4D云渲染一分钟动画要多少钱?如何进行Cinema 4D云渲染?看完就懂了

&#xfeff;1.为什么Cinema 4D要使用云渲染&#xff1f; 近年来&#xff0c;Cinema 4D在实现视觉效果方面取得了很大的进展。但是&#xff0c;随着视觉效果的复杂化&#xff0c;渲染的工作量也相应增加&#xff0c;导致渲染时间变长。在这种情况下&#xff0c;云渲染平台就能…

Linux嵌入式系统开发之路:从小白到大牛

&#x1f482; 个人网站:【工具大全】【游戏大全】【神级源码资源网】&#x1f91f; 前端学习课程&#xff1a;&#x1f449;【28个案例趣学前端】【400个JS面试题】&#x1f485; 寻找学习交流、摸鱼划水的小伙伴&#xff0c;请点击【摸鱼学习交流群】 嵌入式系统开发是一个充…

Spring framework Day22:Aware接口

前言 在Spring框架中&#xff0c;有许多接口和类都有一个非常重要的作用——让我们能够更方便地构建应用程序和管理组件。其中&#xff0c;Aware接口就是其中一个非常重要的接口之一。通过实现该接口&#xff0c;我们可以让Spring容器感知到特定的组件和资源&#xff0c;并进行…

媒体转码和输出软件:Media Encoder 2024中文版

想要高效地转码、优化输出吗&#xff1f;那就来尝试全新的Media Encoder 2024吧&#xff01;Media Encoder是Adobe公司出品的一款媒体转码和输出软件&#xff0c;可以帮助您快速、高效地将多种格式的视频和音频转换为所需的输出格式。 全新的Media Encoder 2024提供了更加智能…

【CANoe】XML Test Module使用实例

文章目录 一、实操步骤1、增加XML Test Module节点2、配置XML Test Module节点3、XML Test Module节点增加CAPL脚本(.can文件)4、文件夹结构5、使用仿真节点开始测试6、测试结果与测试报告7、同理&#xff0c;在Test Setup也可如此操作 一、实操步骤 1、增加XML Test Module节…

使用conda install一直卡在solving environment的解决方法

使用国内镜像源&#xff0c;但install仍旧一直卡在solving environment&#xff0c;超过10分钟就不用等了&#xff1b; 检查C:\Users\UserName 路径下的.condarc文件 将这个defaults这一行删掉即可

【Linux-常用命令-基础命令-复制-copy-命令-笔记】

【Linux-常用命令-基础命令-复制文件-copy-命令-笔记】 1、前言2、操作3、自己的实践 1、前言 最近&#xff0c;在使用Linux的时&#xff0c;使用相关基础命令是&#xff0c;总是容易忘记&#xff0c;上网一搜&#xff0c;大部分都写的比较繁琐&#xff0c;我就找下复制命令&a…

【算法设计与分析qwl】04 NP-hard——只是举例几个,货郎,双机调度,01背包

NP-hard问题&#xff1a; 有效算法是 输入规模的多项式时间算法。 这些问题的难度处于可有效计算的边界。 算法数据结构程序设计 例4 货郎问题 建模与算法&#xff1a; 解是一个排列&#xff0c; 0-1背包问题&#xff1a; 建模&#xff1a; 双机调度&#xff1a; 建模&#x…

【PPT技巧】如何将多张幻灯片打印在一张纸上?

PPT页面很多&#xff0c;想在打印的时候&#xff0c;多张幻灯片放置在同一页面&#xff0c;也就是打印在一张纸上&#xff0c;如何设置呢&#xff1f; 首先&#xff0c;打开需要打印的PPT文件&#xff0c;点击菜单选项卡【文件】&#xff0c;然后在弹出的页面中点击【打印】选…

单链表经典OJ题:找出链表的中间节点

题目&#xff1a; 给你单链表的头结点 head &#xff0c;请你找出并返回链表的中间结点。如果有两个中间结点&#xff0c;则返回第二个中间结点。 图例&#xff1a; 解法&#xff1a; 解法1: 先遍历链表确定链表节点的数量&#xff0c;然后再找到中间位置的节点 解法2: 快慢…

Linux性能优化--补充

14.1. 性能工具的位置 本书描述的性能工具来源于Internet上许多不同的位置。幸运的是&#xff0c;大多数主要发行版都把它们放在一起&#xff0c;包含在了其发行版的当前版本中。表A-1描述了全部工具&#xff0c;提供了指向其原始源位置的地址&#xff0c;并注明它们是否包含在…

百度地图高级进阶开发:圆形区域周边搜索地图监听事件(覆盖物重叠显示层级\图像标注监听事件、setZIndex和setTop方法)

百度地图API 使用百度地图API添加多覆盖物渲染时&#xff0c;会出现覆盖物被相互覆盖而导致都无法触发它们自己的监听&#xff1b;在百度地图API里&#xff0c;map的z-index为0&#xff0c;但是触发任意覆盖物的监听如click时也必定会触发map的监听&#xff1b; 项目需求 在…

6.7 案例分析与实现

思维导图&#xff1a; 6.7 案例分析与实现 #### 案例6.2: 六度空间理论 【案例分析】 - **背景介绍**&#xff1a; 六度空间理论提及在任意两人之间最多仅有6个人的连接。尽管这一理论被广泛提及并得到了某种程度的验证&#xff0c;但从科学角度看&#xff0c;它仍然只是一…

模型的选择与调优(网格搜索与交叉验证)

1、为什么需要交叉验证 交叉验证目的&#xff1a;为了让被评估的模型更加准确可信 2、什么是交叉验证(cross validation) 交叉验证&#xff1a;将拿到的训练数据&#xff0c;分为训练和验证集。以下图为例&#xff1a;将数据分成4份&#xff0c;其中一份作为验证集。然后经过…