C# 设计模式(创建型模式):工厂模式

C# 设计模式(创建型模式):工厂模式

引言

在软件设计中,创建型模式是用来创建对象的设计模式,它们帮助我们将对象的创建过程从业务逻辑中分离出来,减少代码的重复性和耦合度。工厂模式作为创建型设计模式之一,它通过提供一个创建对象的接口来避免直接实例化具体类,从而增强了代码的灵活性和可维护性。

在本文中,我们将深入探讨工厂模式的概念、类型及其在C#中的应用。


1. 工厂模式概述

工厂模式(Factory Pattern)提供了一个创建对象的接口,但将实际的对象创建推迟到子类中。这种模式的核心思想是定义一个用于创建对象的接口,但让子类决定实例化哪一个类。工厂模式主要目的是将对象的创建与使用分离,从而提高系统的灵活性和可扩展性。


2. 工厂模式的种类

工厂模式可以分为以下几种类型:

  1. 简单工厂模式(Simple Factory Pattern)
  2. 工厂方法模式(Factory Method Pattern)
  3. 抽象工厂模式(Abstract Factory Pattern)

接下来,我们将分别介绍这几种工厂模式。


3. 简单工厂模式

定义:

简单工厂模式通过一个工厂类根据传入的参数决定实例化哪个类。该模式将对象的创建逻辑集中到一个工厂类中,客户端只需要请求工厂创建对象,而无需关心具体的创建过程。

代码示例:
// 产品接口
public interface IProduct
{void GetInfo();
}// 具体产品A
public class ProductA : IProduct
{public void GetInfo(){Console.WriteLine("This is Product A.");}
}// 具体产品B
public class ProductB : IProduct
{public void GetInfo(){Console.WriteLine("This is Product B.");}
}// 工厂类
public class ProductFactory
{public static IProduct CreateProduct(string productType){if (productType == "A"){return new ProductA();}else if (productType == "B"){return new ProductB();}else{throw new ArgumentException("Invalid product type.");}}
}
使用示例:
class Program
{static void Main(string[] args){IProduct productA = ProductFactory.CreateProduct("A");productA.GetInfo();  // 输出:This is Product A.IProduct productB = ProductFactory.CreateProduct("B");productB.GetInfo();  // 输出:This is Product B.}
}
优点:
  • 简化客户端代码:客户端只需调用工厂方法,而不需要关心具体产品的创建过程。
  • 集中管理:对象的创建逻辑集中在工厂类中,易于维护和扩展。
缺点:
  • 不符合开闭原则:每次新增产品时,都需要修改工厂类的代码,这违反了开闭原则。

4. 工厂方法模式

定义:

工厂方法模式允许子类决定实例化哪一个类。与简单工厂模式不同的是,工厂方法模式是将对象的创建推迟到具体的子类中,每个子类实现一个工厂方法,来创建相应的产品对象。

代码示例:
// 产品接口
public interface IProduct
{void GetInfo();
}// 具体产品A
public class ProductA : IProduct
{public void GetInfo(){Console.WriteLine("This is Product A.");}
}// 具体产品B
public class ProductB : IProduct
{public void GetInfo(){Console.WriteLine("This is Product B.");}
}// 工厂接口
public interface IProductFactory
{IProduct CreateProduct();
}// 具体工厂A
public class ProductAFactory : IProductFactory
{public IProduct CreateProduct(){return new ProductA();}
}// 具体工厂B
public class ProductBFactory : IProductFactory
{public IProduct CreateProduct(){return new ProductB();}
}
使用示例:
class Program
{static void Main(string[] args){IProductFactory factoryA = new ProductAFactory();IProduct productA = factoryA.CreateProduct();productA.GetInfo();  // 输出:This is Product A.IProductFactory factoryB = new ProductBFactory();IProduct productB = factoryB.CreateProduct();productB.GetInfo();  // 输出:This is Product B.}
}
优点:
  • 符合开闭原则:新增产品时,只需要新增工厂类,而不需要修改现有代码。
  • 增强了灵活性:每个工厂负责创建不同的产品,方便扩展。
缺点:
  • 增加了类的数量:每增加一个产品就需要创建一个新的工厂类。

5. 抽象工厂模式

定义:

抽象工厂模式是工厂模式的扩展,它提供了一个创建一系列相关或互相依赖的对象的接口,而无需指定具体类。抽象工厂模式通过一组工厂方法来创建不同种类的产品,适用于产品家族的创建。

代码示例:
// 产品A接口
public interface IProductA
{void GetInfo();
}// 产品B接口
public interface IProductB
{void GetInfo();
}// 具体产品A
public class ProductA1 : IProductA
{public void GetInfo() { Console.WriteLine("This is Product A1."); }
}public class ProductA2 : IProductA
{public void GetInfo() { Console.WriteLine("This is Product A2."); }
}// 具体产品B
public class ProductB1 : IProductB
{public void GetInfo() { Console.WriteLine("This is Product B1."); }
}public class ProductB2 : IProductB
{public void GetInfo() { Console.WriteLine("This is Product B2."); }
}// 抽象工厂
public interface IAbstractFactory
{IProductA CreateProductA();IProductB CreateProductB();
}// 具体工厂1
public class ConcreteFactory1 : IAbstractFactory
{public IProductA CreateProductA() { return new ProductA1(); }public IProductB CreateProductB() { return new ProductB1(); }
}// 具体工厂2
public class ConcreteFactory2 : IAbstractFactory
{public IProductA CreateProductA() { return new ProductA2(); }public IProductB CreateProductB() { return new ProductB2(); }
}
使用示例:
class Program
{static void Main(string[] args){IAbstractFactory factory1 = new ConcreteFactory1();IProductA productA1 = factory1.CreateProductA();IProductB productB1 = factory1.CreateProductB();productA1.GetInfo();  // 输出:This is Product A1.productB1.GetInfo();  // 输出:This is Product B1.IAbstractFactory factory2 = new ConcreteFactory2();IProductA productA2 = factory2.CreateProductA();IProductB productB2 = factory2.CreateProductB();productA2.GetInfo();  // 输出:This is Product A2.productB2.GetInfo();  // 输出:This is Product B2.}
}
优点:
  • 提供一站式创建:抽象工厂模式允许创建一系列相关的产品,符合用户的需求。
  • 便于产品家族的管理:通过一系列工厂类,可以确保产品的一致性和完整性。
缺点:
  • 增加了类的复杂度:每增加一种产品,都会增加新的工厂类,导致系统类的数量增加。

6. 总结

工厂模式是创建型设计模式中的重要一环,通过工厂方法,它使得对象的创建与业务逻辑解耦,从而提高了代码的可维护性和可扩展性。C#中的工厂模式根据需求的不同,提供了简单工厂、工厂方法和抽象工厂三种常见的实现方式。在实际开发中,选择合适的工厂模式可以帮助我们更好地管理对象的创建,提升代码的灵活性。


希望这篇博客能帮助你理解C#中的工厂模式及其在实际开发中的应用。如果你有任何问题或建议,欢迎在评论区讨论!


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

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

相关文章

智能水文:ChatGPT等大语言模型如何提升水资源分析和模型优化的效率

大语言模型与水文水资源领域的融合具有多种具体应用,以下是一些主要的应用实例: 1、时间序列水文数据自动化处理及机器学习模型: ●自动分析流量或降雨量的异常值 ●参数估计,例如PIII型曲线的参数 ●自动分析降雨频率及重现期 ●…

Android SPRD 工模测试修改

设备有两颗led灯,工模测试需全亮 vendor/sprd/proprietories-source/factorytest/testitem/led.cpp -13,6 13,10 typedef enum{#define LED_BLUE "/sys/class/leds/blue/brightness"#define LED_RED …

nodeJS下npm和yarn的关系和区别详解

一、命令对应关系 1. 初始化项目 操作npm 命令Yarn 命令初始化项目npm inityarn init跳过提问快速初始化npm init -yyarn init -y 2. 安装依赖 操作npm 命令Yarn 命令安装项目所有依赖npm installyarn install添加依赖npm install <package-name>yarn add <package…

C# 设计模式:装饰器模式与代理模式的区别

C# 设计模式&#xff1a;装饰器模式与代理模式的区别 在软件设计中&#xff0c;装饰器模式&#xff08;Decorator Pattern&#xff09;和代理模式&#xff08;Proxy Pattern&#xff09;都是结构型设计模式&#xff0c;它们的目的都是通过对对象进行包装&#xff0c;来增加或改…

ES中查询中参数的解析

目录 query中参数match参数match_allmatch:匹配指定参数match_phrase query中其他的参数query_stringprefix前缀查询:wildcard通配符查询:range范围查询&#xff1a;fuzzy 查询: 组合查询bool参数mustmust_notshould条件 其他参数 query中参数 词条查询term:它仅匹配在给定字段…

纵览!报表控件 Stimulsoft Reports、Dashboards 和 Forms 2025.1 新版本发布!

Stimulsoft 2025.1 新版发布&#xff0c;旨在增强您创建报告、仪表板和 PDF 表单的体验&#xff01;此最新版本为您带来了许多改进和新功能&#xff0c;使数据处理更加高效和用户友好。亮点包括对 .NET 9 的支持、Microsoft Analysis Services 的新数据适配器、发布向导中适用于…

慧集通iPaaS集成平台低代码训练-实践篇

练习使用帐号信息&#xff1a; 1.致远A8平台&#xff08;请自行准备测试环境&#xff09; 慧集通连接器配置相关信息 访问地址&#xff1a; rest账号&#xff1a;rest rest密码&#xff1a; OA账号&#xff1a; 2.云星空&#xff08;请自行准备测试环境&#xff09; 连接…

Unity Pico 应用失去焦点后,追踪功能被禁用(原生 UI 界面弹出)

在 Unity 中&#xff0c;如果正在使用新的输入系统&#xff0c;任何触发 OnApplicationFocus(false) 的事件都可能会禁用追踪功能。 负责此功能的组件是附加到主摄像机的 "Tracked Pose Driver (Input System)" 组件。由于非输入系统版本不是新输入系统的一部分&…

【运维工具】Ansible一款好用的自动化工具

Ansible一款好用的自动化工具 概述一、基本概念与特点二、核心组件三、主要功能与应用场景四、优缺点 如何使用一、安装Ansible二、配置Ansible三、使用Ansible四、注意事项 Playbook语法详解一、YAML文件的基本结构二、Playbook的主要组成部分三、Playbook示例四、注意事项 概…

使用CSS 和 JavaScript 实现鼠标悬停时图片放大、缩小和抖动

我们可以通过 CSS 和 JavaScript 来实现鼠标悬停时图片放大、缩小和抖动的效果。以下是一个简单的实现方式&#xff1a; 1.HTML 结构 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewp…

面试准备备备备

职业技能 放到简历的黄金位置&#xff08;HR刷选简历的重要参考&#xff09; 基本准则&#xff1a;写在简历上的必须能聊&#xff0c;不然就别写 参考公式&#xff1a;职业技能 必要技术 其他技术 针对性的引导面试官&#xff08;让他问一些你想让他问的&#xff09; 寻找合…

基于微信小程序的面部动作检测系统

引言 本技术文档旨在详细阐述一个基于微信小程序的面部动作检测系统的技术路线、实现方法及关键技术框架。系统的核心功能包括检测用户的左右转头、眨眼和张嘴动作&#xff0c;并根据检测结果逐步引导用户完成任务。为确保系统的安全性和准确性&#xff0c;特别是防止用户通过…

Javascript数据结构——图Graph

当然&#xff0c;让我们深入探讨一下JavaScript中的图数据结构&#xff0c;并列出一些常见的面试题及其代码示例。 图数据结构详解 图&#xff08;Graph&#xff09;是一种非线性的数据结构&#xff0c;由节点&#xff08;也称为顶点&#xff09;和连接这些节点的边组成。节点…

算法-判断一个数是不是3的次幂

给定一个整数&#xff0c;写一个函数来判断它是否是 3 的幂次方。如果是&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 整数 n 是 3 的幂次方需满足&#xff1a;存在整数 x 使得 n 3x 示例 1&#xff1a; 输入&#xff1a;n 27 输出&#xff1a;true示…

多光谱图像的处理和分析方法有哪些?

一、预处理方法 1、辐射校正&#xff1a; 目的&#xff1a;消除或减少传感器本身、大气条件以及太阳光照等因素对多光谱图像辐射亮度值的影响&#xff0c;使得图像的辐射值能够真实反映地物的反射或发射特性。 方法&#xff1a;包括传感器校正和大气校正。传感器校正主要是根…

艾体宝方案丨全面提升API安全:AccuKnox 接口漏洞预防与修复

一、API 安全&#xff1a;现代企业的必修课 在现代技术生态中&#xff0c;应用程序编程接口&#xff08;API&#xff09;扮演着不可或缺的角色。从数据共享到跨平台集成&#xff0c;API 成为连接企业系统与外部服务的桥梁。然而&#xff0c;伴随云计算的普及与微服务架构的流行…

多个DataV遍历生成

DataV是数据可视化工具 与Echart类似 相对Echart图标边框 装饰可选官网DataV 安装 npm install kjgl77/datav-vue3main.ts import DataVVue3 from kjgl77/datav-vue3 app.use(DataVVue3)多个DataV遍历生成 Vue3viteDataV为例:<template><div w50rem h25rem flex&qu…

小程序租赁系统的优势与应用探索

内容概要 小程序租赁系统&#xff0c;听起来很高大上&#xff0c;但实际上它比你想象的要实用得多&#xff01;设想一下&#xff0c;几乎所有的租赁需求都能通过手机轻松解决。这种系统的便捷性体现在让用户随时随地都能发起租赁请求&#xff0c;而不再受制于传统繁琐的手续。…

40.3 prometheus预聚合源码解读

本节重点介绍 : 预聚合原理总结源码解读 预聚合原理总结 prometheus把record记录当做和alert一样处理进行instant_query查询当前点&#xff0c;如果是alert则走报警的流程如果是record&#xff0c;那么将查询到的结果写入tsdb&#xff0c;新的metric_name使用配置中设置的re…

driftingblues2

修改网卡配置信息 首先kali终端运行以下命令查看靶机ip 这里我们发现并没有查到靶机的ip&#xff0c;这时我们重启靶机 打开靶机&#xff0c;按下e键&#xff0c;进入到如下界面 将ro替换为rw signie init/bin/bash 替换完毕后&#xff0c;按下Ctrl键X键&#xff0c;进入如下…