文章目录
源码已上传至github,仓库地址
https://github.com/CWJ10242048/WindowsCourseHomeworkCode
1.引言
作业要求:使用 C# 编码(涉及类、接口、委托等关键知识点),实现对周黑鸭工厂的产品生产统一管理,主要产品包括鸭脖和鸭翅。武汉工厂能生生产鸭脖和鸭翅,南京工厂只能生产鸭翅,长沙工厂只能生产鸭脖。具体要求如下:
- 定义接口 IProductionFactory,包含生产鸭脖和鸭翅的方法。
- 定义类 WuhanFactory、NanjingFactory、ChangshaFactory 分别实现接口 IProductionFactory,用于具体的生产工厂。
- 使用委托 ProductionDelegate 定义生产委托。
- 在 Main 函数中,创建不同工厂的实例,并通过生产委托进行生产
本题的目的是通过工厂模式和委托来模拟周黑鸭在不同地区工厂的生产过程。展示了如何使用工厂模式来创建具有不同生产能力的工厂对象,并通过委托来动态地调用这些工厂的生产方法。
代码中有工厂类(WuhanFactory、NanjingFactory、ChangshaFactory)代表了不同地区的周黑鸭生产工厂,每个工厂都有自己的生产方法(ProduceDuckNeck、ProduceDuckWing),用于生产不同的周黑鸭产品。
ProductionDelegate委托类型用于定义生产方法的签名,它允许我们将工厂的生产方法作为委托的实例进行传递和调用。通过这种方式,代码实现了生产逻辑的解耦和灵活性。工厂模式的引入使得我们可以根据不同的需求创建不同的工厂对象,而不需要修改现有的代码。委托的使用则使得我们可以在运行时动态地组合和调用不同的生产方法,提高了代码的可扩展性和可维护性。
2. 工厂模式简介
为解决这个实际工厂问题,需要使用工厂模式。工厂模式是一种常用的设计模式,它属于创建型模式,主要用于解决对象创建的问题。工厂模式的核心思想是将对象的创建与使用相分离,从而降低代码之间的耦合度,提高系统的灵活性和可扩展性。
2.1定义
工厂模式定义了一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
2.2作用
- 解耦:工厂模式将对象的创建与使用相分离,使得客户端代码无需关注对象的创建细节,只需关注如何使用对象。
- 降低耦合:由于对象的创建逻辑被封装在工厂类中,客户端代码与具体的产品类之间的耦合度降低,使得代码更加灵活和可维护。
- 可扩展性:当需要添加新的产品时,只需添加新的产品类和对应的工厂子类,无需修改现有的客户端代码。
2.3适用场景
- 当一个类不知道它所必须创建的对象的类时。
- 当一个类希望由它的子类来指定它所创建的对象时。
- 当类将创建对象的职责委托给多个帮助子类中的某一个,并且希望将哪一个帮助子类是代理者这一信息局部化时。
2.4以本题为例
我们的周黑鸭生产系统,其中包含了多种不同的周黑鸭产品(如鸭脖、鸭翅等)。我们可以使用工厂模式来创建这些产品对象。
首先,我们定义一个产品接口(如DuckProduct),该接口定义了所有产品共有的方法,但是这题题目并没有要求共有方法,所以在本篇的代码中就没有展现。然后,我们为每个具体的产品类(如DuckNeck、DuckWing)实现这个接口。
接下来,我们创建一个工厂接口IProductionFactory,该接口定义了创建产品的方法。然后,我们为每个地区创建一个工厂子类(如WuhanFactory、NanjingFactory),这些子类实现了工厂接口,并负责创建具体的产品对象。
客户端代码只需与工厂接口交互,而无需关心具体的产品类。当需要创建产品时,客户端代码调用工厂对象的创建方法,工厂对象根据需求创建并返回相应的产品对象。
通过这种方式,实现了对象的创建与使用的分离。客户端代码只需关注如何使用产品对象,而无需了解产品对象的创建细节。同时,由于工厂模式的使用,客户端代码与具体的产品类之间的耦合度降低,使得代码更加灵活和易于维护。
3.委托简介
委托(Delegate)是C#中的一种类型,它定义了方法的签名和返回类型,用于安全地封装方法的引用。委托允许将方法作为参数传递,或者将方法赋值给变量,从而实现方法的动态调用。简而言之,委托就是方法的引用。
3.1定义
委托的定义与方法的定义类似,但是它本身并不实现任何功能,而是指向已经存在的方法。定义委托时,需要指定它所能引用的方法的返回类型和参数列表。例如:
public delegate void VoidDelegate(); // 定义一个无参数无返回值的委托
3.2作用
- 回调函数:允许将一个方法作为参数传递给另一个方法,并在需要时调用它。
- 事件处理:在.NET中,事件是基于委托实现的,允许对象通知其他对象当某些特殊事情发生时进行响应。
- 实现多态:通过委托,可以在运行时动态地确定调用哪个方法,实现一种类似于面向对象多态性的效果。
3.3使用方式
一般步骤包括:
- 定义委托:首先,需要定义一个委托类型,指定它所能引用的方法的签名。
- 创建委托实例:然后,创建一个或多个该委托类型的实例,并将它们与具体的方法关联起来。
- 调用委托:最后,像调用方法一样调用委托实例,使与委托关联的方法被执行。
3.4以本题为例
定义委托:
// 定义工厂生产委托
public delegate void ProductionDelegate();
创建委托实例:
// 定义生产鸭脖和鸭翅的接口
public interface IProductionFactory
{
void ProduceDuckNeck();
void ProduceDuckWing();
}
// 武汉工厂,能生产鸭脖和鸭翅
public class WuhanFactory : IProductionFactory
{
public void ProduceDuckNeck()
{
Console.WriteLine("武汉工厂生产鸭脖");
}
public void ProduceDuckWing()
{
Console.WriteLine("武汉工厂生产鸭翅");
}
}
// 南京工厂,只能生产鸭翅
public class NanjingFactory : IProductionFactory
{
public void ProduceDuckNeck()
{
throw new NotImplementedException("南京工厂不能生产鸭脖");
}
public void ProduceDuckWing()
{
Console.WriteLine("南京工厂生产鸭翅");
}
}
// 长沙工厂,只能生产鸭脖
public class ChangshaFactory : IProductionFactory
{
public void ProduceDuckNeck()
{
Console.WriteLine("长沙工厂生产鸭脖");
}
public void ProduceDuckWing()
{
throw new NotImplementedException("长沙工厂不能生产鸭翅");
}
}
调用委托:
static void Main(string[] args)
{
// 创建工厂实例
WuhanFactory wuhan = new WuhanFactory();
NanjingFactory nanjing = new NanjingFactory();
ChangshaFactory changsha = new ChangshaFactory();
// 使用委托进行生产
ProductionDelegate wuhanProduction = new ProductionDelegate(wuhan.ProduceDuckNeck);
wuhanProduction += wuhan.ProduceDuckWing;
ProductionDelegate nanjingProduction = new ProductionDelegate(nanjing.ProduceDuckWing);
ProductionDelegate changshaProduction = new ProductionDelegate(changsha.ProduceDuckNeck);
// 异常处理
try
{
wuhanProduction.Invoke();
nanjingProduction.Invoke();
changshaProduction.Invoke();
}
catch (NotImplementedException e)
{
Console.WriteLine($"生产异常: {e.Message}");
}
Console.ReadLine();
}
4.代码实现细节
4.1委托的定义
定义需要确保参数和返回类型与所要引用的方法一致,比如下面的代码,都是无参数无返回值类型的:
//定义时
public delegate void ProductionDelegate();
//调用时
wuhanProduction.Invoke();
nanjingProduction.Invoke();
changshaProduction.Invoke();
4.2创建委托
创建委托实例时,需要使用new关键字,并传入方法的引用:
ProductionDelegate wuhanProduction = new ProductionDelegate(wuhan.ProduceDuckNeck);
wuhanProduction += wuhan.ProduceDuckWing;
ProductionDelegate nanjingProduction = new ProductionDelegate(nanjing.ProduceDuckWing);
ProductionDelegate changshaProduction = new ProductionDelegate(changsha.ProduceDuckNeck);
委托支持使用+运算符来创建委托链,即多个委托可以按顺序被调用。这在实现事件处理时非常有用,因为可以有多个方法订阅同一个事件。上面的wuhanProduction就使用+运算符创建了委托链
4.3调用委托
委托实例可以像方法一样被调用,既可以使用Invoke()方法来显式调用委托,也可以直接调用委托实例:
wuhanProduction.Invoke();
nanjingProduction.Invoke();
changsha.ProduceDuckNeck();
5.运行示例与结果
运行结果如下:
注意,如果代码是正确的,结果框一闪而过,需要加一行这个:
Console.ReadLine();
这样就不会自动关闭运行框,就会成功展示以上结果了
6.异常处理
在编程中,异常处理是一种机制,用于在程序执行过程中遇到错误或异常状况时,能够以一种结构化和可预测的方式处理这些状况,而不是让程序直接崩溃。它允许程序在遇到问题时采取适当的行动,比如记录错误信息、尝试恢复或安全地终止执行。一般是用try-catch代码实现,常见的一个格式如下:
public class MyClass
{
public void MyMethod()
{
try
{
// 尝试执行一些代码
throw new NotImplementedException("这个方法还没有实现。");
}
catch (NotImplementedException ex)
{
// 当 NotImplementedException 被抛出时,执行这里的代码
Console.WriteLine("捕获到 NotImplementedException:" + ex.Message);
// 可以选择记录日志、回滚操作、或者执行其他恢复逻辑
}
}
}
除了NotImplementedException异常以外,还有许多常见的异常类型,如NullReferenceException、IndexOutOfRangeException、ArgumentException 、IOException、FormatException、TimeoutException、InvalidOperationException、CustomExceptions等
本篇的代码也使用了异常处理:
try
{
wuhanProduction.Invoke();
nanjingProduction.Invoke();
changsha.ProduceDuckNeck();
}
catch (NotImplementedException e)
{
Console.WriteLine($"生产异常: {e.Message}");
}
Console.ReadLine();
7.总结
在本代码中,我们主要实现了工厂模式和委托的应用。通过工厂模式,我们创建了一个生产鸭脖和鸭翅的接口IProductionFactory,用于生产不同种类的鸭子部件,如鸭脖子。工厂模式使得我们在需要增加新的鸭子部件或改变生产逻辑时,只需修改工厂类而无需改动客户端代码,提高了代码的可扩展性和可维护性。
委托的使用则为我们提供了一种灵活的方式来定义和执行操作。在代码中,我们定义了ProduceDelegate委托,它允许我们引用任何与委托签名匹配的方法。通过委托,我们可以将方法的引用作为参数传递,或在运行时动态地决定执行哪个方法,从而实现了方法的解耦和动态调用。
通过结合工厂模式和委托,我们的代码实现了灵活且可扩展的鸭子部件生产逻辑。客户端代码可以通过工厂类获取所需的部件,并通过委托来定义和执行部件的生产过程。
代码也有很多可以补充完善的地方,如果有哪里没有讲清楚的,欢迎您在评论区留言探讨;如果您感觉本文讲述的还比较清晰,希望您能给本文点个赞,谢谢!