C# Composition - 不完全确定我是否正确实施
C# Composition - not fully sure I am implementing correctly
最近我学习了更多关于 C# OOP 的知识——特别是如何处理继承、组合和聚合。
我在练习任务的上下文中执行此操作,该任务要求为餐厅类型的服务构建订购 API。具体来说,该任务要求一个菜单。菜单可以有多种类型,例如午餐菜单、晚餐菜单等。每个菜单都有多个类别,例如开胃菜、主菜、甜点等。一个类别可以属于多个菜单。然后每个类别也有子类别,因此例如 Starter 可以有冷热选项。在子类别中然后有多个食物项目,因此对于午餐菜单(菜单)上的开胃菜(类别)中的热菜(子类别),可以有汤,比萨饼等
根据我对任务和 OOP 的理解,这将需要组合而不是继承。这是因为每个 Class 内部都有其他类型的 classes - 菜单有类别,类别有子类别等。
所以我构建了 classes 如下:
菜单 class:
public class Menu
{
public Menu()
{}
public Menu(long Id, string Name)
{
this.id = Id;
this.name = Name;
}
private long id;
private string name;
}
类别class:
public class Category
{
public Category()
{}
public Category(Menu menu, long categoryID, string Name)
{
this._menu = menu;
this.CategoryID = categoryID;
this.name = Name;
}
private Menu _menu;
public long CategoryID { get; set; }
private string name { get; set; }
}
子类别class:
public class Subcategory
{
public Subcategory()
{}
public Subcategory(Category category, int subcategoryID, string Name)
{
this._category = category;
this.SubcategoryID = subcategoryID;
this.name = Name;
}
private Category _category;
private long SubcategoryID { get; set; }
private string name { get; set; }
}
最后是 FoodItem class:
public class FoodItem
{
public FoodItem()
{}
public FoodItem(Subcategory subcategory, long Id, string Name, string Size)
{
this._subCategory = subcategory;
this.Id = Id;
this.name = Name;
this.size = Size;
}
private Subcategory _subCategory;
public long Id { get; set; }
public string name { get; set; }
public string size { get; set; }
}
所以我所做的是遵循在线示例 - 每个 subclass 中的 superclass 实例被创建并传递到构造函数中。这意味着子 class 不能存在,除非超级 class 也已创建 - 类别需要菜单,子类别需要类别,食品项目需要子类别。
我的问题是:
- 我现在遇到的问题是实例化 FoodItem。要创建一个 FoodItem,我是否需要创建一个 Menu 对象,然后创建一个 Category 对象并将 Menu 对象放入,创建一个子类别并将 Category 放入,然后创建一个 FoodItem 并将子类别放入?那是正确的吗?还是我只创建一个 FoodItem 而其余的自动创建?我认为第一个选项是正确的,但想澄清一下。
- 我假设组合是正确的方法是正确的吗?还是继承更好?
- 为了完成任务,我需要能够创建 FoodItems 和 post 到 API。假设我做问题 1 的方法是正确的,我将如何创建 FoodItem 需要的超级classes?
非常感谢任何方向。
您已确定您的菜单有类别,但以相反的方式实现了它(在您的代码中,您的类别有一个菜单)。引用从叶节点到父节点,而不是父节点包含对其包含的项目的引用集合。
关于您发布的内容,我发现另一件不寻常的事情是所有成员都是私人的。您可以向外界公开属性,有时您将需要一种方法来查看菜单中包含的数据并将其呈现给用户。
我会重写 类 使其看起来更像这样:
public class Menu
{
public Menu() { }
public Menu(long id, string name)
{
Id = id;
Name = name;
}
public long Id { get; }
public string Name { get; set; }
public List<Category> Categories { get; } = new List<Category>();
}
请注意,我对某些人使用了 get
,对其他人使用了 get/set
。这只是一个假设,但您通常不希望对象的 id 发生变化。同样,初始化列表并保留它 get
-only 意味着用户不必在每次使用它时都进行空检查。
添加到另一个答案。
类别没有父类别,但子类别有。但除此之外它们非常相似。所以我会考虑定义一个子类别作为类别的子类型。使它成为一个递归数据结构,允许子...子子类别。
public class SubCategory : Category
{
public SubCategory(Category Parent, ...) : base(...){
ParentCategory = Parent;
}
public Category ParentCategory { get; }
}
虽然您也可以消除子类别 class,方法是允许类别具有空父类别。
然后一个食品项目有一个类别,它可以是一个子类别的实例。由于每个菜单都有不同的食物,但可能有相同的类别。您应该将其建模为按类别分组的食品列表。也许;
public class Menu {
public List<FoodItem> FoodItems { get; } = new List<FoodItem>();
public IGrouping<Category,FoodItems> GroupItems =>
FoodItems.GroupBy(f => f.Category);
}
最近我学习了更多关于 C# OOP 的知识——特别是如何处理继承、组合和聚合。
我在练习任务的上下文中执行此操作,该任务要求为餐厅类型的服务构建订购 API。具体来说,该任务要求一个菜单。菜单可以有多种类型,例如午餐菜单、晚餐菜单等。每个菜单都有多个类别,例如开胃菜、主菜、甜点等。一个类别可以属于多个菜单。然后每个类别也有子类别,因此例如 Starter 可以有冷热选项。在子类别中然后有多个食物项目,因此对于午餐菜单(菜单)上的开胃菜(类别)中的热菜(子类别),可以有汤,比萨饼等
根据我对任务和 OOP 的理解,这将需要组合而不是继承。这是因为每个 Class 内部都有其他类型的 classes - 菜单有类别,类别有子类别等。
所以我构建了 classes 如下:
菜单 class:
public class Menu
{
public Menu()
{}
public Menu(long Id, string Name)
{
this.id = Id;
this.name = Name;
}
private long id;
private string name;
}
类别class:
public class Category
{
public Category()
{}
public Category(Menu menu, long categoryID, string Name)
{
this._menu = menu;
this.CategoryID = categoryID;
this.name = Name;
}
private Menu _menu;
public long CategoryID { get; set; }
private string name { get; set; }
}
子类别class:
public class Subcategory
{
public Subcategory()
{}
public Subcategory(Category category, int subcategoryID, string Name)
{
this._category = category;
this.SubcategoryID = subcategoryID;
this.name = Name;
}
private Category _category;
private long SubcategoryID { get; set; }
private string name { get; set; }
}
最后是 FoodItem class:
public class FoodItem
{
public FoodItem()
{}
public FoodItem(Subcategory subcategory, long Id, string Name, string Size)
{
this._subCategory = subcategory;
this.Id = Id;
this.name = Name;
this.size = Size;
}
private Subcategory _subCategory;
public long Id { get; set; }
public string name { get; set; }
public string size { get; set; }
}
所以我所做的是遵循在线示例 - 每个 subclass 中的 superclass 实例被创建并传递到构造函数中。这意味着子 class 不能存在,除非超级 class 也已创建 - 类别需要菜单,子类别需要类别,食品项目需要子类别。
我的问题是:
- 我现在遇到的问题是实例化 FoodItem。要创建一个 FoodItem,我是否需要创建一个 Menu 对象,然后创建一个 Category 对象并将 Menu 对象放入,创建一个子类别并将 Category 放入,然后创建一个 FoodItem 并将子类别放入?那是正确的吗?还是我只创建一个 FoodItem 而其余的自动创建?我认为第一个选项是正确的,但想澄清一下。
- 我假设组合是正确的方法是正确的吗?还是继承更好?
- 为了完成任务,我需要能够创建 FoodItems 和 post 到 API。假设我做问题 1 的方法是正确的,我将如何创建 FoodItem 需要的超级classes?
非常感谢任何方向。
您已确定您的菜单有类别,但以相反的方式实现了它(在您的代码中,您的类别有一个菜单)。引用从叶节点到父节点,而不是父节点包含对其包含的项目的引用集合。
关于您发布的内容,我发现另一件不寻常的事情是所有成员都是私人的。您可以向外界公开属性,有时您将需要一种方法来查看菜单中包含的数据并将其呈现给用户。
我会重写 类 使其看起来更像这样:
public class Menu
{
public Menu() { }
public Menu(long id, string name)
{
Id = id;
Name = name;
}
public long Id { get; }
public string Name { get; set; }
public List<Category> Categories { get; } = new List<Category>();
}
请注意,我对某些人使用了 get
,对其他人使用了 get/set
。这只是一个假设,但您通常不希望对象的 id 发生变化。同样,初始化列表并保留它 get
-only 意味着用户不必在每次使用它时都进行空检查。
添加到另一个答案。
类别没有父类别,但子类别有。但除此之外它们非常相似。所以我会考虑定义一个子类别作为类别的子类型。使它成为一个递归数据结构,允许子...子子类别。
public class SubCategory : Category
{
public SubCategory(Category Parent, ...) : base(...){
ParentCategory = Parent;
}
public Category ParentCategory { get; }
}
虽然您也可以消除子类别 class,方法是允许类别具有空父类别。
然后一个食品项目有一个类别,它可以是一个子类别的实例。由于每个菜单都有不同的食物,但可能有相同的类别。您应该将其建模为按类别分组的食品列表。也许;
public class Menu {
public List<FoodItem> FoodItems { get; } = new List<FoodItem>();
public IGrouping<Category,FoodItems> GroupItems =>
FoodItems.GroupBy(f => f.Category);
}