我可以摆脱这个开关和枚举吗?
Can I get rid of this switch and enum?
我觉得这段代码可以通过某种方式利用多态性变得更清晰,但我似乎找不到合适的方法来做这件事。我尝试使用访问者模式,但没有成功。
有开关的"Hero"class:
public class Hero {
private Equipment equipment = new Equipment();
// other fields
public void equipArmor(Armor armor) {
findCorrespondingArmorSlot(armor).equipItem(armor);
}
private ItemSlot findCorrespondingArmorSlot(Armor armor) {
switch (armor.getArmorType()) {
case SHIELD:
return equipment.offHand;
case BODY:
return equipment.body;
case HEAD:
return equipment.head;
case GLOVES:
return equipment.hands;
case BOOTS:
return equipment.feet;
case BELT:
return equipment.waist;
case AMULET:
return equipment.neck;
case RING:
return equipment.finger;
case TRINKET:
return equipment.special;
}
throw new NullPointerException();
}
public Equipment getEquipment() {
return equipment;
}
// other methods
public class Equipment {
public ItemSlot mainHand = new ItemSlot();
public ItemSlot offHand = new ItemSlot();
public ItemSlot body = new ItemSlot();
public ItemSlot head = new ItemSlot();
public ItemSlot hands = new ItemSlot();
public ItemSlot feet = new ItemSlot();
public ItemSlot waist = new ItemSlot();
public ItemSlot neck = new ItemSlot();
public ItemSlot finger = new ItemSlot();
public ItemSlot special = new ItemSlot();
}
}
还有一些其他的东西:
public class ItemSlot {
private static final Miscellaneous EMPTY = new Miscellaneous();
private Item item = EMPTY;
public Item getItem() {
return item;
}
public void equipItem(Item item) {
unequipItem();
this.item = item;
}
public void unequipItem() {
if (!isEmpty()) {
item.addToInventory();
item = EMPTY;
}
}
public boolean isEmpty() {
return (item == EMPTY);
}
}
public abstract class Item {
// fields
public void addToInventory() {
// code
}
// other methods
}
public class Miscellaneous extends Item{}
public class Armor extends Item {
private ArmorType type;
public ArmorType getArmorType() {
return type;
}
//other methods
}
public enum ArmorType
{
SHIELD, BODY, HEAD, GLOVES, BOOTS, AMULET, RING, BELT, TRINKET;
}
设备中的HashMap如何Class?
像这样:
public HashMap<String, ItemSlot> itemSlots = new ItemSlots HashMap<String, ItemSlot>();
然后在你的构造函数中:
itemSlots.put("mainHand ", new ItemSlot());
然后您必须像这样定义一个方法:
public ItemSlot getItemSlot(String item) {
return itemSlots.get(item);
}
最后,您的案例将类似于:
return equipment.getItemSlot(armor.getArmorType());
是的,你可以摆脱开关。请记住,枚举只是静态保证的单例。所以他们可以有方法。只需按以下方式操作即可:
public enum ArmorType {
SHIELD {
public ItemSlot getItemSlot(Equipment e) { return e.offHand; }
},
// ... repeat for all other armor types
TRINKET {
public ItemSlot getItemSlot(Equipment e) { return e.special; }
};
public abstract ItemSlot getItemSlot(Equipment e);
}
然后你可以简单地调用armorType.getItemSlot(equiment);
。
尝试以下操作:
public enum ArmorType
{
SHIELD(){
public ItemSlot getArmorSlot(Equipment equipment){
return equipment.offHand;
}
},
...
public abstract ItemSlot getArmorSlot(Equipment equipment);
}
然后调用:
ItemSlot armorSlot = armor.getArmorType().getArmorSlot(equipment);
我觉得这段代码可以通过某种方式利用多态性变得更清晰,但我似乎找不到合适的方法来做这件事。我尝试使用访问者模式,但没有成功。
有开关的"Hero"class:
public class Hero {
private Equipment equipment = new Equipment();
// other fields
public void equipArmor(Armor armor) {
findCorrespondingArmorSlot(armor).equipItem(armor);
}
private ItemSlot findCorrespondingArmorSlot(Armor armor) {
switch (armor.getArmorType()) {
case SHIELD:
return equipment.offHand;
case BODY:
return equipment.body;
case HEAD:
return equipment.head;
case GLOVES:
return equipment.hands;
case BOOTS:
return equipment.feet;
case BELT:
return equipment.waist;
case AMULET:
return equipment.neck;
case RING:
return equipment.finger;
case TRINKET:
return equipment.special;
}
throw new NullPointerException();
}
public Equipment getEquipment() {
return equipment;
}
// other methods
public class Equipment {
public ItemSlot mainHand = new ItemSlot();
public ItemSlot offHand = new ItemSlot();
public ItemSlot body = new ItemSlot();
public ItemSlot head = new ItemSlot();
public ItemSlot hands = new ItemSlot();
public ItemSlot feet = new ItemSlot();
public ItemSlot waist = new ItemSlot();
public ItemSlot neck = new ItemSlot();
public ItemSlot finger = new ItemSlot();
public ItemSlot special = new ItemSlot();
}
}
还有一些其他的东西:
public class ItemSlot {
private static final Miscellaneous EMPTY = new Miscellaneous();
private Item item = EMPTY;
public Item getItem() {
return item;
}
public void equipItem(Item item) {
unequipItem();
this.item = item;
}
public void unequipItem() {
if (!isEmpty()) {
item.addToInventory();
item = EMPTY;
}
}
public boolean isEmpty() {
return (item == EMPTY);
}
}
public abstract class Item {
// fields
public void addToInventory() {
// code
}
// other methods
}
public class Miscellaneous extends Item{}
public class Armor extends Item {
private ArmorType type;
public ArmorType getArmorType() {
return type;
}
//other methods
}
public enum ArmorType
{
SHIELD, BODY, HEAD, GLOVES, BOOTS, AMULET, RING, BELT, TRINKET;
}
设备中的HashMap如何Class?
像这样:
public HashMap<String, ItemSlot> itemSlots = new ItemSlots HashMap<String, ItemSlot>();
然后在你的构造函数中:
itemSlots.put("mainHand ", new ItemSlot());
然后您必须像这样定义一个方法:
public ItemSlot getItemSlot(String item) {
return itemSlots.get(item);
}
最后,您的案例将类似于:
return equipment.getItemSlot(armor.getArmorType());
是的,你可以摆脱开关。请记住,枚举只是静态保证的单例。所以他们可以有方法。只需按以下方式操作即可:
public enum ArmorType {
SHIELD {
public ItemSlot getItemSlot(Equipment e) { return e.offHand; }
},
// ... repeat for all other armor types
TRINKET {
public ItemSlot getItemSlot(Equipment e) { return e.special; }
};
public abstract ItemSlot getItemSlot(Equipment e);
}
然后你可以简单地调用armorType.getItemSlot(equiment);
。
尝试以下操作:
public enum ArmorType
{
SHIELD(){
public ItemSlot getArmorSlot(Equipment equipment){
return equipment.offHand;
}
},
...
public abstract ItemSlot getArmorSlot(Equipment equipment);
}
然后调用:
ItemSlot armorSlot = armor.getArmorType().getArmorSlot(equipment);