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

news2025/7/17 9:10:06

本节主要介绍设计模式中的工厂方法模式。

简介:

工厂方法模式,它是对简单工厂模式的进一步抽象化,其好处是可以使系统在不修改原来代码的情况下引进新的产品,即满足开闭原则。
它定义了一个用于创建对象的工厂接口,让子类决定实例化哪个类。在工厂方法模式中,父类负责定义创建对象的公共接口,而子类则负责生成具体的对象。这种模式将类实例化操作延迟到子类中完成,即由子类来决定究竟应该实例化哪个类。

工厂方法模式的创建步骤如下:
1、创建抽象工厂类,定义具体工厂的公共接口。
2、创建抽象产品类,定义具体产品的公共接口。
3、创建具体产品类,继承抽象产品类并定义具体产品的生产。
4、创建具体工厂类,继承抽象工厂类并定义创建对应具体产品实例的方法。
5、外界通过调用具体工厂类的方法,从而创建不同具体产品类的实例。

工厂方法模式的优点,主要包括:
1、增加新的产品类时无需修改现有系统:当需要增加一个新的产品时,只需要创建一个新的具体工厂和具体产品类,符合“开放-封闭”原则,增加了系统的灵活性和可扩展性。
2、封装了产品对象的创建细节:客户端只需要使用具体工厂类创建产品对象,无需关心对象是如何被创建的,这样就可以将产品对象的创建细节封装在具体工厂类中。
3、系统具有良好的灵活性和可扩展性:通过使用工厂方法模式,可以在不改变现有客户端代码的情况下,增加或修改产品类和工厂类,具有较强的灵活性。

工厂方法模式的缺点,主要包括:
1、增加额外的编写工作量:在增加新产品时,需要编写新的具体产品类和对应的具体工厂类,增加了系统的复杂度,需要更多的类需要编译和运行,给系统带来一些额外的开销。
2、需要考虑系统的抽象性和理解难度:为了增加系统的可扩展性,需要引入抽象层,在客户端代码中均使用抽象层进行定义,增加了系统的抽象性和理解难度,且在实现时可能需要用到DOM、反射等技术,增加了系统的实现难度。

​​​​​​​

示例

一、C#工厂方法模式

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

// 产品的抽象类  
public abstract class Product  
{  
    public abstract void Use();  
}  
  
// 具体产品类1  
public class ConcreteProduct1 : Product  
{  
    public override void Use()  
    {  
        Console.WriteLine("使用具体产品1");  
    }  
}  
  
// 具体产品类2  
public class ConcreteProduct2 : Product  
{  
    public override void Use()  
    {  
        Console.WriteLine("使用具体产品2");  
    }  
}  
  
// 工厂的抽象类  
public abstract class Creator  
{  
    // 工厂方法,由子类实现具体的创建逻辑  
    public abstract Product CreateProduct();  
}  
  
// 具体工厂类1  
public class ConcreteCreator1 : Creator  
{  
    public override Product CreateProduct()  
    {  
        return new ConcreteProduct1();  
    }  
}  
  
// 具体工厂类2  
public class ConcreteCreator2 : Creator  
{  
    public override Product CreateProduct()  
    {  
        return new ConcreteProduct2();  
    }  
}  
  
class Program  
{  
    static void Main(string[] args)  
    {  
        Creator creator1 = new ConcreteCreator1(); 
        Product product1 = creator1.CreateProduct();   
        product1.Use();  
        
        Creator creator2 = new ConcreteCreator2  
        Product product2 = creator2.CreateProduct(); 
        product2.Use();  
    }  
}

二、java工厂方法模式

以下是一个示例,展示了如何在Java中实现工厂方法模式:

// 抽象产品类  
public abstract class Product {  
    public abstract void use();  
}  
  
// 具体产品类1  
public class ConcreteProduct1 extends Product {  
    @Override  
    public void use() {  
        System.out.println("使用具体产品1");  
    }  
}  
  
// 具体产品类2  
public class ConcreteProduct2 extends Product {  
    @Override  
    public void use() {  
        System.out.println("使用具体产品2");  
    }  
}  
  
// 抽象工厂类  
public abstract class Factory {  
    // 工厂方法,由子类实现具体的创建逻辑  
    public abstract Product createProduct();  
}  
  
// 具体工厂类1  
public class ConcreteFactory1 extends Factory {  
    @Override  
    public Product createProduct() {  
        return new ConcreteProduct1();  
    }  
}  
  
// 具体工厂类2  
public class ConcreteFactory2 extends Factory {  
    @Override  
    public Product createProduct() {  
        return new ConcreteProduct2();  
    }  
}  
  
// Client代码  
public class Client {  
    public static void main(String[] args) {  
        Factory factory = new ConcreteFactory1(); // 可以根据实际需要更换为ConcreteFactory2  
        Product product = factory.createProduct();  
        product.use();  
    }  
}


三、javascript工厂方法模式

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

// 抽象产品类  
class Product {  
  // 抽象方法  
  use() {  
    throw new Error('Use abstract method "use"');  
  }  
}  
  
// 具体产品类1  
class ConcreteProduct1 extends Product {  
  use() {  
    console.log('使用具体产品1');  
  }  
}  
  
// 具体产品类2  
class ConcreteProduct2 extends Product {  
  use() {  
    console.log('使用具体产品2');  
  }  
}  
  
// 抽象工厂类  
class Factory {  
  // 工厂方法,由子类实现具体的创建逻辑  
  createProduct() {  
    throw new Error('Use abstract method "createProduct"');  
  }  
}  
  
// 具体工厂类1  
class ConcreteFactory1 extends Factory {  
  createProduct() {  
    return new ConcreteProduct1();  
  }  
}  
  
// 具体工厂类2  
class ConcreteFactory2 extends Factory {  
  createProduct() {  
    return new ConcreteProduct2();  
  }  
}  
  
// Client代码  
class Client {  
  constructor(factory) {  
    this.factory = factory;  
  }  
  
  useProduct() {  
    let product = this.factory.createProduct();  
    product.use();  
  }  
}  
  
// 使用Client类和ConcreteFactory1实例化一个新的Client对象并使用产品  
let client1 = new Client(new ConcreteFactory1());  
client1.useProduct();

四、C++工厂方法模式

以下是在C++中实现工厂方法模式:

//定义一个抽象产品类,它包含产品对象的公共接口。
class Product {  
public:  
  virtual void use() = 0; // 纯虚函数,具体实现由子类来决定  
};
//创建具体产品类,它们扩展了抽象产品类并实现了产品的具体行为。
class ConcreteProduct1 : public Product {  
public:  
  void use() override {  
    // 具体实现逻辑  
    std::cout << "使用具体产品1" << std::endl;  
  }  
};  
  
class ConcreteProduct2 : public Product {  
public:  
  void use() override {  
    // 具体实现逻辑  
    std::cout << "使用具体产品2" << std::endl;  
  }  
};
//定义一个抽象工厂类,它包含一个工厂方法用于创建产品对象。这个方法是纯虚函数,具体实现由子类来决定。
class Factory {  
public:  
  virtual Product* createProduct() = 0; // 纯虚函数,具体实现由子类来决定  
};
//创建具体工厂类,它们扩展了抽象工厂类并实现了工厂方法的特定实现,以创建特定类型的产品对象。
class ConcreteFactory1 : public Factory {  
public:  
  Product* createProduct() override {  
    return new ConcreteProduct1();  
  }  
};  
  
class ConcreteFactory2 : public Factory {  
public:  
  Product* createProduct() override {  
    return new ConcreteProduct2();  
  }  
};
//最后,在客户端代码中使用工厂方法模式来创建产品对象。客户端通过调用工厂对象的 createProduct 方法来创建产品对象,而不需要直接了解如何创建这些对象。这样可以提高客户端代码的灵活性和可维护性。
int main() {  
  Factory* factory = new ConcreteFactory1(); // 创建具体工厂对象  
  Product* product = factory->createProduct(); // 创建具体产品对象  
  product->use(); // 使用具体产品对象  
  
  delete factory; // 释放工厂对象内存  
  delete product; // 释放产品对象内存  
  
  return 0;  
}

五、python工厂方法模式

以下是在python中实现工厂方法模式:

from abc import ABCMeta, abstractmethod  
  
# 抽象产品类  
class Product(metaclass=ABCMeta):  
    @abstractmethod  
    def operation(self):  
        pass  
  
# 具体产品类1  
class ConcreteProduct1(Product):  
    def operation(self):  
        print("具体产品1被使用了")  
  
# 具体产品类2  
class ConcreteProduct2(Product):  
    def operation(self):  
        print("具体产品2被使用了")  
  
# 抽象工厂类  
class Factory(metaclass=ABCMeta):  
    @abstractmethod  
    def create_product(self):  
        pass  
  
# 具体工厂类1  
class ConcreteFactory1(Factory):  
    def create_product(self):  
        return ConcreteProduct1()  
  
# 具体工厂类2  
class ConcreteFactory2(Factory):  
    def create_product(self):  
        return ConcreteProduct2()  
  
# Client代码  
if __name__ == "__main__":  
    factory1 = ConcreteFactory1()  
    product1 = factory1.create_product()  
    product1.operation()  
  
    factory2 = ConcreteFactory2()  
    product2 = factory2.create_product()  
    product2.operation()

    

六、go工厂方法模式

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

//首先定义一个产品接口,该接口定义了产品的通用方法:
type Product interface {  
 Use()  
}
//然后,定义两个具体产品结构体,并实现Product接口的方法:
type ConcreteProduct1 struct{}  
  
func (p *ConcreteProduct1) Use() {  
 fmt.Println("使用具体产品1")  
}  
  
type ConcreteProduct2 struct{}  
  
func (p *ConcreteProduct2) Use() {  
 fmt.Println("使用具体产品2")  
}
//接下来,定义一个工厂接口,该接口定义了一个创建产品的 方法:
type Factory interface {  
 CreateProduct() Product  
}
//然后,定义两个具体工厂结构体,并实现Factory接口的方法:
type ConcreteFactory1 struct{}  
  
func (f *ConcreteFactory1) CreateProduct() Product {  
 return &ConcreteProduct1{}  
}  
  
type ConcreteFactory2 struct{}  
  
func (f *ConcreteFactory2) CreateProduct() Product {  
 return &ConcreteProduct2{}  
}
//最后,在客户端代码中,根据需要选择具体的工厂结构体实例化,然后使用该工厂结构体创建并使用产品:
func main() {  
 factory1 := &ConcreteFactory1{}  
 product1 := factory1.CreateProduct()  
 product1.Use()  
  
 factory2 := &ConcreteFactory2{}  
 product2 := factory2.CreateProduct()  
 product2.Use()  
}

七、PHP工厂方法模式

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

//定义一个抽象产品接口(Abstract Product):
interface Product {  
    public function operation();  
}
//创建具体产品类实现抽象产品接口:
class ConcreteProduct1 implements Product {  
    public function operation() {  
        echo "具体产品1被使用了";  
    }  
}  
  
class ConcreteProduct2 implements Product {  
    public function operation() {  
        echo "具体产品2被使用了";  
    }  
}
//定义一个抽象工厂类:
abstract class Creator {  
    abstract public function factoryMethod(): Product;  
}
//创建具体工厂类继承抽象工厂类:
class ConcreteCreator1 extends Creator {  
    public function factoryMethod() {  
        return new ConcreteProduct1();  
    }  
}  
  
class ConcreteCreator2 extends Creator {  
    public function factoryMethod() {  
        return new ConcreteProduct2();  
    }  
}
//在客户端代码中,根据需要选择具体的工厂类实例化,并使用该工厂类创建并使用产品:
$creator1 = new ConcreteCreator1();  
$product1 = $creator1->factoryMethod();  
$product1->operation(); // 输出:具体产品1被使用了  
  
$creator2 = new ConcreteCreator2();  
$product2 = $creator2->factoryMethod();  
$product2->operation(); // 输出:具体产品2被使用了

《完结》

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

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

相关文章

Nginx正向代理,反向代理,负载均衡

Nginx正向代理&#xff0c;反向代理&#xff0c;负载均衡 Nginx当中有两种代理方式&#xff1a; 七层代理&#xff08;http协议&#xff09; 四层代理&#xff08;tcp/udp流量转发&#xff09; 七层代理&#xff1a;七层代理&#xff0c;代理的是http的请求和响应 客户端请求…

Redis RDB持久化

前言 我们知道 Redis 之所以快&#xff0c;很大程度是因为它的数据直接放在内存里&#xff0c;而内存是易失性存储器&#xff0c;只有通电才存储数据&#xff0c;断电数据就会丢失。 这个时候就要看你的应用场景了&#xff0c;如果你只是拿 Redis 做关系型数据库的缓存&#x…

SpringBoot实现SSMP整合

一、整合JUnit 1、Spring 整合 JUnit 核心注解有两个&#xff1a; RunWith(SpringJUnit4ClassRunner.class) 是设置Spring专用于测试的类运行器&#xff08;Spring程序执行程序有自己的一套独立的运行程序的方式&#xff0c;不能使用JUnit提供的类运行方式&#xff09;Conte…

Deep Learning(0-14草履虫)

深度学习解决的问题 自动提取出最合适的特征 深度学习应用 神经网络基础 损失函数 前向传播 反向传播 绿色字体为正向传播i输入&#xff0c;红色字体为反向传播梯度 MAX门单元只把梯度传给最大的 神经网络整体架构 激活函数 隐藏层激活函数 一般选择Relu&#xff0c;sigmoid会…

STM32 IWDGWWDG

STM32 IWDG&WWDG 启动看门狗之后&#xff0c;看门狗是不能再被关闭的&#xff0c;除非发生复位。 IWDG独立看门狗 独立看门狗配置流程 开启LSI时钟&#xff0c;只有LSI时钟开启了&#xff0c;独立看门狗才能运行。 但是开启LSI的代码&#xff0c;并不需要我们来写&#xf…

【23种设计模式】装饰器模式

个人主页&#xff1a;金鳞踏雨 个人简介&#xff1a;大家好&#xff0c;我是金鳞&#xff0c;一个初出茅庐的Java小白 目前状况&#xff1a;22届普通本科毕业生&#xff0c;几经波折了&#xff0c;现在任职于一家国内大型知名日化公司&#xff0c;从事Java开发工作 我的博客&am…

WinSCP 集成 putty(也可以其他Terminal客户端)

putty 安装 官网安装地址 WinSCP集成putty&#xff08;也可以其他Terminal客户端&#xff09; 扩展 WinSCP是什么&#xff1f; WinSCP&#xff08;Windows Secure Copy Protocol&#xff09;是一个用于 Windows 操作系统的开源的 SFTP&#xff08;SSH File Transfer Protoc…

【Unity HDRP渲染管线下的WorleyUtilities文件,“Hash”函数】

Unity HDRP内置文件WorleyUtilities WorleyUtilities文件路径如下:文件代码如下然后转译到ShaderLab中:存档:WorleyUtilities文件路径如下: D:…\Library\PackageCache\com.unity.render-pipelines.high-definition@14.0.8\Runtime\Lighting\VolumetricClouds\WorleyUtili…

网络解析(二)

ICMP 报文有很多的类型,不同的类型有不同的代码。最常用的类型是主动请求为 8,主动请求的应答为 0。 ICMP 相当于网络世界的侦察兵。我讲了两种类型的 ICMP 报文,一种是主动探查的查询报文,一种异常报告的差错报文; ping 使用查询报文,Traceroute 使用差错报文。 IP和…

C++ 用户学习 Python 的最佳方法

对于很多是一名计算机科学专业的学生而言&#xff0c;很多入门是学习的C和 C&#xff0c;可能熟悉非常基本的 python 语法&#xff0c;以及 C 中相当高级的数据结构。现在想深入学习Python的话&#xff0c;光看很多在线教程可能没法有较大的提升&#xff0c;这里有一些针对C用户…

信息系统项目管理师第四版学习笔记——组织通用治理

组织战略 组织战略是组织高质量发展的总体谋略&#xff0c;是组织相关干系方就其发展达成一致认识的重要基础。组织战略是指组织针对其发展进行的全局性、长远性、纲领性目标的策划和选择。 战略目标是组织在一定的战略期内总体发展的总水平和总任务。它决定了组织在该战略期…

CodePlan

CodePlan论文解读 最近在看老师给的LLM-Agent论文&#xff0c;在这记录一下 CodePlan: Repository-level Coding using LLMs and Planning【论文】 旨在解决储存库级别的coding task&#xff0c;提出一个框架called CodePlan综合多步骤的编辑链&#xff0c;其中每个步骤都导…

华为---PPP协议简介及示例配置

PPP协议简介 PPP是Point-to-Point Protocol的简称&#xff0c;中文翻译为点到点协议。与以太网协议一样,PPP也是一个数据链路层协议。以太网协议定义了以太帧的格式&#xff0c;PPP协议也定义了自己的帧格式&#xff0c;这种格式的帧称为PPP帧。 利用PPP协议建立的二层网络称为…

云耀服务器L实例部署Typecho开源博客系统|华为云云耀云服务器L实例评测使用体验

云耀服务器L实例部署Typecho开源博客系统 文章目录 云耀服务器L实例部署Typecho开源博客系统1. 华为云云耀服务器L实例介绍2. Typecho2.1 Typecho 3. 部署华为云云耀服务器L实例3.1 云耀服务器L实例购买3.1.1 云耀服务器L实例初始化配置3.1.2 远程登录云耀服务器L实例 4. Typec…

基于MATLAB的图像条形码识别系统(matlab毕毕业设计2)

摘要 &#xff1a; 本论文旨在介绍一种基于MATLAB的图像条形码识别系统。该系统利用计算机视觉技术和图像处理算法&#xff0c;实现对不同类型的条形码进行准确识别。本文将详细介绍系统学习的流程&#xff0c;并提供详细教案&#xff0c;以帮助读者理解和实施该系统。 引言…

Git构建分布式版本控制系统

一、版本控制 1、概念&#xff1a; 版本控制&#xff08;Version Control&#xff09;&#xff0c;也被称为版本管理、源代码管理或代码控制&#xff0c;是一种系统和工具&#xff0c;用于跟踪和管理文件、数据或源代码的不同版本和历史记录&#xff0c;在软件开发、文档管理…

深入理解Huffman编码:原理、代码示例与应用

目录 ​编辑 介绍 Huffman编码的原理 信息理论背景 频率统计 Huffman树 Huffman编码的代码示例 数据结构 权重选择 Huffman编码生成 完整示例 完整代码 测试截图 Huffman编码的应用 总结 介绍 在这个数字时代&#xff0c;数据的有效压缩和传输变得至关重要。Hu…

【Linux】Ubunt20.04在vscode中使用Fira Code字体【教程】

【Linux】Ubunt20.04在vscode中使用Fira Code字体【教程】 文章目录 【Linux】Ubunt20.04在vscode中使用Fira Code字体【教程】1. 什么是Fira Code字体2. 安装Fira Code字体3. 配置vscodeReference 1. 什么是Fira Code字体 Fira Code&#xff1a;是一种带有编程连字的等宽字体。…

多组试验时正态分布标准差估计公式

本文介绍如何通过多组试验数据来估计正态总体的标准差. 一,各组试验次数相等 设正态总体X&#xff5e;N(μ,σ),其中均值μ和标准差σ未知.今有m组样本,每组样本大小n相等,其试验数据如下:求标准差σ的估计σ. 多组试验时正态分布标准差估计公式 - 百度学术

机器人制作开源方案 | 行星探测车概述

1. 功能描述 行星探测车&#xff08;Planetary Rover&#xff09;是一种用于进行科学探索和勘测任务的无人车辆&#xff0c;它们被设计成能够适应各种复杂的地形条件和极端环境&#xff0c;以便收集数据、拍摄照片、采集样本等。行星探测车通常包含以下主要组件和功能&#xff…