Avoiding instanceof Java

主宰稳场 提交于 2019-12-13 05:05:11

问题


I am trying to find a way to bypass the use of instanceof. I've created a class Item which has multiple subclasses like WeaponItem and BodyItem. Now I would like to make to do a call such as equip(Item) and it should determine by itself which overloaded function it should call such as equip(BodyItem).

Is there a way to bypass the use of instanceof for this case and what would you recommend? I've heard that in most cases using instanceof is bad practice and therefor I want to know what the alternatives are.

Code:

inv.equip(it); // inv = inventory object, it = Item

An example of equip function within inventory class how I preferably want it

public void equip(HelmItem it) 
{
    if (it != this.getHelm())
    {
        this.setHelm(it);
    }
}

How I had it before:

public void equip(Item it)
{
    if (it instanceof WeaponItem)
    {
        if (it != this.getWeapon())
        {
            this.setWeapon((WeaponItem) it);
        } 
    } etc for all subclasses of item
}

回答1:


Indeed, this could be solved with a visitor pattern.

However, it does not have to be a full-blown visitor, but a simplified variation of it. You could pass the inventory to the item and let the item do whatever it wants with it:

abstract class Item {
    public abstract void equip(Inventory inv);
}

class HelmItem extends Item {
    @Override
    public void equip(Inventory inv) {
        inv.setHelm(this);
    }
}

class WeaponItem extends Item {
    @Override
    public void equip(Inventory inv) {
        inv.setWeapon(this);
    }
}

Then you can just call:

it.equip(inv)

without the instanceof operator.




回答2:


Why not put the method in the Item concrete class, and it can equip itself? It's a little counter intuitive but it would solve your problem.

public class SomeConcreteItem extends Item {
    public void equip(Body body) {
        // Just an example.
        body.getSections().get(0).equip(this);
    }
}

That way, the concrete implementation knows how to equip itself and the classes that use it don't care. You can reference it by the Item superclass and provided that the Item superclass has an abstract method public void equip(Body body);, then you don't ever need to know about the concrete implementation and, therefore, no need for the instanceof operator.

A Note on Introducing a Design Pattern

You should be careful about introducing Design Patterns. People have a bad habit of leaping straight to a complicated pattern to solve a problem, when really something simpler and (in my opinion) more elegant is available.



来源:https://stackoverflow.com/questions/30953608/avoiding-instanceof-java

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!