首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >基于C#和OOP的简单产品库存软件

基于C#和OOP的简单产品库存软件
EN

Code Review用户
提问于 2016-12-30 16:02:37
回答 3查看 15.6K关注 0票数 6

作为编码练习清单的一部分,我做了这个小程序。该列表提出了一种小型软件的编码,该软件应该管理产品的库存。以下是我们的要求:

产品库存项目-创建一个管理产品库存的应用程序。创建一个具有价格、id和数量的产品类。然后创建一个库存类,它可以跟踪各种产品,并可以对库存价值进行汇总。

这是我在这个应用程序中实现的特性:

  • 添加产品的可能性。
  • 数据作为JSON对象的本地存储。
  • 所有产品的清单。
  • 移除特定产品的可能性。
  • 你可以清空妓女的存货。
  • 获得存货的价值(所有物品的价格之和)。
  • 将产品清点到库存中。
  • 获取单位计数(所有项目的数量之和)。

我已经用两个项目创建了一个Visual解决方案:

  • IvManager.ConsoleApp -演示部分。
  • IvManager.Business -包含业务逻辑的库。

IvManager.Business中,我有三个类:

产品-我必须管理的产品对象。

库存--这是一个静态类,包含一个产品列表,并有几种方法:

  • Load() -私有方法,它将数据从本地文件加载到产品的Inventory.Products列表中。
  • 保存()-将产品列表保存到磁盘的私有方法(以JSON格式)。
  • RemoveProduct() -根据编码将特定的产品移除到其id。
  • Add() --在库存中添加一个新产品。
  • GetNewId() -根据列表中的项获取可用的id。
  • GetProductCount() -获取库存中产品的数量。
  • GetUnitCount() -获取所有项的数量之和。
  • GetInventoryValue() -所有物品的价格之和。
  • ClearInventory() -从库存中删除所有项目。

DataManager -处理从磁盘中保存和恢复数据的私有静态类。它有两种方法:

  • LoadProducts() -从磁盘加载数据。
  • SaveProducts() -将数据保存到磁盘。

Product.cs:

代码语言:javascript
复制
[Serializable]
public class Product
{                        
    public int Id { get; set; }
    public string Name { get; set; }
    public decimal Price { get; set; }
    public int Quantity { get; set; }
}

Inventory.cs代码:

代码语言:javascript
复制
public static class Inventory
{
    public static List<Product> products;
    public static List<Product> Products
    {
        get
        {
            if (products.Count == 0)
            {
                Load();
            }

            return products;
        }
        set { products = value; }
    }

    static Inventory()
    {
        Products = new List<Product>();
    }

    private static void Load()
    {
        Products = DataManager.LoadProducts();
    }

    private static void Save()
    {
        DataManager.SaveProducts(Products);
    }

    public static void RemoveProduct(int productId)
    {
        Inventory.Products.RemoveAll(x => x.Id == productId);
        Save();
    }

    public static void Add(Product product)
    {
        Products.Add(product);
        Save();
    }

    public static int GetNewId()
    {
        int id;
        if (Inventory.Products.Count == 0)
            id = 1;
        else
        {
            id = Inventory.Products.Last().Id + 1;
        }

        return id;
    }

    public static int GetProductCount()
    {
        return Inventory.Products.Count();
    }

    public static int GetUnitCount()
    {
        return Inventory.Products.Select(x => x.Quantity).Sum();
    }

    public static decimal GetInventoryValue()
    {
        return Inventory.Products.Select(x => (x.Price * x.Quantity)).Sum();
    }
    public static void ClearInventory()
    {
        Inventory.Products.Clear();
        Save();
    }
}

DataManager.cs代码:

代码语言:javascript
复制
static class DataManager
{
    private static string dataPath = "data.json";

    public static List<Product> LoadProducts()
    {
        List<Product> listOfProducts = new List<Product>();

        if (File.Exists(dataPath))
        {
            string json = File.ReadAllText("data.json");
            if (!string.IsNullOrWhiteSpace(json))
            {
                listOfProducts = JsonConvert.DeserializeObject<List<Product>>(json);
            }
        };           

        return listOfProducts;
    }        

    public static void SaveProducts(List<Product> productsToSave)
    {
        if (!File.Exists(dataPath))
            File.Create(dataPath);

        string json = JsonConvert.SerializeObject(productsToSave);

        File.WriteAllText(dataPath, json);
    }
}

下面是完整的代码,包括表示为:https://gist.github.com/andradedearthur/20d6fc4b1325c11ecc7822e0bdb19fe8的控制台应用程序

我是C#和面向对象的学生,所以我想知道在这段代码中可以改进什么。对我来说最大的挑战可能是定义每个方法应该在哪个类中运行,以及每个类的责任应该是什么。欢迎任何反馈意见。

EN

回答 3

Code Review用户

回答已采纳

发布于 2016-12-30 17:07:01

  1. :私有静态空存(){DataManager.SaveProducts(产品);}公共静态空存(Int productId) { Inventory.Products.RemoveAll(x => x.Id == productId);Save();}公共静态空添加(产品){Products.Add(产品);Save();}那么每次添加产品或删除产品时,都会重新保存所有产品?如果你有上百万的产品呢?这难道不是过度杀戮和低效吗?(回答:是)
  2. 什么东西都是静态的?背后的好理由是什么?我可以看到至少Inventory类不是静态的一个很好的原因-它有状态!摆脱所有这些静态的东西,然后创建一个你需要的每个类的实例,并正常使用它。
  3. :public静态int GetNewId() { int id;if (Inventory.Products.Count == 0) id = 1;in { id = Inventory.Products.Last().Id + 1;}返回id;}这是一个非常糟糕的主意,因为如何保证产品总是以完全相同的顺序存储和加载,以及它们在列表中的顺序永远不会改变?(没有,特别是当列表是可公开设置和可修改的时候。)您可以很容易地获得多个具有相同ID的产品。
  4. DataManager应该是一个存储库。
票数 7
EN

Code Review用户

发布于 2016-12-30 16:20:05

很少有人注意到:

  • 为什么你有2 public static List<Product>?如果其中的一个打算作为备份字段,那么它应该是私有的,而不是公共的,就像这样,您并不是真正地将属性封装到任何外部访问。私有静态List产品;公共静态List产品{ get { if (products.Count == 0) { Load();}返回产品;} set { Products = value;}}
  • 只有一份存货吗?对我来说,这听起来更像是一个普通的类,而不是静态的。您仍然可以在非静态类中拥有公共静态成员。
  • 不需要始终显式指向包含类的冗余限定符,例如Inventory.Foo()可以变成简单的Foo()

公共静态int GetNewId() { int id;if (Products.Count == 0) { id = 1;} else { id = Products.Last().Id + 1;}返回id;}

您还可以进一步缩短以下内容:

代码语言:javascript
复制
public static int GetNewId()
{
    return Products.Count == 0 ? 1 : Products[products.Count - 1].Id + 1;
}
  • 表达式体成员用于单行返回方法,可以使用表达式体:

公共静态int GetNewId() {返回Products.Count == 0?1: Productsproducts.Count -1.Id + 1;}公共静态int GetProductCount() {返回Products.Count;}公共静态int GetUnitCount() {返回Products.Select(x => x.Quantity).Sum();} public静态十进制GetInventoryValue() {返回Products.Select(x => (x.Price *x.Quantity))x.Price();

可以成为:

代码语言:javascript
复制
public static int GetNewId() => Products.Count == 0 ? 1 : Products[products.Count - 1].Id + 1;

public static int GetProductCount() => Products.Count;

public static int GetUnitCount() => Products.Select(x => x.Quantity).Sum();

public static decimal GetInventoryValue() => Products.Select(x => (x.Price * x.Quantity)).Sum();

但是总的来说,它看起来很不错,保持它!:)

票数 5
EN

Code Review用户

发布于 2016-12-30 18:21:25

我不同意你的要求

产品库存项目-创建一个管理产品库存的应用程序。创建一个具有价格、id和数量的产品类。然后创建一个库存类,它可以跟踪各种产品,并可以对库存价值进行汇总。

我会认为身份是独一无二的。您有一个GetNewId(),但是use不是强制的,甚至不能保证返回唯一的id。

公共静态List产品{ get { if (products.Count == 0) { Load();}返回产品;} set {=====;}

假设Load()实际上返回0。这将在每次获取时重新加载()。它是静态的。在构造函数中加载即可。

为什么连套都有?它允许使用创建一个新的List<Product>并完全替换现有的列表。

代码语言:javascript
复制
public static void Add(Product product)

不检查唯一的id,即使它检查了,也可以通过直接添加到产品来绕过它。

用户可以直接从产品中添加或删除,并且不会保存。

我认为更好的设计是让Product实现对象,这样您就可以平等地执行id。然后,对于产品,使用HashSet来执行唯一性。

产品列表应该是只读的

甚至没有理由让Product拥有公共构造函数

公共int Id { get;set;}

用户不应该能够修改Id

总之,解决方案缺乏库存控制。

票数 2
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/151265

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档