摆脱`instanceof`

Tho*_*hle 8 java types instanceof sprite

在我正在编写的基于精灵的游戏中,2D网格中的每个字段都包含一堆精灵.最重要的是最重要的.

在游戏的规则模块中,我有很多这样的代码:

public boolean isGameWon(Board board) {
    for (Point point : board.getTargetPoints())
        if(!(board.getTopSpriteAt(point) instanceof Box))
            return false;
    return true;
}
Run Code Online (Sandbox Code Playgroud)

Upadate: //Do something计算Box每个顶部是否有顶部Target.我不知道如何简单地添加doSomething()到Sprite,除非doSomething()精灵是一个盒子,否则返回1 ,否则返回0.(这与instanceof相同).


我知道instanceof被认为是有害的,因为它杀死了面向对象编程的想法.

我不知道如何在我的情况下修复代码.以下是我的一些想法:

  • 我不认为简单isABox()地向Sprite接口添加方法会更好.
  • 如果Box是一个接口会有帮助吗,所以其他类可以得到相同的特权?
  • 我应该尝试做一些像花样匹配/双重调度这样的东西吗?
  • 规则模块是否可以与类型密切配合,只是因为它应该知道它们的语义?
  • 规则模块策略模式的整个想法是否有缺陷?
  • 将规则构建到Sprite中是没有意义的,因为在添加新类型时它们都必须被更改.

我希望你尝试过类似的东西,并能指出我正确的方向.

Art*_*tem 7

使用多态:

class Sprite {
    ..
    someMethod(){
    //do sprite
    }
    ..
}

class Box extends Sprite {
    ..
    @Overrides
    someMethod(){
    //do box
    }
    ..
}
Run Code Online (Sandbox Code Playgroud)

所以,你只需要在你的例子中调用sprite.someMethod().


Chr*_*own 5

Instanceof:(差不多)总是有害的

我看了你帖子的所有答案,并试图了解你在做什么.我得出的结论instanceof正是你想要什么,你原来的代码示例是罚款.

你澄清说:

  • 没有违反Liskov替换原则,因为Box代码都没有使Sprite代码无效.

  • 没有使用响应来分配代码instanceof.这就是为什么人们说实例是坏的; 因为人们这样做:

    if(shape instanceof Circle) {
        area = Circle(shape).circleArea();
    } else if(shape instanceof Square) {
        area = Square(shape).squareArea();
    } else if(shape instanceof Triangle) {
        area = Triangle(shape).triangleArea();
    }
    
    Run Code Online (Sandbox Code Playgroud)

    这就是人们避免使用instanceof的原因.但这不是你在做什么.

  • 有一个一到一个关系Box并赢得比赛(没有其他的精灵能赢得比赛).因此,您不需要额外的"赢家"精灵抽象(因为Boxes == Winners).

  • 您只需检查电路板以确保每个顶部项目都是一个Box.这正是instanceof设计目的.

其他人的答案(包括我自己的答案)增加了一个额外的机制来检查Sprite是否是一个Box.但是,它们不会增加任何稳健性.实际上,您正在使用已经由语言提供的功能并在您自己的代码中重新实现它们.

Tomas Narros认为你应该在代码中区分"语义类型"和"java类型".我不同意.您已经建立了一个java类型Box,哪个子类Sprite.所以你已经掌握了所需的所有信息.

在我看来,拥有第二个独立机制,也报告"我是一个盒子",违反了干(不要重复自己).这意味着对于同一条信息没有两个独立的来源.您现在必须维护枚举和类结构.

所谓的"利益"是围绕完全填满目的的关键词旋转的能力,并且当以更有害的方式使用时是有害的.


黄金法则是用你的头.不要把规则当成事实.问他们,了解他们为什么在那里,并在适当的时候弯曲它们.