双模式实现

时间:2010-06-11 21:10:53

标签: c# .net design-patterns

我在自己的代码中利用the Doubleton Design Pattern on Code Project中的Doubleton模式。我认为它使事情变得更容易,因为Singleton只提供了一个实例,但我得到了两个这样的模式。我想知道让它实现一个接口是否有意义,所以我可以将它注入我的域层。

3 个答案:

答案 0 :(得分:3)

尽管这种设计的实用性和巧妙性,但这是不可能的。您无法在界面中定义静态成员。

public interface IDoubleton
{
    static IDoubleton Instance { get; } // Can't be done
}

@Pierreten,如果您使用实例方法,请想象一下:

IDoubleton firstInstance;
// Construct firstInstance,
// do some stuff...

// Now comes trouble.
IDoubleton secondInstance = firstInstance.Instance; // what does it mean?
IDoubleton anotherInstance = secondInstance.Instance.Instance.Instance; // what now?

编辑:正如@Roger Pate正确地指出的那样,我的第二个答案应该合并到这一个中。正如他已经完成的那样,我删除了另一个。

答案 1 :(得分:1)

澄清这个答案:这并不完全解决问题问题,但是与上面链接的实现是可怕的编码。也许下面的实现是线程安全的。

我不是100%确定这是线程安全的,因为我没有测试它(我无法想出任何真实世界使用这种“模式”,因为我觉得它很混乱),但它是一个更正确的类似Singleton的实现,你可以用来实现你想要的东西。祝你好运。

Console.WriteLine()次来电感到抱歉,我使用了Snippet Compiler进行此操作。

/// <summary>
/// Doubleton
/// </summary>
public sealed class Doubleton
{
    const int MaxInstances = 2;
    static volatile Hashtable instances = new Hashtable();
    static volatile int PreviousInstanceNumber = MaxInstances;

    #region Constructor
    Doubleton()
    {
    }
    #endregion

    #region Properties
    /// <summary>
    /// Get 1 of 2 instances of a Doubleton
    /// </summary>
    public static Doubleton Instance
    {
        get
        {
            lock (instances.SyncRoot)
            {
                int instanceNumber = PreviousInstanceNumber == MaxInstances ? 1 : ++PreviousInstanceNumber;

                // if it doesn't exist, create it
                if (instances[instanceNumber] == null)
                {
                    instances[instanceNumber] = new Doubleton();
                }

                PreviousInstanceNumber = instanceNumber;

                return (Doubleton)instances[instanceNumber];
            }
        }
    }
    #endregion

    /// <summary>
    /// Get the index of the Doubleton
    /// </summary>
    /// <returns></returns>
    public int GetInstanceIndex()
    {
        lock (instances.SyncRoot)
        {
            for (int i = 1; i <= MaxInstances; i++)
            {
                if (instances[i] != null && instances[i].Equals(this))
                {
                    return i;
                }
            }
        }

        return -1;
    }
}

然后您可以使用以下代码:

var instance1 = Doubleton.Instance;
var instance2 = Doubleton.Instance;

var instance1Again = Doubleton.Instance;
var instance2Again = Doubleton.Instance;

Console.WriteLine("The following 2 lines should be true:");
Console.WriteLine(instance1.Equals(instance1Again));
Console.WriteLine(instance2.Equals(instance2Again));

Console.WriteLine("---");
Console.WriteLine("The next 50 lines should alternate instances:");
for (int i = 0; i < 50; i++)
{
    var instance = Doubleton.Instance;
    Console.WriteLine("I have instance # " + instance.GetInstanceIndex());
}

答案 2 :(得分:0)

我认为很难看到使用这样的类,但是,我有一个我用于Singleton的泛型类 - 我想它可以被修改/扩展 - 你可以获得一些接口的好处:

public class SingletonBase<T> where T : class
{
    static SingletonBase()
    {
    }

    public static readonly T Instance = 
        typeof(T).InvokeMember(typeof(T).Name, 
                                BindingFlags.CreateInstance | 
                                BindingFlags.Instance |
                                BindingFlags.Public |
                                BindingFlags.NonPublic, 
                                null, null, null) as T;
}