我的菜单层次结构如下所示:
Root
ProductGroups
Products
ItemTypes
Items
我避免使用循环引用,因此只有从父级到其子级的引用,例如ProductGroup引用其产品。
如果我想知道项目所属的产品,我必须从Root开始遍历层次结构。这导致5个for循环:
for (MenuElement rootChild : Root.getChildren())
for(ProductGroup group : rootChild.getChildren())
for(Product product: group.getChildren())
for(ItemType itemType : product.getChildren())
for(Item item : itemType.getChildren())
if(item == searchedItem)
return product;
这是最好的方法还是您认为递归方法更好?
性能不应该是问题:10个产品组,10个产品,6个ItemTypes,~30个项目,因此递归方法不会导致大的过载。
递归的一个参数是较短的代码。在这个特定情况下还有更多吗?
答案 0 :(得分:1)
如果你只是经常调用它,我建议在每个级别都包含一个父指针,或者如果你不想修改代码,为反向查找创建哈希图而不是使用任何一个你的解决方案。
Item->ItemType
ItemType->Product
Product->ProductGroup
您当前的解决方案始终遍历所有现有项目,这有点矫枉过正。如果你进行反向查找,你将在从一个hashmap获得2后完成,你的代码会更加简单:
type = itemToTypeMap.get(item);
if (null == type); //treat error
product = typeToProductMap.get(type);
if (null == product); //treat error
return product;
答案 1 :(得分:1)
我不知道递归方法是如何工作的,因为你在每个级别都有不同的类型,我们对这些类型或任何超类型等都知之甚少。
我可以给出的一条建议是关于耦合。
您的代码违反了Law of Demeter,因为此代码中的每个内部结构都存在高度耦合。这使得以后很难重构或扩展。
此代码更松散耦合:
for (MenuElement rootChild : Root.getChildren()) {
Product product = rootChild.findProductByItem(searchedItem);
if (product != null) return product;
}
然后在MenuElement
:
public Product findProductByItem(Item item) {
for (ProductGroup group : getChildren()) {
Product product = group.findProductByItem(item);
if (product!=null) return product;
}
return null;
}
然后在ProductGroup
:
public Product findProductByItem(Item item) {
for (Product product: getChildren())
if (product.matchesItem(item))
return product;
return null;
}
然后在Product
:
public boolean matchesItem(Item item) {
for (ItemType itemType : getChildren())
if (itemType.matches(item))
return true;
return false;
}
然后在ItemType
:
public boolean matchesItem(Item searchItem) {
for (Item item : getChildren())
if (item == searchItem) //do you really mean == BTW?
return true;
return false;
}
现在你可以看到可能适合提升超类的重复模式,这可以帮助你实现递归代码。