一、作业内容
使用 C# 编码(涉及类、接口、委托等关键知识点),实现对周黑鸭工厂的产品生产统一管理,主要产品包括鸭脖和鸭翅。武汉工厂能生生产鸭脖和鸭翅,南京工厂只能生产鸭翅,长沙工厂只能生产鸭脖。具体要求如下:
- 定义接口 IProductionFactory,包含生产鸭脖和鸭翅的方法。
- 定义类 WuhanFactory、NanjingFactory、ChangshaFactory 分别实现接口 IProductionFactory,用于具体的生产工厂。
- 使用委托 ProductionDelegate 定义生产委托。
- 在 Main 函数中,创建不同工厂的实例,并通过生产委托进行生产。
二、作业目的
在本次作业中,我们需要设计一个周黑鸭工厂的产品生产统一管理系统。首先,我们明确工厂的主要产品和不同工厂的生产能力。主要产品包括鸭脖和鸭翅,武汉工厂能生产鸭脖和鸭翅,南京工厂只能生产鸭翅,长沙工厂只能生产鸭脖。熟悉掌握定义接口、定义类和产生委托等来实现周黑鸭工厂产品生产统一管理的C#实现。
三、概念介绍
3.1 委托的介绍
委托是一种可以指向方法的引用,可以理解为一种函数指针,是类型安全的。它类似于C++中的函数指针,通过对于方法特征和返回值类型的声明,封装了具有相同特征和返回类型的方法。 使用委托需要三个步骤:1、 声明委托类型 2、创建委托实例 3、 向委托实例注册方法
3.2 接口的介绍
接口的语法结构: [访问修饰符] interface 接口标识符 [:基接口列表] { 接口体;}
接口成员访问权限为public,但不能加访问修饰符 接口成员不能有定义 接口的成员必须是方法,属性,事件或索引器,不能包含常数、字段、运算符、实例构造函数、析构函数或类型。
3.3 接口和类的区别
接口(Interface)和类(Class)在面向对象编程中是两个不同的核心概念,它们之间存在几个显著的区别:
1、定义与实现:
类是一个具体的实现,它包含了属性(即状态信息)、方法(即可以被对象调用的函数)以及可能还有构造函数,用于在创建对象时进行初始化操作。
接口则是一种规范或协议,它只定义了一组方法和常量,并不提供具体的实现。
2、实例化与继承:
类是可以被实例化的,即可以通过类创建具体的对象。此外,类与类之间可以形成继承关系,一个类可以直接继承自另一个类,从而获得父类的属性和方法,并在子类中进行重写和扩展。
接口则不能被直接实例化。类无法直接继承接口,但可以通过实现接口来获取接口中定义的方法,并对其进行实现。而且,一个类可以实现多个接口,这使得一个类可以具备多种行为,提供更大的灵活性。
3、功能与作用:
类是构造面向对象程序的基本单位,用于封装数据和方法,创建多个对象来表示不同的实体,并在这些对象上执行特定的操作。
接口的主要作用包括定义程序中不同模块之间的通信方式,使它们可以交互和集成,降低耦合性,实现代码复用,以及实现多态性。接口提供了一种规范,使得开发人员能够定义和实现模块之间的通信协议,从而实现代码的模块化和可复用性。
四、代码实现
4.1 定义接口
首先,我们定义一个接口 IProductionFactory,它包含了生产鸭脖和鸭翅的方法。这样,我们可以为不同的工厂实现统一的接口,便于管理和使用。
//定义一个接口 IProductionFactory
public interface IProductionFactory
{
void ProduceDuckNeck();
void ProduceDuckWing();
}
4.2 实现工厂类
我们分别实现三个工厂类:WuhanFactory、NanjingFactory 和 ChangshaFactory,它们各自实现了 IProductionFactory 接口。
public class WuhanFactory : IProductionFactory
{
public void ProduceDuckNeck()
{
Console.WriteLine("武汉工厂生产鸭脖");
}
public void ProduceDuckWing()
{
Console.WriteLine("武汉工厂生产鸭翅");
}
}
public class NanjingFactory : IProductionFactory
{
public void ProduceDuckNeck()
{
throw new NotImplementedException("南京工厂不能生产鸭脖");
//对于不能生产的产品,我们抛出了 NotImplementedException 异常
//用于表明该类不支持该方法。
}
public void ProduceDuckWing()
{
Console.WriteLine("南京工厂生产鸭翅");
}
}
public class ChangshaFactory : IProductionFactory
{
public void ProduceDuckNeck()
{
Console.WriteLine("长沙工厂生产鸭脖");
}
public void ProduceDuckWing()
{
throw new NotImplementedException("长沙工厂不能生产鸭翅");
}
}
在上面的代码中,我们为每个工厂实现了生产鸭脖和鸭翅的方法。对于不能生产的产品,我们抛出了 NotImplementedException 异常,这是一种良好的实践,用于表明该类不支持该方法。
4.3 定义生产委托
我们使用委托 ProductionDelegate 定义生产委托。委托类似于 C 语言中的函数指针,可以引用一个具有特定签名的方法。
public delegate void ProductionDelegate();
4.4 在Main函数中创建实例并生产
class Program
{
static void Main(string[] args)
{
// 创建工厂实例
IProductionFactory wuhanFactory = new WuhanFactory();
IProductionFactory nanjingFactory = new NanjingFactory();
IProductionFactory changshaFactory = new ChangshaFactory();
// 定义生产委托
ProductionDelegate produceDelegate;
// 武汉工厂可以生产鸭脖和鸭翅
produceDelegate = wuhanFactory.ProduceDuckNeck;
produceDelegate(); // 调用委托执行方法
produceDelegate = wuhanFactory.ProduceDuckWing;
produceDelegate();
// 南京工厂只能生产鸭翅
produceDelegate = nanjingFactory.ProduceDuckWing;
produceDelegate();
// 尝试让南京工厂生产鸭脖,这里会抛出异常
// produceDelegate = nanjingFactory.ProduceDuckNeck;
// produceDelegate();
// 长沙工厂只能生产鸭脖
produceDelegate = changshaFactory.ProduceDuckNeck;
produceDelegate();
// 尝试让长沙工厂生产鸭翅,这里会抛出异常
// produceDelegate = changshaFactory.ProduceDuckWing;
// produceDelegate();
Console.ReadKey();
}
}
在 Main 函数中,我们创建了三个工厂实例,并通过委托来调用它们各自的生产方法。需要注意的是,对于不能生产的产品,尝试调用相关方法会导致异常,这在实际开发中需要妥善处理。
五、运行结果
5.1 正常运行结果
5.2 异常运行结果
为每个工厂实现了生产鸭脖和鸭翅的方法。对于不能生产的产品,抛出了 NotImplementedException 异常,用于表明该类不支持该方法。
六、设计思路与难点
设计思路主要是通过接口定义统一的生产方法,不同的工厂类实现这个接口并提供具体的生产逻辑。使用委托来动态地调用这些方法,增加了代码的灵活性和可维护性。设计模式有助于提高代码的复用性和可维护性。
难点在于如何合理设计接口和工厂类,以确保它们能够正确地实现产品生产的逻辑。此外,对于不能生产的产品,需要妥善处理异常情况,防止程序崩溃。
七、小结
在这次作业中,主要完成了对周黑鸭工厂产品生产的统一管理功能的实现。通过使用C#编程语言,成功定义了一个接口IProductionFactory,并创建了三个实现该接口的工厂类:WuhanFactory、NanjingFactory和ChangshaFactory。每个工厂类都具有生产鸭脖和鸭翅的能力,但根据工厂的实际生产能力,某些工厂可能不支持生产特定产品。
在实现过程中,使用了委托ProductionDelegate来定义生产行为,并在主函数Main中通过创建工厂实例和调用生产委托来完成实际的生产操作。同时,也处理了不支持的生产行为,通过抛出NotSupportedException异常来提醒调用者工厂的生产限制。
通过这次作业,加深了对C#中接口、类、委托等关键知识点的理解,并学会了如何运用这些知识点来解决实际问题。同时,也认识到了在实际开发中,使用接口和委托可以提高代码的复用性和灵活性,使得代码更易于维护和扩展。
然而,也意识到自己在编程过程中还存在一些不足,比如对异常处理的理解还不够深入,有时候会出现不必要的异常抛出或者异常处理不够优雅的情况。
八、完整代码
https://github.com/juanniaoguilin/juanniao.git
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp12
{
//定义一个接口 IProductionFactory,它包含了生产鸭脖和鸭翅的方法。
//这样,我们可以为不同的工厂实现统一的接口,便于管理和使用。
public interface IProductionFactory
{
void ProduceDuckNeck();
void ProduceDuckWing();
}
//分别实现三个工厂类:WuhanFactory、NanjingFactory 和 ChangshaFactory
//它们各自实现了 IProductionFactory 接口。
public class WuhanFactory : IProductionFactory
{
public void ProduceDuckNeck()
{
Console.WriteLine("武汉工厂生产鸭脖");
}
public void ProduceDuckWing()
{
Console.WriteLine("武汉工厂生产鸭翅");
}
}
public class NanjingFactory : IProductionFactory
{
public void ProduceDuckNeck()
{
throw new NotImplementedException("南京工厂不能生产鸭脖");//对于不能生产的产品,我们抛出了 NotImplementedException 异常
//用于表明该类不支持该方法。
}
public void ProduceDuckWing()
{
Console.WriteLine("南京工厂生产鸭翅");
}
}
public class ChangshaFactory : IProductionFactory
{
public void ProduceDuckNeck()
{
Console.WriteLine("长沙工厂生产鸭脖");
}
public void ProduceDuckWing()
{
throw new NotImplementedException("长沙工厂不能生产鸭翅");
}
}
//使用委托 ProductionDelegate 定义生产委托。
//委托类似于 C 语言中的函数指针,可以引用一个具有特定签名的方法。
public delegate void ProductionDelegate();
class Program
{
//在 Main 函数中,我们创建不同工厂的实例,并通过生产委托进行生产。
static void Main(string[] args)
{
// 创建工厂实例
IProductionFactory wuhanFactory = new WuhanFactory();
IProductionFactory nanjingFactory = new NanjingFactory();
IProductionFactory changshaFactory = new ChangshaFactory();
// 定义生产委托
ProductionDelegate produceDelegate;
// 武汉工厂可以生产鸭脖和鸭翅
produceDelegate = wuhanFactory.ProduceDuckNeck;
produceDelegate(); // 调用委托执行方法
produceDelegate = wuhanFactory.ProduceDuckWing;
produceDelegate();
// 南京工厂只能生产鸭翅
produceDelegate = nanjingFactory.ProduceDuckWing;
produceDelegate();
// 尝试让南京工厂生产鸭脖,这里会抛出异常
//produceDelegate = nanjingFactory.ProduceDuckNeck;
//produceDelegate();
// 长沙工厂只能生产鸭脖
produceDelegate = changshaFactory.ProduceDuckNeck;
produceDelegate();
// 尝试让长沙工厂生产鸭翅,这里会抛出异常
produceDelegate = changshaFactory.ProduceDuckWing;
produceDelegate();
Console.ReadKey();
}
}
}