当前位置: 首页 > news >正文

C# 工厂模式学习

工厂模式(Factory Pattern)是一种创建型设计模式,它提供了一种创建对象的接口,而不是通过具体类来实例化对象。工厂模式可以将对象的创建过程封装起来,使代码更具有灵活性和可扩展性。

工厂模式有几种常见的实现方式:

  1. 简单工厂模式(Simple Factory Pattern): 简单工厂模式通过一个工厂类来决定创建哪种具体类的实例。这个工厂类通常提供一个静态方法,根据传入的参数创建相应的对象。

  2. 工厂方法模式(Factory Method Pattern): 工厂方法模式定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法使一个类的实例化延迟到其子类。

  3. 抽象工厂模式(Abstract Factory Pattern): 抽象工厂模式提供一个接口,用于创建相关或依赖对象的家族,而无需明确指定具体类。通过使用抽象工厂模式,一个类可以实例化一组相关对象,而不需要知道它们的具体类。

简单工厂模式示例

假设我们有一个动物园项目,需要创建不同的动物对象:

// 动物接口
public interface IAnimal
{void Speak();
}// 具体的动物类
public class Dog : IAnimal
{public void Speak(){Console.WriteLine("Woof!");}
}public class Cat : IAnimal
{public void Speak(){Console.WriteLine("Meow!");}
}// 简单工厂类
public static class AnimalFactory
{public static IAnimal CreateAnimal(string animalType){switch (animalType.ToLower()){case "dog":return new Dog();case "cat":return new Cat();default:throw new ArgumentException("Unknown animal type");}}
}// 使用示例
class Program
{static void Main(string[] args){IAnimal animal = AnimalFactory.CreateAnimal("dog");animal.Speak();  // 输出:Woof!}
}

工厂方法模式示例

假设我们有一个动物园项目,不同的子类需要创建不同的动物对象:

// 动物接口
public interface IAnimal
{void Speak();
}// 具体的动物类
public class Dog : IAnimal
{public void Speak(){Console.WriteLine("Woof!");}
}public class Cat : IAnimal
{public void Speak(){Console.WriteLine("Meow!");}
}// 工厂接口
public interface IAnimalFactory
{IAnimal CreateAnimal();
}// 具体工厂类
public class DogFactory : IAnimalFactory
{public IAnimal CreateAnimal(){return new Dog();}
}public class CatFactory : IAnimalFactory
{public IAnimal CreateAnimal(){return new Cat();}
}// 使用示例
class Program
{static void Main(string[] args){IAnimalFactory factory = new DogFactory();IAnimal animal = factory.CreateAnimal();animal.Speak();  // 输出:Woof!}
}

抽象工厂模式示例

假设我们有一个动物园项目,需要创建一组相关的对象(例如,动物及其食物):

// 动物接口
public interface IAnimal
{void Speak();
}// 具体的动物类
public class Dog : IAnimal
{public void Speak(){Console.WriteLine("Woof!");}
}public class Cat : IAnimal
{public void Speak(){Console.WriteLine("Meow!");}
}// 食物接口
public interface IFood
{void Get();
}// 具体的食物类
public class DogFood : IFood
{public void Get(){Console.WriteLine("Dog food");}
}public class CatFood : IFood
{public void Get(){Console.WriteLine("Cat food");}
}// 抽象工厂接口
public interface IAnimalFactory
{IAnimal CreateAnimal();IFood CreateFood();
}// 具体工厂类
public class DogFactory : IAnimalFactory
{public IAnimal CreateAnimal(){return new Dog();}public IFood CreateFood(){return new DogFood();}
}public class CatFactory : IAnimalFactory
{public IAnimal CreateAnimal(){return new Cat();}public IFood CreateFood(){return new CatFood();}
}// 使用示例
class Program
{static void Main(string[] args){IAnimalFactory factory = new DogFactory();IAnimal animal = factory.CreateAnimal();IFood food = factory.CreateFood();animal.Speak();  // 输出:Woof!food.Get();      // 输出:Dog food}
}

以上是三种工厂模式的基本示例,可以根据具体需求选择合适的工厂模式来实现代码的创建和管理。如果希望在增加新动物类型时尽量减少对现有类的修改,推荐使用工厂方法模式。工厂方法模式的设计使得每新增一种动物,只需增加一个对应的工厂类和具体的动物类,而无需修改已有的代码,从而符合开闭原则(即对扩展开放,对修改关闭)。

使用工厂方法模式

下面是一个更完善的工厂方法模式示例,展示了如何在增加新动物时,尽量减少对现有代码的修改。

// 动物接口
public interface IAnimal
{void Speak();
}// 具体的动物类
public class Dog : IAnimal
{public void Speak(){Console.WriteLine("Woof!");}
}public class Cat : IAnimal
{public void Speak(){Console.WriteLine("Meow!");}
}// 新增的动物类
public class Bird : IAnimal
{public void Speak(){Console.WriteLine("Tweet!");}
}// 工厂接口
public interface IAnimalFactory
{IAnimal CreateAnimal();
}// 具体工厂类
public class DogFactory : IAnimalFactory
{public IAnimal CreateAnimal(){return new Dog();}
}public class CatFactory : IAnimalFactory
{public IAnimal CreateAnimal(){return new Cat();}
}// 新增的动物工厂类
public class BirdFactory : IAnimalFactory
{public IAnimal CreateAnimal(){return new Bird();}
}// 使用示例
class Program
{static void Main(string[] args){List<IAnimalFactory> factories = new List<IAnimalFactory>{new DogFactory(),new CatFactory(),new BirdFactory()  // 新增的工厂只需在这里添加};foreach (var factory in factories){IAnimal animal = factory.CreateAnimal();animal.Speak();}}
}

在这个示例中,新增一种动物只需:

  1. 创建新的具体动物类,例如 Bird
  2. 创建对应的工厂类,例如 BirdFactory
  3. 在使用的地方添加新的工厂实例,例如在 factories 列表中添加 new BirdFactory()

这样做的好处是每增加一个新动物类型,不需要修改现有的工厂类或具体的动物类,只需要添加新的类和工厂即可,从而降低了代码修改的风险和复杂度。

使用反射和配置来进一步减少修改

如果希望在增加动物时连代码都不需要改动,可以考虑使用反射和配置文件的方式。通过配置文件定义动物类型和对应的工厂类,然后使用反射动态加载:

// 动物接口和具体的动物类(同上)// 工厂接口和具体工厂类(同上)// 使用反射加载工厂类
class Program
{static void Main(string[] args){// 假设配置文件中定义了动物类型和对应的工厂类var factoryTypes = new List<string>{"DogFactory","CatFactory","BirdFactory"  // 配置文件中新增的工厂类};var factories = new List<IAnimalFactory>();foreach (var factoryType in factoryTypes){var type = Type.GetType(factoryType);if (type != null && typeof(IAnimalFactory).IsAssignableFrom(type)){var factory = (IAnimalFactory)Activator.CreateInstance(type);factories.Add(factory);}}foreach (var factory in factories){IAnimal animal = factory.CreateAnimal();animal.Speak();}}
}

接口与继承结合使用

工厂模式主要使用了接口、继承,在C#中,接口和继承是面向对象编程的重要概念。接口定义了一组方法和属性,而继承允许一个类从另一个类继承其成员。接口可以实现多重继承,而类只能继承一个基类。通常情况下,接口和继承可以结合使用,以充分利用它们各自的优点。通过这种方式,基类可以提供一些通用的实现,而接口可以定义特定的行为。

// 接口
public interface IAnimal
{void Speak();void Eat();
}// 基类
public class Animal
{public void Sleep(){Console.WriteLine("Sleeping...");}
}// 派生类实现接口
public class Dog : Animal, IAnimal
{public void Speak(){Console.WriteLine("Woof!");}public void Eat(){Console.WriteLine("Dog is eating.");}
}public class Cat : Animal, IAnimal
{public void Speak(){Console.WriteLine("Meow!");}public void Eat(){Console.WriteLine("Cat is eating.");}
}// 使用示例
class Program
{static void Main(string[] args){IAnimal dog = new Dog();dog.Speak(); // 输出:Woof!dog.Eat();   // 输出:Dog is eating.IAnimal cat = new Cat();cat.Speak(); // 输出:Meow!cat.Eat();   // 输出:Cat is eating.// 使用基类方法Animal animalDog = (Animal)dog;animalDog.Sleep(); // 输出:Sleeping...Animal animalCat = (Animal)cat;animalCat.Sleep(); // 输出:Sleeping...}
}

总结

  • 接口:定义了一组必须实现的方法和属性,没有实现代码。支持多重继承,使得类可以实现多个接口。
  • 继承:用于从现有类创建新类,继承基类的成员。每个类只能有一个基类,但可以实现多个接口。
  • 结合使用:通过将接口和继承结合使用,可以实现代码的高复用性和灵活性。

通过上述示例,可以看到如何使用接口和继承来设计灵活且可扩展的应用程序结构。这样既能充分利用基类的通用功能,又能通过接口实现特定的行为。

相关文章:

C# 工厂模式学习

工厂模式&#xff08;Factory Pattern&#xff09;是一种创建型设计模式&#xff0c;它提供了一种创建对象的接口&#xff0c;而不是通过具体类来实例化对象。工厂模式可以将对象的创建过程封装起来&#xff0c;使代码更具有灵活性和可扩展性。 工厂模式有几种常见的实现方式&…...

AI生成微信职业头像

加油&#xff0c;新时代打工人&#xff01; 真别说&#xff0c;还挺好看的 https://chatglm.cn/main/alltoolsdetail...

遥感图像的深度学习的任务类型

在遥感图像的深度学习任务中&#xff0c;利用深度学习技术处理和分析遥感图像已经成为一个重要的研究方向。遥感图像来自卫星、无人机等设备&#xff0c;包含了丰富的地球表面信息。以下是遥感图像深度学习中的主要任务类型&#xff1a; 1. 图像分类&#xff08;Image Classif…...

162.二叉树:填充每个节点的下一个右侧节点指针(力扣)

代码解决 /* // Definition for a Node. class Node { public:int val;Node* left;Node* right;Node* next;Node() : val(0), left(NULL), right(NULL), next(NULL) {}Node(int _val) : val(_val), left(NULL), right(NULL), next(NULL) {}Node(int _val, Node* _left, Node* _…...

NLP(20)--知识图谱+实体抽取

前言 仅记录学习过程&#xff0c;有问题欢迎讨论 基于LLM的垂直领域问答方案&#xff1a; 特点&#xff1a;不是通用语料&#xff1b;准确度要求高&#xff0c;召回率可以低&#xff08;转人工&#xff09;&#xff1b;拓展性和可控性&#xff08;改变特定内容的回答&#xf…...

【mysql数据库】mycat中间件

MyCat 简介 Mycat 是数据库 中间件 。 1、 数据库中间件 中间件 是一类连接软件组件和应用的计算机软件&#xff0c; 以便于软件各部件之间的沟通 。 例子 Tomcat web 中间件 。 数据库 中间件 连接 java 应用程序和数据库 2、 为什么要用 Mycat ① Java 与数据库紧耦合 …...

满帮集团 Eureka 和 ZooKeeper 的上云实践

作者&#xff1a;胡安祥 满帮集团&#xff0c;作为“互联网物流”的平台型企业&#xff0c;一端承接托运人运货需求&#xff0c;另一端对接货车司机&#xff0c;提升货运物流效率。2021 年美股上市&#xff0c;成为数字货运平台上市第一股。根据公司年报&#xff0c;2021 年&a…...

ubuntu中彻底删除mysql (配置文件删除可选)

ubuntu中彻底删除mysql (配置文件删除可选) 对于此类即搜即用的分享文章&#xff0c;也不过多赘述&#xff0c;直接依次按照下面的操作执行即可&#xff1a; 一、删除 mysql 数据文件 sudo rm /var/lib/mysql/ -R二、删除 mysql 配置文件 sudo rm /etc/mysql/ -R三、查看 m…...

根据模板和git commit自动生成日·周·月·季报

GitHub - qiaotaizi/dailyreport: 日报生成器 GitHub - yurencloud/daily: 程序员专用的日报、周报、月报、季报自动生成器&#xff01; config.json: { "Author": "gitname", "Exclude": ["update:", "add:", "…...

matlab GUI界面设计

【实验内容】 用MATLAB的GUI程序设计一个具备图像边缘检测功能的用户界面&#xff0c;该设计程序有以下基本功能&#xff1a; &#xff08;1&#xff09;图像的读取和保存。 &#xff08;2&#xff09;设计图形用户界面&#xff0c;让用户对图像进行彩色图像到灰度图像的转换…...

MyBatis 面试题

一、什么是 Mybatis? 1、Mybatis 是一个半 ORM(对象关系映射)框架,它内部封装了 JDBC,开发时 只需要关注 SQL 语句本身,不需要花费精力去处理加载驱动、创建连接、创建 statement 等繁杂的过程。程序员直接编写原生态 sql,可以严格控制 sql 执行性 能,灵活度高。 …...

C#根据数据量自动排版标签的样例

这是一个C#根据数据量自动排版标签的样例 using System; using System.Collections.Generic; using System.Data.SqlClient; using System.Drawing; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; using HslCommuni…...

【网络安全】Web安全基础 - 第一节:使用软件及环境介绍

VMware VMware&#xff0c;是全球云基础架构和移动商务解决方案的佼佼者。 VMware可是一个总部位于美国加州帕洛阿尔托的计算机虚拟化软件研发与销售企业呢。简单来说&#xff0c;它就是通过提供虚拟化解决方案&#xff0c;让企业在数据中心改造和公有云整合业务上更加得心应…...

Mac下载docker

先安装homebrew Mac下载Homebrew-CSDN博客 然后输入以下命令安装docker brew install --cask --appdir/Applications docker 期间需要输入密码。输入完等待即可...

k8s_设置dns

配置k8s dns 在 Kubernetes 集群中&#xff0c;CoreDNS 是默认的 DNS 服务器&#xff0c;它负责处理集群内所有的 DNS 请求。 kubectl edit cm coredns -n kube-system (此命令修改coredns 配置) kubectl describe cm coredns -n kube-system&#xff08;此命令查看coredns 配…...

翻译《The Old New Thing》- What a drag: Dragging a virtual file (HGLOBAL edition)

What a drag: Dragging a virtual file (HGLOBAL edition) - The Old New Thing (microsoft.com)https://devblogs.microsoft.com/oldnewthing/20080318-00/?p23083 Raymond Chen 2008年03月18日 拖拽虚拟文件&#xff08;HGLOBAL 版本&#xff09; 现在我们已经对简单的数据…...

SA316系列音频传输模块-传输距离升级音质不打折

SA316是思为无线研发的一款远距离音频传输模块&#xff0c;音频采样率为48K&#xff0c;传输距离可达200M。为了满足更多用户需求&#xff0c;思为无线在SA316基础上进一步增加传输距离推出SA316F30。相比SA316性能&#xff0c;同样其采用48K采样&#xff0c;-96dBm灵敏度&…...

【机器学习】智能选择的艺术:决策树在机器学习中的深度剖析

在机器学习的分类和回归问题中&#xff0c;决策树是一种广泛使用的算法。决策树模型因其直观性、易于理解和实现&#xff0c;以及处理分类和数值特征的能力而备受欢迎。本文将解释决策树算法的概念、原理、应用、优化方法以及未来的发展方向。 &#x1f680;时空传送门 &#x…...

电脑缺少运行库,无法启动程序

在我们使用一些软件的时候&#xff0c;由于电脑缺少一些运行库&#xff0c;导致无法启动应用软件&#xff0c;此时需要我们安装缺少的运行库。 比如当电脑提示&#xff1a; Cannot load library Qt5Xlsx.dll 我们就需要下载C得运行库&#xff0c;以满足软件运行需要。 下载链…...

【计算机软考_初级篇】每日十题2

各位老师大家好&#xff0c;软考对于日常的知识储备和企业中的考试&#xff0c;或者说在校大学生来说&#xff0c;那用处是非常大的&#xff01;&#xff01;那么下面我们进入正题&#xff0c;软考呢是分两种语言&#xff0c;java和C&#xff0c;对于其他语言目前还没&#xff…...

DeepStream-Yolo GPU加速原理深度解析:从ONNX到TensorRT的完整流程

DeepStream-Yolo GPU加速原理深度解析&#xff1a;从ONNX到TensorRT的完整流程 【免费下载链接】DeepStream-Yolo NVIDIA DeepStream SDK 8.0 / 7.1 / 7.0 / 6.4 / 6.3 / 6.2 / 6.1.1 / 6.1 / 6.0.1 / 6.0 / 5.1 implementation for YOLO models 项目地址: https://gitcode.c…...

AB下载管理器终极指南:高效管理你的下载任务

AB下载管理器终极指南&#xff1a;高效管理你的下载任务 【免费下载链接】ab-download-manager A Download Manager that speeds up your downloads 项目地址: https://gitcode.com/GitHub_Trending/ab/ab-download-manager AB下载管理器是一款基于Kotlin开发的开源跨平…...

基于知识图谱与NLP技术的小说文本结构化分析实战

1. 项目概述&#xff1a;当小说遇见知识图谱 如果你和我一样&#xff0c;既是个技术爱好者&#xff0c;又是个小说迷&#xff0c;那你肯定有过这样的体验&#xff1a;读完一本情节复杂、人物关系盘根错节的小说后&#xff0c;合上书页&#xff0c;脑子里却一团乱麻。谁是谁的盟…...

基于LLM的代码库智能维护:自动化更新与重构实践

1. 项目概述&#xff1a;当代码库有了AI大脑最近在GitHub上看到一个挺有意思的项目&#xff0c;叫“CodeWithLLM-Updates”。光看名字&#xff0c;你可能觉得这又是一个“用AI写代码”的工具&#xff0c;但仔细研究它的README和代码结构&#xff0c;我发现它的定位要更“幕后”…...

考古现场数据智能治理新范式(NotebookLM+地层学语义建模深度解析)

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;考古现场数据智能治理新范式&#xff08;NotebookLM地层学语义建模深度解析&#xff09; 在田野考古数字化进程中&#xff0c;传统地层记录存在碎片化、非结构化与语义断层三大瓶颈。NotebookLM 作为基…...

基于Slack与AI的IDE智能助手:架构设计与实战部署

1. 项目概述&#xff1a;当你的IDE拥有了“光标智能体” 如果你是一名开发者&#xff0c;每天在IDE&#xff08;集成开发环境&#xff09;里敲代码的时间超过8小时&#xff0c;那你一定对这样的场景不陌生&#xff1a;光标在代码行间跳跃&#xff0c;你正试图理解一个复杂的函…...

TV Bro电视浏览器:如何在Android电视上享受完整网页浏览体验的终极指南

TV Bro电视浏览器&#xff1a;如何在Android电视上享受完整网页浏览体验的终极指南 【免费下载链接】tv-bro Simple web browser for android optimized to use with TV remote 项目地址: https://gitcode.com/gh_mirrors/tv/tv-bro 您是否曾经尝试在智能电视上浏览网页…...

【实战排错】Vivado 综合卡死与“PID not specified”的深度诊断与修复

1. 故障现象与初步排查 最近在跑Vivado综合时&#xff0c;突然遇到一个让人头疼的问题&#xff1a;综合进程莫名其妙卡死&#xff0c;日志里还跳出"PID not specified"的错误提示。这种情况相信不少FPGA工程师都遇到过&#xff0c;特别是项目紧急的时候&#xff0c;这…...

BoxLite-AI:开箱即用的轻量级AI应用容器部署与优化指南

1. 项目概述&#xff1a;BoxLite-AI 是什么&#xff0c;以及它解决了什么问题 最近在折腾本地大模型部署和轻量化应用时&#xff0c;发现了一个挺有意思的项目&#xff0c;叫 BoxLite-AI。乍一看这个名字&#xff0c;可能会联想到“盒子”和“轻量”&#xff0c;没错&#xff0…...

AI驱动编辑预设:智能调色与音频处理实战指南

1. 项目概述&#xff1a;AI驱动的编辑预设库最近在折腾视频和图片后期的时候&#xff0c;发现一个挺有意思的项目&#xff0c;叫kaushalrao/ai-editor-presets。光看名字&#xff0c;你可能觉得这又是一个普通的滤镜包或者调色预设合集。但深入用下来&#xff0c;我发现它的核心…...