目前,我正在对像这样的项目列表执行线性搜索:
private Item getKey(ArrayList<Item> inventory) {
for(Item item : inventory) {
if(item instanceof Key) {
return item;
}
}
return null;
}
我听说使用instanceof
被认为是“代码异味”。通常,为了避免使用instanceof
,我会使用多态性(例如this answer中描述的多态性),但是,在这种情况下,我正在努力寻找如何使用它。
所以我想知道是否有一种方法可以消除对instanceof
的需求,并可能使用另一种技术,例如多态性,而这种技术更注重OOD?
答案 0 :(得分:1)
您的情况与您的链接有所不同。在这种情况下,我认为您的代码不是“代码异味”。
正如@shmosel提到
此方法中没有此缺陷。
但是您可以使代码更可重用,例如:
private Item getKey(ArrayList<Item> inventory) {
return getAnItemByType(inventory, Key.class);
}
private Item getAnItemByType(ArrayList<Item> inventory, Class<? extends Item> type) {
for(Item item : inventory) {
if(type.isInstance(item)) {
return item;
}
}
return null;
}
答案 1 :(得分:1)
如果您想要一个使用多态性而不是instanceof
的解决方案,则需要在您的超类型中定义一个isKey()
方法,并为有资格作为键的子类型覆盖它:
public class Item {
public boolean isKey() {
return false;
}
}
class Key extends Item {
@Override
public boolean isKey() {
return true;
}
}
然后您的解决方案将变为:
private Item getKey(ArrayList<Item> inventory) {
for(Item item : inventory) {
if(item.isKey()) {
return item;
}
}
return null;
}
请注意,这将返回清单中的 first 键。
对于更现代(更紧凑)的代码样式,您可以在stream操作中利用谓词方法isKey()
并返回Optional
而不是可能为null的键:>
private Optional<Item> getKey(ArrayList<Item> inventory) {
return inventory.stream().filter( item -> item.isKey() ).findFirst();
}