C# 保存餐厅菜单的合适数据结构
我必须实现一个类(用C#,但我认为这并不重要)来保存餐厅菜单的菜单项列表。有两个要求: 每个项目可能都有一个类别,然后将使用该类别输出此项目。例如,所有“饮料”类物品应在“饮料”标签下输出 项目可能是顶级的,即没有类别。输出这些项目时,上面不应有任何标签或带有特定标签 此类的用户应该能够轻松添加项目,如果项目有类别,则指定其类别 我当前的解决方案非常脏,它要求类的用户提供一个类别,不管该项是否有。也就是说,当项目没有任何类别时,用户必须创建某种默认类别C# 保存餐厅菜单的合适数据结构,c#,oop,data-structures,C#,Oop,Data Structures,我必须实现一个类(用C#,但我认为这并不重要)来保存餐厅菜单的菜单项列表。有两个要求: 每个项目可能都有一个类别,然后将使用该类别输出此项目。例如,所有“饮料”类物品应在“饮料”标签下输出 项目可能是顶级的,即没有类别。输出这些项目时,上面不应有任何标签或带有特定标签 此类的用户应该能够轻松添加项目,如果项目有类别,则指定其类别 我当前的解决方案非常脏,它要求类的用户提供一个类别,不管该项是否有。也就是说,当项目没有任何类别时,用户必须创建某种默认类别 public class Menu {
public class Menu
{
public ICollection<Category> Categories { get; set; }
}
public class Category
{
public string Name { get; set; }
public ICollection<MenuItem> Items { get; set; }
}
public class MenuItem
{
public string Name { get; set; }
public decimal Price { get; set; }
public Category Category { get; set; }
}
公共类菜单
{
公共ICollection类别{get;set;}
}
公共类类别
{
公共字符串名称{get;set;}
公共ICollection项{get;set;}
}
公共类菜单项
{
公共字符串名称{get;set;}
公共十进制价格{get;set;}
公共类别{get;set;}
}
什么样的数据结构/类设计能更好地解决这个问题
编辑:
它应该以某种方式打印出来。更准确地说,这是订购系统中的菜单模型,也可能以文本形式出现。该模型从解析器中获取,然后表示给用户,以便用户可以手动编辑它。
例如,用户可能会在菜单字段中写入类似的内容
项目1{22}
项目2{33}
--类别1--
项目3{44}
然后将其转换回菜单,然后,当提交菜单时,以一种奇特的方式输出给最终用户
更新结构:
经过一些考虑,我想出了这个设计:
public abstract class MenuItem
{
public string Name { get; set; }
public abstract bool IsCategory();
public abstract decimal Price();
public abstract ICollection<MenuItem> Items();
}
public class Dish : MenuItem
{
private readonly decimal price;
public Dish(decimal price)
{
this.price = price;
}
public override bool IsCategory()
{
return false;
}
public override decimal Price()
{
return price;
}
public override ICollection<MenuItem> Items()
{
return new List<MenuItem>(); //or null
}
}
public class Category : MenuItem
{
public ICollection<MenuItem> Items { get; private set; }
public Category() : this(new List<MenuItem>()) { }
public Category(ICollection<MenuItem> items)
{
this.Items = items;
}
public override bool IsCategory()
{
return true;
}
public override decimal Price()
{
return 0; //or make price nullable and return null
}
public override ICollection<MenuItem> Items()
{
return Items;
}
}
公共抽象类菜单项
{
公共字符串名称{get;set;}
公共抽象类();
公开摘要十进制价格();
公共摘要i收集项目();
}
公共类菜肴:MenuItem
{
私有只读十进制价格;
公共菜(十进制价格)
{
这个价格=价格;
}
公共覆盖布尔分类()
{
返回false;
}
公共覆盖十进制价格()
{
退货价格;
}
公共覆盖ICollection项()
{
返回新列表();//或null
}
}
公共类类别:MenuItem
{
公共ICollection项{get;private set;}
公共类别():此(新列表()){}
公共类别(i收集项目)
{
这个。项目=项目;
}
公共覆盖布尔分类()
{
返回true;
}
公共覆盖十进制价格()
{
返回0;//或使价格为null并返回null
}
公共覆盖ICollection项()
{
退货项目;
}
}
“菜单”中有一个菜单项列表。这个问题可能有点过于宽泛,因为我脑子里突然出现了几个问题。例如,副订单可以列在几个地方吗?它们是不同的菜单项,还是你想把菜单项提到几个地方,这样,如果你改变一道主菜的额外土豆价格,那么所有这些额外的东西都会改变,还是只改变你改变的那一个?你需要描述吗?本地化描述如何(例如,如果你是一家意大利餐厅,你可能想发布意大利命名菜肴,但也要有英文描述或名称)。换句话说,这个问题可能更多地是关于需求的讨论,而不是它们的实际实现。我想说的是,对于一个基本菜单,您现有的代码,减去集合属性设置器,乍一看对我来说似乎很好。我建议您选择一个您应该表示的菜单的实际物理副本,或者至少是一个非常类似的副本,然后找出如何表示所有内容。例如,这是用来打印菜单的东西吗?或者只是在订购系统中处理它们?我建议实现两个类,实现一个公共接口
IMenu
,其中第一个类是“顶级”项,第二个类定义一个子级项。我想到的另一种可能性是将类别设置为NULL,这表示某个项目是顶级项目。在op post中添加了一个答案。