Is this an acceptable use of instanceof?

六月ゝ 毕业季﹏ 提交于 2019-12-02 07:13:25
Doug Moscrop

The short answer: Not really acceptable, so yes - it's a sign of a design deficiency. instanceof is almost always a smell except in rare cases where a library is trying to do some kind of assistance that is meta or otherwise ugly but helps overcome a language/environment shortcoming.

With that opinion, the question is sort of a duplicate. See the answer to:

When is it acceptable to use instanceof?

It suggests to use the visitor pattern. This may be true if you genuinely have two different types in the system.

You also don't have to use the visitor pattern 'explicitly' but rather incorporate it in to your program flow. So consider an interface card:

interface Card {
  void pick(Player player);
}

class DrawCard implements Card {
  void pick(Player player) {
    player.draw(value); // assume value passed in e.g. ctor
  }
}

I would say in general it's best to avoid instanceof wherever possible.

While it's somewhat vague since you didn't post any actual code, one option in this type of situation would be to implement two different interfaces, say ICard and IDrawCard and have the Card class implement the ICard interface and the DrawCard class implement both interfaces.

Then you would be able to differentiate the DrawCard class by virtue of its interface in function signatures, etc. (that is, refer to it as an object of type IDrawCard).

Edit in response to comment from OP:

In terms of handling the action after the card is played, you can leverage the interfaces to override the function that handles the actions. Since that's the context for this, I would probably recommend three different interfaces:

  1. ICommonCard
  2. ICard
  3. IDrawCard

Where ICommonCard is the generic interface for when you need that which perhaps handles has some general-purpose methods, and the other two interfaces handle the needs of those two specific types.

Then say you have an action handler method named handleAction, which could be defined thusly:

void handleAction(ICard card)
{
    // do ICard stuff here
    return;
}

void handleAction(IDrawCard card)
{
    // do IDrawCard stuff here
    return;
}

And then when you call that function, you can pass off an object which is the type of the interface into the overloaded function (one option would be to have a member variable for each type, and if it's going to be one or the other, pass the one that isn't null into the function).

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