我在滥用静电吗?

时间:2015-05-18 15:12:44

标签: java bukkit

为了将玩家伪装成另一个实体,我做了一个伪装课程,你可以在这里看到:

public class Disguise
{
    private static HashSet<Disguise> disguises = new HashSet<>();
    private net.minecraft.server.v1_8_R2.EntityLiving nmsEntity;
    private Player disguise;

    public Disguise(Player disguise, EntityLiving entity, boolean affectLogin)
    {
        if(affectLogin)
            disguises.add(this);

        this.disguise = disguise;
        this.nmsEntity = entity;
    }

    public Disguise(Player disguise, EntityLiving entity)
    {
        this(disguise, entity, true);
    }

    public void send(Player visible)
    {
        if(visible == disguise)
            return;

        EntityPlayer player = NMSUtils.getNMSPlayer(visible);

        nmsEntity.setPosition(player.locX, player.locY, player.locZ);
        nmsEntity.d(disguise.getEntityId());
        nmsEntity.setCustomName(disguise.getDisplayName());
        nmsEntity.setCustomNameVisible(true);

        PacketPlayOutSpawnEntityLiving spawn = new PacketPlayOutSpawnEntityLiving(nmsEntity);
        PacketPlayOutEntityDestroy destroy = new PacketPlayOutEntityDestroy(disguise.getEntityId());

        player.playerConnection.sendPacket(destroy);
        player.playerConnection.sendPacket(spawn);
    }

    public void send(List<Player> visible)
    {
        for(Player player : visible)
            send(player);
    }

    public void send(Player... visible)
    {
        send(Arrays.asList(visible));
    }

    public void send()
    {
        send(new ArrayList<>(Bukkit.getOnlinePlayers()));
    }

    public Player getDisguised()
    {
        return disguise;
    }

    public static HashSet<Disguise> getDisguises()
    {
        return disguises;
    }
}

我还有一个静态HashSet,它存储所有实例。我这样做是因为我希望登录的玩家能够看到伪装,并且我想在玩家退出时从玩家身上移除伪装。静态HashSet是这样做的方式(就像我做的那样)?如果没有,应该怎么做?

3 个答案:

答案 0 :(得分:3)

static正在要求它。就其性质而言,它很容易“滥用”,但这只是挑战的一部分。

如果说完了所有内容,如果你的mod做了你需要做的事情而没有懈怠,不要过分强调这个粒度级别(特定变量)的最佳实践。它不可能在范围上扩展到设计不良会给您带来问题的程度。毕竟,它不是生命支持系统。

如果你想练习好形式以获得乐趣,我的第一直觉就是将你的管理逻辑从Disguise转移到(例如)DisguiseManager类,并通过manager类处理所有伪装创建/破坏。不太复杂的是隐私上的私有构造函数和静态创建/销毁方法。像你发布的构造函数中的全局副作用通常是不好的形式。

答案 1 :(得分:2)

基本上每次调用构造函数时,都希望将this添加到全局位置。

没关系,但有两个问题:

  1. 在构造函数中暴露this是危险的,需要仔细分析。 (你的代码在这方面有问题)
  2. 并发 - 如果应用程序是多线程的,则需要是线程安全的。 (在构造函数中公开this在并发环境中更成问题)
  3. 垃圾收集 - 当对象变为“垃圾”时,如何将其从全局位置删除。

答案 2 :(得分:2)

当代码增长时,使用静态对象会变得非常令人沮丧,并且所述对象有许多访问器。如果您要调试代码,那么如何捕获操作HashSet的确切代码?

为什么不使用HashSet重构客户端,以通过getter获取它?将HashSet实例封装为Singleton怎么样?听起来好像只创建了一个HashSet来存储玩家/伪装。

通过Singleton,有了任何类型的getter方法,您可以在访问HashSet之前或之后轻松添加其他代码。例如,在每次使用返回HashSet的方法之后,您可以打印HashSet的内容。你也可以用静态对象做到这一点,但是找到静态对象的所有用法的噩梦......