将Foo类型的对象存储到属于Foo的Foo类型的静态数组中是不是很糟糕的编程习惯?

时间:2016-03-01 16:03:30

标签: arrays data-structures static

假设我想在自己的类中静态存储对象。像这样:

public class Foo  
{  
    private static int instance_id = 0;  
    public static List<Foo> instances = new List<Foo>();

    public Foo()  
    {  
        instances[instance_id++] = this;  
    }  
}

为什么?

  • 我不需要在课外创建独特的数组结构(一个会这样做)。
  • 我想根据出生时间将每个对象映射到唯一的ID。
  • 我将只使用一个使用该类的线程。 Foo将仅作为程序中的一个集合存在。

我做了搜索,但没有提到这个数据结构。这是不好的做法吗?如果是这样,为什么?谢谢。

{请注意,此问题并非针对任何语言}

1 个答案:

答案 0 :(得分:0)

我可以通过此设置看到一些潜在的问题。

首先,由于您只有一个对象数组,如果您需要更新代码以便在不同的上下文中有许多不同的对象组,则需要进行重要的重写,以便每个对象结束与不同的背景相关联。根据您的设置,这可能不是问题,但我怀疑从长远来看,这个决定可能会回来困扰您。

其次,这种方法假定您永远不需要处理任何对象。想象一下,您想要更新代码,以便进行许多不同的模拟并汇总结果。如果你这样做,那么你最终会让你的巨型数组存储指向你没有使用的对象的指针。这意味着您将(1)发生内存泄漏,(2)必须更新所有循环代码以跳过您不再关心的对象。

第三,这种方法使得类(而不是客户端)负责跟踪所有实例。从某种意义上说,如果您正在做的目的是让客户更容易访问存在的所有对象的全局列表,您可能需要考虑在其他地方放置一个全局可访问的其他列表,以便对象本身不是负责跟踪自己的人。

我建议使用其中一种替代方法:

  1. 让客户端执行此操作。如果客户端需要跟踪所有实例,只需让它们始终创建所需的数组并填充它。这样,如果多个客户端需要不同的阵列,他们就可以这样做。如果正确执行此操作,也可以避免内存泄漏问题。

  2. 让每个对象作为其构造函数的一部分,构建一个上下文。例如,如果所有这些对象都是四叉树中的节点,那么让它们取一个指向它们将作为构造函数参数存在的四叉树的指针,然后使四叉树对象存储其中的节点列表。毕竟,看起来四元组的责任似乎是跟踪所有事情。

  3. 继续做你正在做的事,但是使用弱引用的东西。例如,你可以考虑在WeakHashMap上使用一些变体,这样你就可以存储所有内容,但如果不再需要这些对象,至少你没有内存泄漏。