Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oop 使用单例模式自动生成唯一ID_Oop_Design Patterns_Singleton - Fatal编程技术网

Oop 使用单例模式自动生成唯一ID

Oop 使用单例模式自动生成唯一ID,oop,design-patterns,singleton,Oop,Design Patterns,Singleton,我给出的一小段代码是C#,但问题更多的是理论和设计(我认为),而不是代码本身 在我的应用程序中,用户可以添加项目(假设它是一个愿望列表管理器,用户可以添加他的愿望)。我需要自动生成此条目的ID。 他们给了我们一个关于如何做到这一点的例子,我们必须使用它(从我在这里读到的内容来看,guid是一种很好的实现这一点的方法,如果选择是我的,我会选择它,但这与这里无关) 举个例子: class IDGenerator { private static IDGenerator instance;

我给出的一小段代码是C#,但问题更多的是理论和设计(我认为),而不是代码本身

在我的应用程序中,用户可以添加项目(假设它是一个愿望列表管理器,用户可以添加他的愿望)。我需要自动生成此条目的ID。 他们给了我们一个关于如何做到这一点的例子,我们必须使用它(从我在这里读到的内容来看,guid是一种很好的实现这一点的方法,如果选择是我的,我会选择它,但这与这里无关)

举个例子:

class IDGenerator
{
    private static IDGenerator instance;

    private int nextID;

    private IDGenerator() { nextID = 1; }

    [MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.Synchronized)]
    public static IDGenerator getGenerator()
    {
        if (instance == null)
        {
            instance = new IDGenerator();
        }
        return instance;
    }

    public int nextId()
    {
        return nextID++;
    }
}
然后,教师有一个Wish继承的IdObject类,每次创建Wish的新实例时,都会使用上面的IdGenerator生成一个唯一的ID。很简单。它基本上就像是一个包裹全局变量的包装器

我在这方面有一些问题:id是不可重用的(这不是一个大问题),如果我想有另一个类来扩展IdObject,我需要另一个id生成器(通过简单地复制粘贴代码来完成,或者我可以接受这样一个事实,我会到处都有id)

但我最大的问题是:如果我保存了愿望列表(简单的文本文件,序列化,没关系),我最终可能会得到重复的ID。我可以在每次程序启动时强制读取文件,检查ID,然后使用超出已使用ID范围的值初始化第一个下一个ID,然后在每次添加项目时强制保存文件。或者我可以一直生成ID,直到生成有效的ID为止。但我不想这样做。一定有更好的办法


那么,通过仍然使用单例模式,而不是像我上面描述的那样使用“魔术”,有什么好方法可以做到这一点呢

好的。因此,问题是如何确保
IDGenerator
不会在每次恢复时重复初始序列,对吗?正如你所指出的,一个解决方案是使用一个足够强的随机发生器;另一个则需要保持其状态

所以问题变成了:坚持还是随机化,没有其他解决方案吗?答案是肯定的


例如,每次恢复生成器时,都可以将其
nextId
变量初始化为以秒表示的当前时间戳(我认为不需要毫秒)。这样就不会有任何重复。当然,您会在会话之间留下大量未使用的ID,但如果您想让生成器代码尽可能简单,这可能是您愿意付出的代价。

我不确定是否理解您的问题。为了避免id重复,您唯一需要的是保存生成器迄今为止分配的最后一个id的方法。然后,每次恢复生成器时,它都必须读取保存的值,向其中添加1,然后从那里继续。@Leandro Caniglia这就是我现在正在做的,但我认为这不是正确的方法。请解释一下此代码的作用以及它解决问题的原因。
   public sealed class SingletonIdGenerator
{
    private static long _id;
    private SingletonIdGenerator()
    {
    }

    public string Id
    {
        get { return _id++.ToString().Substring(8); }
    }

    public static SingletonIdGenerator Instance { get { return Nested.instance; } }

    private class Nested
    {
        static Nested()
        {
            _id = DateTime.Now.Ticks;
        }
        internal static readonly SingletonIdGenerator instance = new SingletonIdGenerator();
    }
}