Windows程序设计课程作业一C#实现周黑鸭工厂生产管理

本文介绍了如何使用C#语言开发一个工厂生产管理系统,通过接口和委托技术,实现在不同工厂间统一管理和调度生产任务,同时阐述了面向对象设计原则在实际项目中的应用。
摘要由CSDN通过智能技术生成

一、前言

  在现代工业生产中,工厂化、自动化、信息化已成为企业提升生产效率、优化资源配置的重要手段。作为一名软件工程师,我们经常需要开发一些生产管理系统,来帮助企业实现生产过程的信息化管理。本文将以周黑鸭这一知名卤味休闲食品品牌为例,讲解如何使用C#语言,运用接口、委托等技术,实现一个简单的工厂生产管理系统,对周黑鸭不同工厂的产品生产进行统一管理。通过这个项目,我们不仅可以学习到接口、委托等C#编程技术的使用,还能理解面向对象设计原则在实际项目中的应用。同时,这个项目也反映了现实生产管理中的一些共性问题,如产品标准化、生产流程抽象等,具有一定的实际意义。

二、需求分析

2.1 业务背景

周黑鸭是一家发展迅速的卤味休闲食品品牌,在全国多地建有生产工厂,生产鸭脖、鸭翅等多种产品。为了提高生产管理的效率,公司决定开发一套生产管理系统,对各地工厂的生产进行统一管理。不同的工厂具有不同的生产能力,比如武汉工厂可以生产鸭脖和鸭翅,南京工厂只能生产鸭翅,长沙工厂只能生产鸭脖。公司希望通过这套系统,能够清晰地掌握各个工厂的生产能力,并能够灵活地调度不同工厂的生产任务。

2.2 功能需求

根据业务背景,总结出这个生产管理系统需要具备以下功能:

  1. 为不同的工厂定义统一的生产接口,包括生产鸭脖、生产鸭翅等方法。
  2. 每个工厂可以根据自身情况实现接口,灵活控制是否具备生产某种产品的能力。
  3. 提供一个查询接口,可以查询每个工厂的生产能力信息。
  4. 能够通过统一的调用方式,对不同工厂进行生产任务的调度。

有了这些具体的功能需求,我们就可以开始进行系统的设计了。

三、系统设计

3.1 接口层

接口层的主要职责是定义系统的抽象接口,为上层提供统一的调用方式,同时隐藏内部实现的细节。在这个系统中,接口层只有一个接口:

interface IProductionFactory
{
    void ProduceDuckNeck();
    void ProduceDuckWing();
    string GetProductionInfo();
}

这个IProductionFactory接口定义了所有工厂都需要实现的方法,包括生产鸭脖(ProduceDuckNeck)、生产鸭翅(ProduceDuckWing)和获取生产信息(GetProductionInfo)。通过定义这样一个接口,我们实现了以下目的:

  1. 统一了所有工厂的对外接口,使得上层调用者可以以相同的方式调用不同的工厂。
  2. 隐藏了各个工厂的内部实现细节,上层调用者只需要关注接口,而不需要了解具体的实现。
  3. 方便未来扩展新的工厂,只需要让新工厂实现这个接口即可,不需要修改已有的代码。

3.2 实现层

实现层的主要职责是提供接口的具体实现,完成实际的业务逻辑。在这个系统中,实现层包括三个具体的工厂类:

class WuhanFactory : IProductionFactory
{
    // 实现 IProductionFactory 接口的方法
}

class NanjingFactory : IProductionFactory
{
    // 实现 IProductionFactory 接口的方法
}

class ChangshaFactory : IProductionFactory
{
    // 实现 IProductionFactory 接口的方法
}

这三个工厂类都实现了IProductionFactory接口,但它们的具体实现是不同的,反映了不同工厂的生产能力。比如,武汉工厂可以生产鸭脖和鸭翅,而南京工厂只能生产鸭翅。通过这种实现方式,我们实现了以下目的:

  1. 将接口的实现与接口的定义分离,符合了"接口隔离原则"。
  2. 每个工厂类只负责自己的生产逻辑,符合了"单一职责原则"。
  3. 新增或修改某个工厂的生产逻辑,不会影响到其他工厂,符合了"开闭原则"。

 3.3 调用层

调用层是这个系统的最上层,它直接面向客户端,接收客户端的请求,并调用下层(即实现层)的方法来完成具体的业务逻辑。在这个系统中,调用层的代码主要集中在Main函数中。

3.3.1 创建工厂实例

Main函数的开始,创建了三个不同工厂的实例:

WuhanFactory wuhanFactory = new WuhanFactory();
NanjingFactory nanjingFactory = new NanjingFactory();
ChangshaFactory changshaFactory = new ChangshaFactory();

这个过程实际上是一种简单的依赖注入(Dependency Injection)。在上层(调用层)创建下层(实现层)的实例,然后在上层中使用这些实例。这样做的好处是,上层不需要关心这些实例的具体创建过程,只需要知道它们实现了IProductionFactory接口即可。这提高了系统的灵活性和可测试性。

3.3.2 输出工厂信息

调用各个工厂实例的GetProductionInfo()方法,输出它们的生产信息:

Console.WriteLine(wuhanFactory.GetProductionInfo());
Console.WriteLine("------------------------");
Console.WriteLine(nanjingFactory.GetProductionInfo());
Console.WriteLine("------------------------");
Console.WriteLine(changshaFactory.GetProductionInfo());
Console.WriteLine("------------------------");

尽管wuhanFactorynanjingFactorychangshaFactory是不同的类的实例,但它们都实现了IProductionFactory接口,所以可以以相同的方式调用它们的GetProductionInfo()方法。这体现了接口的一个重要作用:提供统一的调用方式。

3.3.3使用委托调用

使用委托来调用各个工厂的生产方法:

ProductionDelegate wuhanProduction = new ProductionDelegate(wuhanFactory.ProduceDuckNeck);
wuhanProduction += wuhanFactory.ProduceDuckWing;
wuhanProduction();

ProductionDelegate nanjingProduction = new ProductionDelegate(nanjingFactory.ProduceDuckNeck);
nanjingProduction += nanjingFactory.ProduceDuckWing;
nanjingProduction();

ProductionDelegate changshaProduction = new ProductionDelegate(changshaFactory.ProduceDuckNeck);
changshaProduction += changshaFactory.ProduceDuckWing;
changshaProduction();

这个过程展示了委托的强大之处。创建一个ProductionDelegate委托的实例,并将某个工厂的ProduceDuckNeck()方法赋给它。再使用+=操作符,将同一工厂的ProduceDuckWing()方法也赋给这个委托实例。最后调用这个委托实例,它就会依次调用之前赋给它的两个方法。这种调用方式非常灵活。在运行时决定要调用哪个工厂的哪些方法,而不需要修改代码。这在某些需要动态调整生产计划的场景下非常有用。

3.4调用层的作用

  1. 创建并组装下层的实例(工厂实例)。
  2. 接收客户端的请求(在这里是运行Main函数),并调用下层的方法来完成请求。
  3. 使用接口来统一不同实例的调用方式。
  4. 使用委托来实现灵活的调用策略。

可以说,调用层是整个系统的入口和控制中心。它负责协调各个部分的工作,使整个系统能够正常运转。

3.5调用层的优点

调用层的设计体现了几个重要的设计原则和模式:

  1. 依赖倒置原则(Dependency Inversion Principle):上层(调用层)依赖下层(实现层)的抽象(接口),而不是具体的实现。这提高了系统的灵活性和可维护性。
  2. 控制反转(Inversion of Control):上层(调用层)不直接创建下层(实现层)的实例,而是通过某种方式(如依赖注入)获得这些实例。这使得上层和下层解耦,提高了系统的可测试性。
  3. 策略模式(Strategy Pattern):使用委托,我们可以在运行时改变对象的行为(即调用不同的方法)。这实际上是一种策略模式,它提高了系统的灵活性和可适应性。

当然,调用层的设计也不是完美的。比如,它现在只能处理固定的三个工厂,如果要增加新的工厂,就需要修改Main函数的代码。这违反了"开闭原则"(Open-Closed Principle)。可以考虑使用配置文件或者反射机制来动态创建工厂实例,以提高系统的可扩展性。

四、代码总览

using System;
using System.Text;

// 定义接口 IProductionFactory
interface IProductionFactory
{
    void ProduceDuckNeck();
    void ProduceDuckWing();
    string GetProductionInfo();
}

// 定义武汉工厂类,实现 IProductionFactory 接口
class WuhanFactory : IProductionFactory
{
    public void ProduceDuckNeck()
    {
        Console.WriteLine("武汉工厂生产鸭脖");
    }

    public void ProduceDuckWing()
    {
        Console.WriteLine("武汉工厂生产鸭翅");
    }

    public string GetProductionInfo()
    {
        StringBuilder sb = new StringBuilder();
        sb.AppendLine("武汉工厂生产信息:");
        sb.AppendLine("- 可生产鸭脖");
        sb.AppendLine("- 可生产鸭翅");
        return sb.ToString();
    }
}

// 定义南京工厂类,实现 IProductionFactory 接口
class NanjingFactory : IProductionFactory
{
    public void ProduceDuckNeck()
    {
        Console.WriteLine("南京工厂不生产鸭脖");
    }

    public void ProduceDuckWing()
    {
        Console.WriteLine("南京工厂生产鸭翅");
    }

    public string GetProductionInfo()
    {
        StringBuilder sb = new StringBuilder();
        sb.AppendLine("南京工厂生产信息:");
        sb.AppendLine("- 不生产鸭脖");
        sb.AppendLine("- 可生产鸭翅");
        return sb.ToString();
    }
}

// 定义长沙工厂类,实现 IProductionFactory 接口
class ChangshaFactory : IProductionFactory
{
    public void ProduceDuckNeck()
    {
        Console.WriteLine("长沙工厂生产鸭脖");
    }

    public void ProduceDuckWing()
    {
        Console.WriteLine("长沙工厂不生产鸭翅");
    }

    public string GetProductionInfo()
    {
        StringBuilder sb = new StringBuilder();
        sb.AppendLine("长沙工厂生产信息:");
        sb.AppendLine("- 可生产鸭脖");
        sb.AppendLine("- 不生产鸭翅");
        return sb.ToString();
    }
}

// 定义生产委托
delegate void ProductionDelegate();

class Program
{
    static void Main(string[] args)
    {
        // 创建不同工厂的实例
        WuhanFactory wuhanFactory = new WuhanFactory();
        NanjingFactory nanjingFactory = new NanjingFactory();
        ChangshaFactory changshaFactory = new ChangshaFactory();

        // 输出工厂的生产信息
        Console.WriteLine(wuhanFactory.GetProductionInfo());
        Console.WriteLine("------------------------");
        Console.WriteLine(nanjingFactory.GetProductionInfo());
        Console.WriteLine("------------------------");
        Console.WriteLine(changshaFactory.GetProductionInfo());
        Console.WriteLine("------------------------");

        // 使用生产委托进行生产
        ProductionDelegate wuhanProduction = new ProductionDelegate(wuhanFactory.ProduceDuckNeck);
        wuhanProduction += wuhanFactory.ProduceDuckWing;
        wuhanProduction();

        ProductionDelegate nanjingProduction = new ProductionDelegate(nanjingFactory.ProduceDuckNeck);
        nanjingProduction += nanjingFactory.ProduceDuckWing;
        nanjingProduction();

        ProductionDelegate changshaProduction = new ProductionDelegate(changshaFactory.ProduceDuckNeck);
        changshaProduction += changshaFactory.ProduceDuckWing;
        changshaProduction();

        Console.ReadLine();
    }
}

运行结果

五、总结

这个工厂生产管理系统虽然简单,但却展示了面向对象设计的多个重要原则和技术。它使用接口来定义统一的操作,使用具体的类来实现不同的功能,使用委托来实现动态调用。这种设计使得系统变得灵活、可扩展,同时又保持了良好的结构和可读性。对我来说,设计并实现这个系统是一次非常有益的学习经历。它让我对面向对象编程有了更深入的理解,也让我体会到了设计模式和原则的重要性。我相信,通过不断地学习和实践,我们每个人都能够掌握面向对象设计的精髓,创建出真正优秀的软件系统。

六、优化创新(借助大模型CLAUDE 3 OPUS)

6.1使用反射动态创建工厂实例

在原始版本中,在Main方法中直接创建了具体的工厂实例:

WuhanFactory wuhanFactory = new WuhanFactory();
NanjingFactory nanjingFactory = new NanjingFactory();
ChangshaFactory changshaFactory = new ChangshaFactory();

这种方式有一个问题:如果需要增加或删除工厂,就必须修改Main方法的代码。这违反了"开闭原则"(对扩展开放,对修改关闭)。在新版本中,使用反射来动态创建工厂实例:

List<IProductionFactory> factories = CreateFactoryInstances();

CreateFactoryInstances方法的实现如下:

static List<IProductionFactory> CreateFactoryInstances()
{
    var factoryTypes = Assembly.GetExecutingAssembly().GetTypes()
        .Where(t => typeof(IProductionFactory).IsAssignableFrom(t) && !t.IsInterface);

    var factories = new List<IProductionFactory>();
    foreach (var type in factoryTypes)
    {
        var factory = (IProductionFactory)Activator.CreateInstance(type);
        factories.Add(factory);
    }

    return factories;
}

这个方法使用反射获取所有实现了IProductionFactory接口的类型,然后动态创建这些类型的实例,并返回一个包含所有工厂实例的列表。这种方式的优点是,如果增加或删除工厂,只需要添加或删除相应的工厂类,而不需要修改Main方法。这满足了"开闭原则",使得系统更加灵活和可扩展。

6.2使用泛型和LINQ简化代码(拓展知识)

6.2.1泛型和LINQ的基本概念

  泛型(Generics)是C#中一种允许在强类型编程中编写代码的功能,它提供了编写可重用代码的能力。泛型允许我们延迟编写类或方法中的编程元素的数据类型的规范,直到实际在程序中使用它的时候。换句话说,泛型允许我们编写一个可以与任何数据类型一起工作的类或方法。          LINQ(Language Integrated Query)是一组技术的统称,基于C#和Visual Basic中的查询表达式。 LINQ的查询提供了一种通用模式,用于对数据源进行操作。 LINQ可以用于任何实现了IEnumerable<T>或IQueryable<T>接口的数据源。

1.使用泛型方法

泛型方法允许我们为方法参数和返回值指定占位符类型。这里是一个泛型方法的基本格式:

public static T MethodName<T>(T param)
{
    // 方法体
}

在这个格式中,T是类型参数,它是方法的泛型类型。当调用这个方法时,需要指定T的具体类型。

2.使用LINQ

from item in collection
where condition
select item

在这个格式中,collection是要查询的数据源,condition是一个布尔表达式,用于过滤数据,item是满足条件的元素。

3.结合泛型和LINQ

使用了泛型(List<IProductionFactory>)和LINQ(Where方法)来简化代码。例如,在CreateFactoryInstances方法中,我们使用Where方法来筛选出所有实现了IProductionFactory接口的类型:

var factoryTypes = Assembly.GetExecutingAssembly().GetTypes()
    .Where(t => typeof(IProductionFactory).IsAssignableFrom(t) && !t.IsInterface);

 6.3使用接口实现多态

Main方法中,只使用IProductionFactory接口来引用工厂对象,而不关心具体的工厂类型: 

foreach (var factory in factories)
{
    ProductionDelegate production = new ProductionDelegate(factory.ProduceDuckNeck);
    production += factory.ProduceDuckWing;
    production();
    Console.WriteLine("------------------------");
}

这种方式体现了"依赖倒置原则"(依赖于抽象,而不是具体),使得高层模块(如Main方法)不依赖于低层模块(如具体的工厂类),提高了系统的灵活性和可维护性。新版本的代码在原始版本的基础上,通过使用反射、泛型、LINQ等技术,以及更加充分地利用接口的多态特性,使得系统更加灵活、可扩展、易维护。这些都是非常值得学习和借鉴的创新点。

6.4优化版本代码展示

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;

// 定义接口 IProductionFactory
interface IProductionFactory
{
    void ProduceDuckNeck();
    void ProduceDuckWing();
    string GetProductionInfo();
}

// 定义武汉工厂类,实现 IProductionFactory 接口
class WuhanFactory : IProductionFactory
{
    public void ProduceDuckNeck()
    {
        Console.WriteLine("武汉工厂生产鸭脖");
    }

    public void ProduceDuckWing()
    {
        Console.WriteLine("武汉工厂生产鸭翅");
    }

    public string GetProductionInfo()
    {
        StringBuilder sb = new StringBuilder();
        sb.AppendLine("武汉工厂生产信息:");
        sb.AppendLine("- 可生产鸭脖");
        sb.AppendLine("- 可生产鸭翅");
        return sb.ToString();
    }
}

// 定义南京工厂类,实现 IProductionFactory 接口
class NanjingFactory : IProductionFactory
{
    public void ProduceDuckNeck()
    {
        Console.WriteLine("南京工厂不生产鸭脖");
    }

    public void ProduceDuckWing()
    {
        Console.WriteLine("南京工厂生产鸭翅");
    }

    public string GetProductionInfo()
    {
        StringBuilder sb = new StringBuilder();
        sb.AppendLine("南京工厂生产信息:");
        sb.AppendLine("- 不生产鸭脖");
        sb.AppendLine("- 可生产鸭翅");
        return sb.ToString();
    }
}

// 定义长沙工厂类,实现 IProductionFactory 接口
class ChangshaFactory : IProductionFactory
{
    public void ProduceDuckNeck()
    {
        Console.WriteLine("长沙工厂生产鸭脖");
    }

    public void ProduceDuckWing()
    {
        Console.WriteLine("长沙工厂不生产鸭翅");
    }

    public string GetProductionInfo()
    {
        StringBuilder sb = new StringBuilder();
        sb.AppendLine("长沙工厂生产信息:");
        sb.AppendLine("- 可生产鸭脖");
        sb.AppendLine("- 不生产鸭翅");
        return sb.ToString();
    }
}

// 定义生产委托
delegate void ProductionDelegate();

class Program
{
    static void Main(string[] args)
    {
        // 使用反射动态创建工厂实例
        List<IProductionFactory> factories = CreateFactoryInstances();

        // 输出工厂的生产信息
        foreach (var factory in factories)
        {
            Console.WriteLine(factory.GetProductionInfo());
            Console.WriteLine("------------------------");
        }

        // 使用生产委托进行生产
        foreach (var factory in factories)
        {
            ProductionDelegate production = new ProductionDelegate(factory.ProduceDuckNeck);
            production += factory.ProduceDuckWing;
            production();
            Console.WriteLine("------------------------");
        }

        Console.ReadLine();
    }

    static List<IProductionFactory> CreateFactoryInstances()
    {
        // 获取所有实现了 IProductionFactory 接口的类型
        var factoryTypes = Assembly.GetExecutingAssembly().GetTypes()
            .Where(t => typeof(IProductionFactory).IsAssignableFrom(t) && !t.IsInterface);

        // 创建所有工厂的实例
        var factories = new List<IProductionFactory>();
        foreach (var type in factoryTypes)
        {
            var factory = (IProductionFactory)Activator.CreateInstance(type);
            factories.Add(factory);
        }

        return factories;
    }
}

  • 33
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值