首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我滥用静电了吗?

我滥用静电了吗?
EN

Stack Overflow用户
提问于 2015-05-18 23:12:44
回答 3查看 1.4K关注 0票数 6

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

代码语言:javascript
复制
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是做这件事的方法吗(就像我正在做的那样)?如果不是,应该怎么做呢?

EN

回答 3

Stack Overflow用户

发布于 2015-05-18 23:39:52

这是static自找的。从本质上讲,它很容易被“滥用”,但这只是挑战的一部分。

说到底,如果您的mod做了您需要它做的事情而没有best,那么在这个粒度级别(一个特定的变量)不要过多强调最佳实践。它不太可能在范围内扩展到糟糕的设计会给您带来问题的程度。毕竟,这不是一个生命维持系统。

如果你想为了好玩而练习好的形式,我的第一反应是把你的管理逻辑从伪装变成一个(例如)DisguiseManager类,并通过管理器类处理所有伪装创建/销毁。不太复杂的是私有构造函数和伪装的静态创建/销毁方法。像你发布的构造器中的全局副作用通常是不好的形式。

票数 4
EN

Stack Overflow用户

发布于 2015-05-18 23:26:02

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

这很好,但有两个问题:

  1. 在构造函数中暴露this是危险的,需要仔细分析。(您的代码在此aspect)
  2. concurrency中有错误-如果应用程序是多线程的,则它需要是线程安全的。(在并发environment)
  3. garbage收集中,在构造函数中公开this更有问题-当对象变成“垃圾”时,如何将其从全局位置移除。
票数 2
EN

Stack Overflow用户

发布于 2015-05-18 23:26:51

当你的代码变得越来越大时,使用静态对象可能会变得非常令人沮丧,而且有很多对象的访问器。如果您要调试代码,您将如何捕获操作HashSet的确切代码?

为什么不使用HashSet重构客户端,以通过getter获得它呢?如何将HashSet实例封装为Singleton?听起来好像只有一个HashSet是用来存储玩家/盘点的。

有了任何类型的getter方法,比如通过单例,您就可以很容易地在访问HashSet之前或之后添加额外的代码。例如,在每次使用返回HashSet的方法之后,您可以打印HashSet的内容。你也可以用静态对象做到这一点,但是找到静态对象的所有用法的噩梦……

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30306868

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档