C#实现一个控制台的点餐系统完整攻略
需求分析
点餐系统需要实现以下功能:
- 展示菜单
- 输入点餐内容和数量
- 确认订单及计算总价
- 退出程序
设计实现
数据结构
点餐系统需要用到的数据结构有:
- 菜品类别 Category
- 菜品类 Dish
- 菜单类 Menu
- 订单类 Order
具体定义如下:
// 菜品类别
public enum Category
{
饮料,
小吃,
主食
}
// 菜品类
public class Dish
{
public string Name { get; }
public Category Category { get; }
public decimal Price { get; }
public Dish(string name, Category category, decimal price)
{
Name = name;
Category = category;
Price = price;
}
}
// 菜单类
public class Menu
{
private readonly List<Dish> _dishes;
public Menu()
{
_dishes = new List<Dish>
{
new Dish("可乐", Category.饮料, 2.00m),
new Dish("薯条", Category.小吃, 5.50m),
new Dish("烤鸡翅", Category.小吃, 12.00m),
new Dish("汉堡", Category.主食, 15.50m),
new Dish("烤肉拌饭", Category.主食, 18.00m)
};
}
public IReadOnlyList<Dish> Dishes => _dishes.AsReadOnly();
}
// 订单类
public class Order
{
private readonly Dictionary<Dish, int> _items;
public Order()
{
_items = new Dictionary<Dish, int>();
}
public void AddItem(Dish item, int quantity)
{
if (quantity < 0)
{
throw new ArgumentException("数量不能为负数。", nameof(quantity));
}
if (quantity == 0)
{
// 数量为 0,删除该项
RemoveItem(item);
}
else
{
_items[item] = quantity;
}
}
public void RemoveItem(Dish item)
{
_items.Remove(item);
}
public IReadOnlyDictionary<Dish, int> GetItems()
{
return _items;
}
public decimal GetTotalPrice()
{
return _items.Sum(item => item.Key.Price * item.Value);
}
}
控制台界面
控制台界面需要显示菜单、接收用户输入、显示订单等信息。实现如下:
public class ConsoleUI
{
private readonly Menu _menu;
private readonly Order _order;
public ConsoleUI()
{
_menu = new Menu();
_order = new Order();
}
public void Run()
{
ShowMenu();
while (true)
{
ReadInput(out var dish, out var quantity);
if (dish == null)
{
// 用户输入 quit 退出程序
break;
}
_order.AddItem(dish, quantity);
ShowOrder();
}
Console.WriteLine("感谢光临!");
}
private void ShowMenu()
{
Console.WriteLine("欢迎光临,我们的菜单如下:");
foreach (var group in _menu.Dishes.GroupBy(dish => dish.Category))
{
Console.WriteLine(group.Key);
foreach (var dish in group)
{
Console.WriteLine($"{dish.Name, -20} {dish.Price, 6}");
}
Console.WriteLine();
}
}
private void ShowOrder()
{
Console.WriteLine($"当前订单:共 {_order.GetItems().Count} 件商品,总价 {_order.GetTotalPrice():C2}");
foreach (var item in _order.GetItems())
{
Console.WriteLine($"{item.Key.Name, -20} {item.Value, 2} × {item.Key.Price, 6:C2} = {(item.Key.Price * item.Value), 8:C2}");
}
}
private void ReadInput(out Dish dish, out int quantity)
{
Console.Write("请输入菜名(quit 结束):");
var input = Console.ReadLine();
if (string.IsNullOrEmpty(input))
{
dish = null;
quantity = 0;
return;
}
if (input == "quit")
{
dish = null;
quantity = 0;
return;
}
var dishes = _menu.Dishes.Where(d => d.Name.StartsWith(input, StringComparison.OrdinalIgnoreCase)).ToList();
if (dishes.Count == 0)
{
Console.WriteLine("找不到该菜品。");
ReadInput(out dish, out quantity);
return;
}
Console.Write("请输入数量:");
input = Console.ReadLine();
if (!int.TryParse(input, out quantity))
{
Console.WriteLine("请输入有效的数量。");
ReadInput(out dish, out quantity);
return;
}
if (quantity <= 0)
{
Console.WriteLine("数量不能为负数或零。");
ReadInput(out dish, out quantity);
return;
}
dish = dishes.Count == 1 ? dishes[0] : SelectDish(dishes);
}
private static Dish SelectDish(List<Dish> dishes)
{
Console.WriteLine("请选择菜品:");
for (var i = 0; i < dishes.Count; i++)
{
Console.WriteLine($"{i + 1}: {dishes[i].Name}");
}
while (true)
{
var input = Console.ReadLine();
if (!int.TryParse(input, out var index))
{
Console.WriteLine("请输入有效的数字编号。");
continue;
}
if (index < 1 || index > dishes.Count)
{
Console.WriteLine("编号超出范围。");
continue;
}
return dishes[index - 1];
}
}
}
示例说明
下面是两个示例说明:
示例一
用户输入的序列为:
汉堡
2
程序会输出当前订单并等待用户输入:
当前订单:共 1 件商品,总价 31.00元
汉堡 2 × 15.50 = 31.00
示例二
用户输入的序列为:
卤肉饭
程序会提示找不到该菜品并要求用户重新输入:
找不到该菜品。
请输入菜名(quit 结束):
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C#实现一个控制台的点餐系统 - Python技术站