我想创建一个可以具有多个菜单的Restaurant对象。每个菜单可以具有多个类别,并且每个类别可以具有多个项目。每个项目都会有一个名称,价格和描述。

--Company--
  -Menu ONE-
  -Menu Name-
    -Category ONE-
       -Category Name-
       -Menu Item ONE-
         -Menu Item Name
         -Menu Item Price
         -Menu Item Description
       -Menu Item TWO-
    -Category TWO-
  -Menu TWO-


没有构造函数,getter / setter或方法的示例类。

拥有一系列菜单的公司

    public class Company
    {
        // Class constants

        // Class variables
        private String companyName;   //  Stores company name
        private String hours;         //  Restaurant hours
        private String phoneNumber;   //  Restaurant phone number
        private Menu[] menuList;      //  Array of menu objects
        private int menuCount;        //  Number of menus in the array

     }


包含类别数组的菜单

    public class Menu
    {
        // Class constants

        // Class variables
        private String menuName;           //  Name of Menu
        private Category[] categoryList;   //  Array of category objects
        private int categoryCount;         //  Number of categories in the array

     }


包含菜单项数组的类别

    public class Category
    {
        // Class constants

        // Class variables
        private String categoryName;       //  Name of Menu
        private MenuItem[] menItemList;    //  Array of MenuItem objects
        private int menuItemCount;         //  Number of menu items in the array

     }


具有名称,价格和说明的单个订单项

    public class MenuItem
    {
        // Class constants

        // Class variables
        private String name;        //  Name of Menu Item
        private float price;        //  Price of the Menu Item
        private String description; //  Description of the Menu Item

     }


在驱动程序类中,如果我只能访问Company的方法,如何更改菜单项中的任何内容?

我曾考虑过要为每个私有数组都有一个吸气剂,但是将3个级别挖掘到私有数组中似乎很难实现。它不像Company.Menu.Category.MenuItem.editName(newName);那样简单。

注意*我对“应使用链接列表或ArrayList”答案不感兴趣。程序要求需要基本数组。

让我知道是否需要进一步说明,或者是否需要SSCCE。

最佳答案

我考虑过要为每个私人物品阵列使用吸气剂,但是
  挖掘3个级别到私有数组似乎很难
  实行。它不像
  Company.Menu.Category.MenuItem.editName(newName);


实施起来并不难,但这是一种反模式,可以依次调用诸如以下的getter:

company.getMenu().getCategory().getMenuItem().editName(newName);


Demeter law 表示为:


  每个单元应仅对其他单元具有有限的知识:仅
  与当前单位“紧密”相关的单位。
  
  每个单位只能与朋友交谈;不要和陌生人说话。
  
  只与您的直系朋友交谈。


因此,要解决您的问题,您将必须重构设计以使对象之间相互协作。

协作/级联方法

您可以定义一个editItemName()方法,该方法由层次结构的每个对象依次调用。

Company可以定义以下方法:

public void editItemName(String menuName, String categoryName, String itemName, String newName){
   Menu menu = findMenu(menuName);
   menu.editItemName(category, item, newName);
}


Menu可以定义以下方法:

public void editItemName(String categoryName, String itemName, String newName){
   Category category = findCategory(categoryName);
   category.editItemName(item, newName);
}


Category可以定义以下方法:

public void editItemName(String itemName, String newName){
   MenuItem item = findItem(itemName);
   item.editItemName(newName);
}


最后,MenuItem可以定义如下方法:

public void editItemName(String newName){
   this.name = newName;
}


更直接的方法(如果适用)

对于客户来说,传递太多的论点可能很麻烦。
或者,如果Item对象是唯一的(就equals()而言),并且您可以从客户端获取它,则可以使事情变得更加简单。
您可能只需要将MenuItem(叶子)中的方法定义为:

public void editItemName(String newName){
   this.name = newName;
}


您可以定义一个按其标识符存储项目的地图:

Map<String, MenuItem> mapUniqueItems = new HashMap<>();
// add items in the map
mapUniqueItems.put("item1", new MenuItem(..));
mapUniqueItems.put("item2", new MenuItem(..));
// add items in the hierarchy as you actually do
...


然后,您可以根据其ID编辑项目,例如:

String itemIdentifier = ...;
MenuItem item = mapUniqueItems.get(itemIdentifier);
item.editItemName("new value");

09-25 18:29
查看更多