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

news2025/2/25 14:09:38

简介:

简单工厂模式,它提供了一个用于创建对象的接口,但具体创建的对象类型可以在运行时决定。这种模式通常用于创建具有共同接口的对象,并且可以根据客户端代码中的参数或配置来选择要创建的具体对象类型。
在简单工厂模式中,有一个专门的类负责创建其他类的实例,这个类称为工厂类。被创建的实例通常都具有共同的父类。工厂类中有一个用于创建对象的静态工厂方法,系统可以根据该方法所传入的参数来动态决定应该创建出哪一个产品类的实例。
以汽车生产为例,简单工厂模式可以模拟该生产过程。我们将汽车抽象为一个产品接口,不同品牌的汽车则具体实现该接口并提供各自的功能。工厂类负责根据传入的品牌参数来创建相应的汽车对象。


以下是简单工厂模式的步骤:
1、定义产品接口:首先定义一个产品接口,例如“汽车”,它包含一些公共的方法,如“启动”、“刹车”等。
2、实现具体产品类:针对不同的品牌,创建具体的实现类来实现产品接口。例如,“奔驰”和“宝马”都实现了“汽车”接口,并提供了各自特有的功能。
3、创建工厂类:创建一个工厂类,它包含一个静态工厂方法,用于根据传入的品牌参数来创建相应的汽车对象。例如,在“奔驰”工厂中,我们创建了一个静态方法“createCar”,它根据传入的品牌来实例化相应的汽车对象。
4、使用工厂类创建产品对象:客户端代码直接调用工厂类的静态工厂方法来创建需要的汽车对象,而无需关心具体的品牌和创建细节。例如,我们调用“奔驰”工厂的“createCar”方法,并传入型号参数“E-260-L”,即可得到一个奔驰E260L对象。
简单工厂模式的优点:它能将对象的创建和对象本身业务处理分离,降低系统的耦合度,使得两者修改起来都相对容易。同时,由于工厂方法是静态方法,使用起来很方便,只需通过工厂类类名直接调用即可,无需了解对象的创建细节。它可以在不修改客户端代码的情况下扩展新的产品类型,因为新产品只需实现抽象产品接口,并在工厂类中添加相应的创建逻辑即可。而不需要修改其它已经存在的代码,这样就保持了良好的封装性。
简单工厂模式的缺点:如果Shape类型的数量很多,那么ShapeFactory类就会变得很庞大,而且所有创建对象的逻辑都集中在一个类中,破坏了代码的模块化,破坏了“开闭原则”。

示例:

一、C#简单工厂模式

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

// 接口  
public interface Shape  
{  
    void Draw();  
}  
  
// 实现接口的实体类  
public class Circle : Shape  
{  
    public void Draw()  
    {  
        Console.WriteLine("绘制一个圆形");  
    }  
}  
  
public class Rectangle : Shape  
{  
    public void Draw()  
    {  
        Console.WriteLine("绘制一个矩形");  
    }  
}  
  
// 工厂类,创建实体类的对象  
public class ShapeFactory  
{  
    // 通过GetShape方法来根据传入的字符串来返回相应的Shape类型的对象  
    public Shape GetShape(string type)  
    {  
        if (type == "Circle")  
        {  
            return new Circle();  
        }  
        else if (type == "Rectangle")  
        {  
            return new Rectangle();  
        }  
        else  
        {  
            throw new ArgumentException("无效的图形类型");  
        }  
    }  
}
//使用这个工厂,你可以在运行时决定创建哪种类型的 Shape。例如:
class FactoryPatternDemo
{
    static void Main(string[] args)
    {
        ShapeFactory shapeFactory = new ShapeFactory();  
        Shape shape1 = shapeFactory.GetShape("Circle");  
        shape1.Draw();  // 输出"绘制一个圆形"  
        Shape shape2 = shapeFactory.GetShape("Rectangle");  
        shape2.Draw();  // 输出"绘制一个矩形"  
    }  
}

二、java简单工厂模式

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

// 接口  
public interface Shape {  
    void draw();  
}  
// 实现接口的实体类  
public class Circle implements Shape {  
    @Override  
    public void draw() {  
        System.out.println("绘制一个圆形");  
    }  
}  
  
public class Rectangle implements Shape {  
    @Override  
    public void draw() {  
        System.out.println("绘制一个矩形");  
    }  
}
// 工厂类,创建实体类的对象 
public class ShapeFactory {  
    // 通过getShape方法来根据传入的字符串来返回相应的Shape类型的对象  
    public Shape getShape(String type) {  
        if (type.equalsIgnoreCase("CIRCLE")) {  
            return new Circle();  
        } else if (type.equalsIgnoreCase("RECTANGLE")) {  
            return new Rectangle();  
        } else {  
            throw new IllegalArgumentException("无效的形状类型");  
        }  
    }  
}
//然后我们就可以这样使用这个工厂类创建Shape对象:
public class FactoryPatternDemo {  
    public static void main(String[] args) {  
        ShapeFactory shapeFactory = new ShapeFactory();  
        Shape shape1 = shapeFactory.getShape("CIRCLE");  
        shape1.draw();  // 输出"绘制一个圆形"  
        Shape shape2 = shapeFactory.getShape("RECTANGLE");  
        shape2.draw();  // 输出"绘制一个矩形"  
    }  
}


三、javascript简单工厂模式

在JavaScript 中,它使用一个共同的接口来实例化不同类型的对象,而无需直接使用具体类。在工厂模式中,您可以创建一个工厂类来负责创建对象,而无需暴露创建逻辑。
以下是一个示例,展示了如何在JavaScript中实现简单工厂模式:

// Car 接口  
class Car {  
  constructor(name) {  
    this.name = name;  
  }  
  
  start() {  
    console.log(this.name + ' started');  
  }  
  
  stop() {  
    console.log(this.name + ' stopped');  
  }  
}  
  
// CarFactory 工厂类  
class CarFactory {  
  constructor() {  
    this.cars = {};  
  }  
  
  // 创建轿车对象  
  createCar(name, type='Sedan') {  
    if (!this.cars[type]) {  
      this.cars[type] = new Car(type);  
    }  
    return this.cars[type];  
  }  
  
  // 创建卡车对象  
  createTruck(name, type='Pickup') {  
    if (!this.cars[type]) {  
      this.cars[type] = new Car(type);  
    }  
    return this.cars[type];  
  }  
}
//接下来,我们使用 CarFactory 工厂类来制造不同类型的汽车:
// 创建 CarFactory 实例  
const carFactory = new CarFactory();  
  
// 制造轿车  
const sedan = carFactory.createCar('Alice', 'Sedan');  
sedan.start(); // 输出 "Sedan started"  
sedan.stop(); // 输出 "Sedan stopped"  
  
// 制造卡车  
const truck = carFactory.createCar('Bob', 'Truck');  
truck.start(); // 输出 "Pickup started"  
truck.stop(); // 输出 "Pickup stopped"

四、C++简单工厂模式

在C++中,可以通过以下步骤来实现简单工厂模式:
1、定义一个抽象基类(或接口),其中包含所有派生类的公共方法。这个抽象基类可以看作是工厂的公共接口,它不知道具体对象的类型。
2、创建多个派生类,这些派生类实现了抽象基类中的所有公共方法,每个派生类具有不同的状态和行为。
3、创建一个工厂类,它包含一个用于创建对象的纯虚函数。这个纯虚函数根据传入的参数类型来创建相应的派生类对象,并返回该对象的指针。
4、在客户端代码中,通过调用工厂类的纯虚函数来创建对象。由于客户端代码不知道具体对象的类型,因此可以使用抽象基类的指针来操作这些对象。
以下是一个示例,展示了如何在C++中实现简单工厂模式:

#include <iostream>  
  
// 抽象基类  
class Shape {  
public:  
    virtual void draw() = 0;  
};  
  
// 圆形派生类  
class Circle : public Shape {  
public:  
    void draw() override {  
        std::cout << "绘制圆形" << std::endl;  
    }  
};  
  
// 矩形派生类  
class Rectangle : public Shape {  
public:  
    void draw() override {  
        std::cout << "绘制矩形" << std::endl;  
    }  
};  
  
// 工厂类  
class ShapeFactory {  
public:  
    // 根据传入的参数类型来创建相应的对象,并返回该对象的指针  
    static Shape* createShape(const std::string& type) {  
        if (type == "Circle") {  
            return new Circle();  
        } else if (type == "Rectangle") {  
            return new Rectangle();  
        } else {  
            throw std::invalid_argument("无效的形状类型");  
        }  
    }  
};  
  
int main() {  
    // 创建圆形对象  
    Shape* circle = ShapeFactory::createShape("Circle");  
    circle->draw(); // 输出"绘制圆形"  
    delete circle;  
  
    // 创建矩形对象  
    Shape* rectangle = ShapeFactory::createShape("Rectangle");  
    rectangle->draw(); // 输出"绘制矩形"  
    delete rectangle;  
  
    return 0;  
}

五、python简单工厂模式

在Python中,工厂模式通常是通过函数或类来创建其他类的实例。简单工厂模式是一种常见的工厂模式,它通过一个单独的工厂类来创建产品对象,这个工厂类一般用来创建与环境有关的具体产品。
下面是一个Python中简单工厂模式的例子:

class Product(object):  
    def operation(self):  
        pass  
  
class ConcreteProduct1(Product):  
    def operation(self):  
        return "ConcreteProduct1 operation"  
  
class ConcreteProduct2(Product):  
    def operation(self):  
        return "ConcreteProduct2 operation"  
  
class Factory:  
    @staticmethod  
    def create_product(product_type):  
        if product_type == "type1":  
            return ConcreteProduct1()  
        elif product_type == "type2":  
            return ConcreteProduct2()  
        else:  
            return None  
  
def client_code(factory=Factory):  
    product = factory.create_product("type1")  
    print(product.operation())  
  
if __name__ == "__main__":  
    client_code()

    
六、Go简单工厂模式

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

// 抽象产品接口  
interface Product {  
    void use();  
}  
  
// 具体产品类1  
class ConcreteProduct1 implements Product {  
    public void use() {  
        System.out.println("使用具体产品1");  
    }  
}  
  
// 具体产品类2  
class ConcreteProduct2 implements Product {  
    public void use() {  
        System.out.println("使用具体产品2");  
    }  
}  
  
// 工厂类  
class Factory {  
    public Product createProduct(String type) {  
        if (type.equals("product1")) {  
            return new ConcreteProduct1();  
        } else if (type.equals("product2")) {  
            return new ConcreteProduct2();  
        } else {  
            throw new IllegalArgumentException("无效的产品类型");  
        }  
    }  
}  
  
// 客户端代码  
public class Client {  
    public static void main(String[] args) {  
        Factory factory = new Factory();  
        Product product1 = factory.createProduct("product1");  
        product1.use(); // 输出:使用具体产品1  
        Product product2 = factory.createProduct("product2");  
        product2.use(); // 输出:使用具体产品2  
    }  
}


七、PHP简单工厂模式

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

<?php  
  
// 产品接口  
interface Product {  
    public function useProduct();  
}  
  
// 具体产品类 1  
class ConcreteProduct1 implements Product {  
    public function useProduct() {  
        echo "使用具体产品1\n";  
    }  
}  
  
// 具体产品类 2  
class ConcreteProduct2 implements Product {  
    public function useProduct() {  
        echo "使用具体产品2\n";  
    }  
}  
  
// 工厂类  
class Factory {  
    public static function createProduct($type) {  
        if ($type === 'product1') {  
            return new ConcreteProduct1();  
        } elseif ($type === 'product2') {  
            return new ConcreteProduct2();  
        } else {  
            throw new Exception('无效的产品类型');  
        }  
    }  
}  
  
// 客户端代码  
function clientCode() {  
    $product1 = Factory::createProduct('product1');  
    $product1->useProduct(); // 输出:使用具体产品1  
  
    $product2 = Factory::createProduct('product2');  
    $product2->useProduct(); // 输出:使用具体产品2  
}  
  
// 调用客户端代码  
clientCode();  
?>

《完结》

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

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

相关文章

DVWA靶场Medium难度部分解析

前言 好久没做题&#xff0c;不想吹牛逼了&#xff0c;消停做点题QAQ Vulnerability: Command Injection 这题不咋难&#xff0c;老Ping题了 输个分号ls试试&#xff0c;没回显即被Ban了&#xff0c;试试别的&#xff0c;例如|或者&& 出了&#xff0c;看看源代码 把…

6.认识Java的API 使用Java函数库

2.1 分析bug SimpleDotCom类中的checkYourself()方法中的for循环有问题 每当玩家猜中某一格时&#xff0c;就将计数器加数&#xff0c;而不管之前是否就已经被猜中。需要一种机制来判别之前是否已经被猜中。 虚拟的行占有7个各自&#xff0c;而DotCom会占有其中连续的3格。下…

win10桌面便签小工具,安全无广告下载哪一款

很多人在日常生活中都有忘记处理事务的情况&#xff0c;偶然的一次两次可能自己就在当时懊恼一下&#xff0c;但是次数多了以后或者是涉及到处理重要的工作任务时&#xff0c;就会给大家带来心里负担及压力。 为避免大家在日常工作中忘记重要的事情&#xff0c;大家可以选择在…

el-table添加fixed属性后底部滚动条添加小手

0 效果 1 样式 /deep/ .el-table--scrollable-x {cursor: pointer; } /deep/ .el-table__empty-block {cursor: auto; } /deep/ .el-table__row {cursor: auto; }

3-k8s-镜像仓库harbor搭建

文章目录 一、概念二、安装harbor三、使用harbor仓库 一、概念 官方概念&#xff1a;Harbor是一个用于存储和分发Docker镜像的企业级Registry服务器。 我们平时拉去镜像都是从线上仓库拉去&#xff0c;但是企业内部的镜像一般都不会随意传到网上&#xff0c;而是保存在自己公…

Halo-Theme-Hao文档:如何设置导航栏?

本篇文章会教你如何配置导航栏&#xff0c;最终效果参考如下。 感谢 Lanbin、小孙同学 等同学的贡献&#xff08;语雀参与编辑&#xff09;。 1标题 进入站点后台 点击左侧面板中的 主题 点击上方的 导航 修改 标题字段即可 2主菜单 主菜单即网站导航栏中间部分的菜单 进入站点…

ChatGPT AIGC 实现多条件求和函数案例

从明细数据中,按多条件进行求和是职场办公应用活动经常要完成的事情。 像这样的需要我们完全可以不用自己动手去查相关函数的应用,让ChatGPT来完成就可以了。 Prompt:有一个Excel表格B3至B483为年份,C3至C483为商品名称,E3至E483为省份,F3至F483为销售额,请写出Excel函…

解惑Android Scoped Storage

原文链接 Android Scoped Storage Puzzles 安卓对于文件存储这块&#xff0c;其实是相当混乱的&#xff0c;在早期的版本中对存储甚至是没有所谓的管理的&#xff0c;有多种方法可以操作文件存储&#xff0c;比如通过Java原生的方式(File/InputStream/OutputStream)&#xff0…

C++算法:前缀和、前缀乘积、前缀异或的原理、源码及测试用例

相关 源码测试用例下载 https://download.csdn.net/download/he_zhidan/88430716 包括4个压缩包&#xff0c;初始代码&#xff0c;实现前缀和&#xff0c;实现前缀积&#xff0c;实现前缀异或。都是在前者的基础上修改的。 本博文是CSDN学院课程的讲义 https://edu.csdn.net/c…

记录--P0事故预警

这里给大家分享我在网上总结出来的一些知识&#xff0c;希望对大家有所帮助 背景 某一天&#xff0c;前端小余同学和后端别问我小哥在做登录业务接口对接&#xff0c;出于业务的特殊性和安全性的考虑&#xff0c;她和后端小哥约定“user”相关信息参数需要通过HTTP协议的header…

Elastic Stack 和 Docker Compose 入门:第 2 部分

作者&#xff1a;Eddie Mitchell 欢迎阅读 Elastic Stack 和 Docker Compose 入门的第二部分。 在第一部分博客中&#xff0c;我们了解了 Docker Compose 的基础知识以及如何将单节点集群建立为本地游乐场&#xff0c;其中包括 Elasticsearch、Kibana、Logstash、Metricbeat 和…

JVS-rules规则引擎,解决大数据风控的自动化决策利器

规则引擎中的评分卡节点是一种用于评估客户信用、风险等级或其他指标的重要工具。它通常用于金融、信贷等领域&#xff0c;以便根据一系列预定义的规则和权重来对客户进行评分。以下是评分卡节点的主要功能、作用以及配置方式的介绍&#xff1a; 功能和作用&#xff1a; 评估…

BUUCTF学习(5): 命令执行Ping

1、介绍 2、解题 127.0.0.1|cat /flag 结束

第三章 交换技术及应用

3.1 port-vlan技术 3.1.1 VLAN概述 VLAN(Virtual Local Area Network)&#xff0c;虚拟局域网VLAN是在一个已建好的物理网络上划分出来的逻辑网络。作用&#xff1a;隔离广播域&#xff0c;同一个VLAN主机可以通信而不同VLAN不能通信。 3.1.2 VLAN划分方法——Port-VLAN 基于端…

ArcGIS笔记7_如何创建新的shp要素文件?新shp的坐标系选择?

本文目录 前言Step 1 创建新的shp要素文件的操作Step 2 常用的坐标系选择Step 3 有点笨但好用的新建shp要素的方法 前言 很多ArcGIS新手都会遇到的问题&#xff0c;会编辑现成的shp要素文件&#xff0c;但不会创建新shp&#xff0c;而且创建时需要选择新的坐标系&#xff0c;这…

OpenSIPS 防扫描处理

文章目录 1. 问题背景2. 防范处理2.1 IP 封禁2.2 OpenSIPS 处理2.2.1 REGISTER 请求2.2.2 INVITE 请求 1. 问题背景 OpenSIPS 作为 SIP 注册服务器&#xff0c;通常需要放在公网供公司各地的员工使用&#xff0c;但是这样就会产生外部扫描问题。一般来说外部扫描量不会很大&am…

ElasticSearch-数据查询

ElasticSearch-数据查询 目录概述需求&#xff1a; 设计思路实现思路分析1.查询某索引下的所有数据2.二、条件查询3.、条件查询方式二4.四、分页查询5.五、格式化数据 六、排序七 其他条件执行的成立的查询九、范围查询 参考资料和推荐阅读 Survive by day and develop by nigh…

13-k8s-ingress网络

文章目录 一、ingress介绍二、创建nginx和tomcat供测试三、创建ingress-http四、yaml方式安装ingress五、helm方式安装ingress&#xff08;推荐&#xff09;六、Ingress的HTTPS代理 一、ingress介绍 Service对集群之外暴露服务的主要方式有两种&#xff1a;NotePort和LoadBalan…

强化学习基础(2)—常用算法总结

目录 1.Value-Based 2. Policy-Based 参考文献 1.Value-Based Sarsa&#xff08;State-action-reward-state’-action&#xff09;&#xff1a;是为了建立和优化状态-动作(state-action)的价值Q表格所建立的方法。首先初始化Q表格&#xff0c;根据当前的状态和动作与环境进行…

Mapping 设计指南

Mapping 设计指南 目录概述需求&#xff1a; 设计思路实现思路分析1、properties2.fields 3.search_analyzer4.2、format1、enabled2、doc_values 参考资料和推荐阅读 Survive by day and develop by night. talk for import biz , show your perfect code,full busy&#xff0…