c#让不同的工厂生产不同的“鸭肉”
任务目标
实现对周黑鸭工厂的产品生产统一管理,主要产品包括鸭脖和鸭翅。武汉工厂能生生产鸭脖和鸭翅,南京工厂只能生产鸭翅,长沙工厂只能生产鸭脖。
分析任务
我们需要有武汉工厂、南京工厂、长沙工厂的类,类中需要实现生产鸭肉的函数,既然都有这个生产鸭肉的函数,我们就可以用接口来限定它。
我们还需要在周黑鸭总部下达生产的命令后,各个工厂都开始生产各自的产品,那么怎么做到让这些函数同时被执行呢?这时我们可以用委托。
前置任务
掌握c#接口和委托的使用
一、接口
在C#中,接口(interface)是一种定义了一套方法和属性但不包含实现的类型。接口规定了一个类必须实现哪些方法和属性,但它不定义这些方法和属性的具体执行内容。接口是抽象类型,不能被实例化。它们通常用于定义对象之间的协议或为不同类提供一个公共的功能接口。
例如:
// 定义一个接口
public interface IAnimal
{ void Eat(); void Sleep();
} // 一个类实现该接口
public class Dog : IAnimal
{ public void Eat() { Console.WriteLine("Dog is eating.");} public void Sleep() { Console.WriteLine("Dog is sleeping."); }
}
Dog类在继承了接口IAnimal接口后必须对其方法进行实现。
-
定义契约和行为:
接口定义了一组方法、属性、事件或其他成员的契约,任何实现该接口的类都必须遵循这些约定。这确保了所有实现该接口的类都具有一致的行为和特征。 -
解耦和抽象:
接口允许我们将类与其具体实现分离,从而实现更高级别的抽象。这使得代码更加模块化,易于维护和扩展。通过将实现细节隐藏在接口后面,我们可以降低类之间的耦合度,提高代码的可重用性。 -
多态性支持:
通过接口,我们可以创建引用不同类型对象的变量,只要这些类型都实现了相同的接口。这使得我们可以在不修改现有代码的情况下,将不同的类互换使用。多态性不仅提高了代码的灵活性,还使得程序更加易于扩展和修改。 -
多重继承的一种形式:
虽然C#不支持类的多重继承(即一个类不能继承自多个基类),但接口允许实现多重继承的效果。一个类可以实现多个接口,从而继承多个接口中的方法、属性等成员。这有助于组合不同的功能集,实现更复杂的业务逻辑。 -
插件式架构和框架设计:
接口在构建插件式架构和框架时非常有用。通过定义一系列接口,我们可以允许第三方开发者创建自己的实现,并将其集成到我们的系统中。这种灵活性使得框架更加开放和可扩展。 -
代码清晰和可读性:
使用接口可以使代码更加清晰和易于理解。通过将相关的方法组织到接口中,我们可以更好地描述类的职责和功能。此外,接口还可以作为文档的一部分,帮助其他开发者理解如何使用我们的类和方法。 -
版本控制和兼容性:
当需要修改现有类的行为时,如果该类实现了接口,我们可以创建一个新的类来实现相同的接口,并在需要时替换旧类。这样,我们可以保持与现有代码的兼容性,同时引入新的功能或修改现有功能。
关于本题,我们可以定义一个IProductionFactory 接口类,里面设置生产方法,然后让所有的工厂类去继承这个接口,并实现其生产方法
二、委托
委托(delegate)在C#编程中是一种特殊的类型,它表示对具有特定参数列表和返回类型的方法的引用。委托的主要用途是将方法作为参数传递给其他方法,或者异步地调用方法。通过使用委托,可以实现回调函数、事件处理、异步编程等多种功能。
具体来说,委托定义了一种方法的签名,并且可以与具有相同签名的方法相关联。一旦委托与某个方法关联,委托就可以被用来调用该方法,就好像委托本身就是一个方法一样。这使得在运行时动态地改变方法的调用成为可能。
- 委托用作回调函数来使:
首先,定义一个委托类型,它接受一个整数数组和一个整数索引(用于返回最大数的位置),并返回最大数:
public delegate int FindMaxDelegate(int[] numbers, out int maxIndex);
然后,创建几个实现这个委托的方法。这些方法将按照不同的逻辑来查找最大数:
public class MaxFinder
{ // 查找数组中的最大数(线性搜索) public static int FindMaxLinear(int[] numbers, out int maxIndex) { int max = numbers[0]; maxIndex = 0; for (int i = 1; i < numbers.Length; i++) { if (numbers[i] > max) { max = numbers[i]; maxIndex = i; } } return max; } // 另一个方法可能使用更高效的算法,这里只是为了演示 // (注意:这个示例方法并没有比线性搜索更高效,只是为了演示多个实现) public static int FindMaxDummy(int[] numbers, out int maxIndex) { // 假设这里有一个更复杂的算法来找到最大数... // 但为了简单起见,我们只是返回第一个元素 maxIndex = 0; return numbers[0]; }
}
现在,你可以创建一个方法,它接受一个整数数组和一个FindMaxDelegate委托作为参数,并使用这个委托来查找最大数:
public class Program
{ static void Main(string[] args) { int[] numbers = { 1, 3, 7, 2, 9, 5 }; FindMaxDelegate findMaxDelegate = MaxFinder.FindMaxLinear; // 使用线性搜索方法 // 使用委托来查找最大数 int max = FindMaxUsingDelegate(numbers, findMaxDelegate); int maxIndex; findMaxDelegate(numbers, out maxIndex); // 也可以直接使用委托获取最大数的索引 Console.WriteLine("Max number is: " + max); Console.WriteLine("Max number index is: " + maxIndex); } static int FindMaxUsingDelegate(int[] numbers, FindMaxDelegate findMax) { int maxIndex; return findMax(numbers, out maxIndex); }
}
程序将输出:
Max number is: 9
Max number index is: 4
- 委托用于多播调用
什么是多播调用?
委托可以添加多个函数地址,当调用委托时,这些函数都会被执行
但是如果函数有返回值,那么委托只会返回最后一个被添加进委托的函数的返回值
例如我们可以实现一个计算器委托
delegate T Calculate<T>(T x,T y);
注:委托是实现成泛型模板的
建一个数学类,里面有加减两种方法:
class Math{public int add(int x, int y) { return x + y; }public int sub(int x, int y) { return x - y; }}
将add和sub添加进委托中,调用委托
internal class Program{static void Main(string[] args){Math math = new Math();Calculate<int> cal = math.add;cal += math.sub;Console.WriteLine(cal(1, 2).ToString());}}
通过调试可以知道,在调用委托后,add和sub都被执行了
但是显示在终端的只有 -1 即sub的返回值,==因为sub是最后被添加进委托的。
三、完成任务
有了前面这些知识,我们便可以实现生产周黑鸭的功能了。
- 定义生产接口
public interface IProductionFactory
{//其他函数...void produce();
}
- 定义工厂类,并实现生产方法
public class WuhanFactory : IProductionFactory
{public void produce(){//具体方法...Console.WriteLine("生产鸭脖和鸭翅");}
}
public class NanjingFactory : IProductionFactory
{public void produce(){//具体方法...Console.WriteLine("生产鸭翅");}
}
public class ChangshaFactory : IProductionFactory
{public void produce(){//具体方法...Console.WriteLine("生产鸭脖");}
}
- 定义委托
delegate void ProductionDelegate();
- 实例化各个工厂,并加其生产方法添加进委托,调用委托即可实现让所有工厂生产。
static void Main(string[] args){WuhanFactory factory1 = new WuhanFactory();NanjingFactory factory2 = new NanjingFactory();ChangshaFactory factory3 = new ChangshaFactory();ProductionDelegate produce = factory1.produce;produce += factory2.produce;produce += factory3.produce;produce(); }
相关文章:
c#让不同的工厂生产不同的“鸭肉”
任务目标 实现对周黑鸭工厂的产品生产统一管理,主要产品包括鸭脖和鸭翅。武汉工厂能生生产鸭脖和鸭翅,南京工厂只能生产鸭翅,长沙工厂只能生产鸭脖。 分析任务 我们需要有武汉工厂、南京工厂、长沙工厂的类,类中需要实现生产鸭…...
大数据分析与内存计算——Spark安装以及Hadoop操作——注意事项
一、Spark安装 1.相关链接 Spark安装和编程实践(Spark3.4.0)_厦大数据库实验室博客 (xmu.edu.cn) 2.安装Spark(Local模式) 按照文章中的步骤安装即可 遇到问题:xshell以及xftp不能使用 解决办法: 在…...
论文阅读RangeDet: In Defense of Range View for LiDAR-based 3D Object Detection
文章目录 RangeDet: In Defense of Range View for LiDAR-based 3D Object Detection问题笛卡尔坐标结构图Meta-Kernel Convolution RangeDet: In Defense of Range View for LiDAR-based 3D Object Detection 论文:https://arxiv.org/pdf/2103.10039.pdf 代码&…...
3D模型格式转换工具HOOPS Exchange如何将3D文件加载到PRC数据结构中?
HOOPS Exchange是一款高效的数据访问工具,专为开发人员设计,用于在不同的CAD(计算机辅助设计)系统之间进行高保真的数据转换和交换。由Tech Soft 3D公司开发,它支持广泛的CAD文件格式,包括但不限于AutoCAD的…...
c# wpf Template ContentTemplate
1.概要 1.1 定义内容的外观 2.2 要点分析 2.代码 <Window x:Class"WpfApp2.Window1"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d"http://schem…...
空和null是两回事
文章目录 前言 StringUtils1. 空(empty):字符串:集合: 2. null:引用类型变量:基本类型变量: 3. isBlank总结: 前言 StringUtils 提示:这里可以添加本文要记录…...
UNIAPP(小程序)每十个文章中间一个广告
三十秒刷新一次广告 ad-intervals"30" <template><view style"margin: 30rpx;"><view class"" v-for"(item,index) in 100"><!-- 广告 --><view style"margin-bottom: 20rpx;" v-if"(inde…...
pip包安装用国内镜像源
一:临时用国内源 可以在使用pip的时候加参数-i https://pypi.tuna.tsinghua.edu.cn/simple 例如:pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pyspider,这样就会从清华这边的镜像去安装pyspider库 清华:https://py…...
uniapp:小程序腾讯地图程序文件qqmap-wx-jssdk.js 文件一直找不到无法导入
先看问题: 在使用腾讯地图api时无法导入到qqmap-wx-jssdk.js文件 解决方法:1、打开qqmap-wx-jssdk.js最后一行 然后导入:这里是我的路径位置,可以根据自己的路径位置进行更改导入 最后在生命周期函数中输出: 运行效果…...
如何物理控制另一台电脑以及无网络用作副屏(现成设备和使用)
初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github:codetoys,所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的,可以在任何平台上使用。 控制另一台电脑有很多方法&…...
Aurora8b10b(1)IP核介绍并基于IP核进行设计
文章目录 前言一、IP核设置二、基于IP核进行设计2.1、设计框图2.2、aurora_8b10b_0模块2.3、aurora_8b10b_0_CLOCK_MODULE2.4、aurora_8b10b_0_SUPPORT_RESET_LOGIC2.5、aurora8b10b_channel模块2.6、IBUFDS_GTE2模块2.7、aurora_8b10b_0_gt_common_wrapper模块2.8、aurora8b10…...
基于Springboot的美发管理系统(有报告)。Javaee项目,springboot项目。
演示视频: 基于Springboot的美发管理系统(有报告)。Javaee项目,springboot项目。 项目介绍: 采用M(model)V(view)C(controller)三层体系结构&…...
最新测试技术
在软件测试领域,随着技术的不断进步和行业需求的变化,新的测试技术和方法不断涌现。以下是一些最新的测试技术,它们正在塑造着软件测试的未来: 人工智能和机器学习(AI/ML)在测试中的应用 人工智能和机器学习正在被集成到软件测试中,以提高测试的自动化水平和效率。AI可…...
【算法】初识算法
尽量不说废话 算法 一、数据结构二、排序算法三、检索算法四、字符算类型算法五、递归算法六、贪心算法七、动态规划八、归一化算法后记 我们这里指的算法,是作为程序员在计算机编程时运用到的算法。 算法是一个庞大的体系,主要包括以下内容:…...
HomeBrew 安装与应用
目录 前言一、安装 HomeBrew二、使用 HomeBrew1、使用 brew 查看已安装的软件包2、使用 brew 安装软件包3、使用 brew 升级已安装的软件包4、brew 还有哪些命令呢? 前言 在 macOS(或Linux)系统里,默认是没有软件包的管理器的&…...
JS详解-设计模式
工厂模式: 单例模式: // 1、定义一个类class SingleTon{// 2、添加私有静态属性static #instance// 3、添加静态方法static getInstance(){// 4、判断实例是否存在if(!this.#instance){// 5、实例不存在,创建实例this.#instance new Single…...
探寻马来西亚服务器托管的优势与魅力
随着全球跨境业务的不断增加,境外服务器成为越来越受欢迎的选择。在这其中,马来西亚服务器备受关注,其机房通常位于马来西亚首都吉隆坡。对于客户群体主要分布在东南亚、澳大利亚和新西兰等地区的用户来说,马来西亚服务器是一个理…...
虚幻UE5数字孪生蓝图开发教程
一、背景 这几年,智慧城市/智慧交通/智慧水利等飞速发展,骑士特意为大家做了一个这块的学习路线。 二、这是学习大纲 1.给虚幻UE5初学者准备的智慧城市/数字孪生蓝图开发教程 https://www.bilibili.com/video/BV1894y1u78G 2.UE5数字孪生蓝图开发教学…...
七、Mybatis-缓存
文章目录 缓存一级缓存二级缓存1.概念2.二级缓存开启的条件:3.使二级缓存失效的情况:4.在mapper配置文件中添加的cache标签可以设置一些属性:5.MyBatis缓存查询的顺序 缓存 一级缓存 级别为sqlSession,Mybatis默认开启一级缓存。 使一级缓存失效的四种…...
数据结构(六)——图的应用
6.4 图的应用 6.4.1 最小生成树 对于⼀个带权连通⽆向图G (V, E),⽣成树不同,每棵树的权(即树中所有边上的权值之和)也可能不同。设R为G的所有⽣成树的集合,若T为R中边的权值之和最小的生成树,则T称为G的…...
云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?
大家好,欢迎来到《云原生核心技术》系列的第七篇! 在上一篇,我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在,我们就像一个拥有了一块崭新数字土地的农场主,是时…...
突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合
强化学习(Reinforcement Learning, RL)是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程,然后使用强化学习的Actor-Critic机制(中文译作“知行互动”机制),逐步迭代求解…...
使用分级同态加密防御梯度泄漏
抽象 联邦学习 (FL) 支持跨分布式客户端进行协作模型训练,而无需共享原始数据,这使其成为在互联和自动驾驶汽车 (CAV) 等领域保护隐私的机器学习的一种很有前途的方法。然而,最近的研究表明&…...
linux 下常用变更-8
1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行,YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID: YW3…...
DBAPI如何优雅的获取单条数据
API如何优雅的获取单条数据 案例一 对于查询类API,查询的是单条数据,比如根据主键ID查询用户信息,sql如下: select id, name, age from user where id #{id}API默认返回的数据格式是多条的,如下: {&qu…...
【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)
骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术,它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton):由层级结构的骨头组成,类似于人体骨骼蒙皮 (Mesh Skinning):将模型网格顶点绑定到骨骼上,使骨骼移动…...
Element Plus 表单(el-form)中关于正整数输入的校验规则
目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入(联动)2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...
Python ROS2【机器人中间件框架】 简介
销量过万TEEIS德国护膝夏天用薄款 优惠券冠生园 百花蜂蜜428g 挤压瓶纯蜂蜜巨奇严选 鞋子除臭剂360ml 多芬身体磨砂膏280g健70%-75%酒精消毒棉片湿巾1418cm 80片/袋3袋大包清洁食品用消毒 优惠券AIMORNY52朵红玫瑰永生香皂花同城配送非鲜花七夕情人节生日礼物送女友 热卖妙洁棉…...
Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战
说明:这是一个机器学习实战项目(附带数据代码文档),如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下,风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...
jdbc查询mysql数据库时,出现id顺序错误的情况
我在repository中的查询语句如下所示,即传入一个List<intager>的数据,返回这些id的问题列表。但是由于数据库查询时ID列表的顺序与预期不一致,会导致返回的id是从小到大排列的,但我不希望这样。 Query("SELECT NEW com…...
