如何删除此循环类依赖项?

时间:2016-05-03 16:45:26

标签: java listener circular-dependency

我有一个Entity接口,其实现可能会相互冲突。我想添加一个在发生碰撞时调用的CollisionListener,它将接受包含两个碰撞实体的CollisionEvent。有没有办法在EntityCollisionListener

之间没有循环依赖的情况下做到这一点

我目前的情况:

public interface Entity {

    void addCollisionListener(CollisionListener listener);

    void getStrength();

    void dealDamage();

    void die();

    // Other methods
}

// To be implemented and added to Entities when you want to watch for collisions
public interface CollisionListener {
    void onCollision(CollisionEvent event);
}

public class CollisionEvent {
    private final Entity source, collider;

    public CollisionEvent(Entity source, Entity collider) {
        this.source = source;
        this.collider = collider;
    }

    public Entity getSource() { return source; }

    public Entity getCollider() { return collider; }
}

这具有以下周期性依赖性:

Entity -> CollisionListener -> CollisionEvent -> Entity

我不确定如何解决此问题(或者甚至可以解决),因为CollisionListener接口的实现应该可以访问受碰撞影响的Entity个对象它可以对它们起作用(例如,调用dealDamagedie方法。

我知道没有严格的错误具有循环依赖性(即代码编译并且运行正常),但是如果可能的话,我宁愿避免它们。< / p>

1 个答案:

答案 0 :(得分:2)

EntityCollisionListener相互了解并不是什么大不了的事;循环依赖意味着两个类彼此了解(这是有道理的;它是一个有凝聚力的系统)。但是,两者没有紧密耦合,因为他们对外部实现细节知之甚少。

为了具体化,请考虑是否要为Entity的实现设计单元测试。您可以非常轻松地模拟CollisionListener(使用像Mockito这样的资源,甚至只是在单元测试中创建一个实现,比如MockCollisionListener)。 Entity实现不依赖于任何外部实现细节,因此,只要遵守契约接口(CollisionListener),就可以自由地更改实现。

但是,如果您仍然不希望您的资源彼此了解,请考虑Mediator pattern,它基本上只是说明,而不是让资源相互通信,您有一个中介对象知道它们,并处理它们之间的通信。