Реализация шаблона Doubleton - PullRequest
1 голос
/ 12 июня 2010

Я использую Doubleton Pattern из Doubleton Design Pattern в Code Project в своем собственном коде. Я думаю, что это делает вещи намного проще, поскольку Singleton предоставляет только один экземпляр, но я получаю два с этим шаблоном. Мне было интересно, имеет ли смысл реализовывать интерфейс, чтобы я мог внедрить его в свой домен.

Ответы [ 3 ]

3 голосов
/ 12 июня 2010

Несмотря на полезность и хитрость такой конструкции, это невозможно.Вы не можете определить статический член в интерфейсе.

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

@ Pierreten, если вы используете методы экземпляра, представьте себе:Как справедливо заметил @Roger Pate, мой второй ответ должен быть объединен с этим.Поскольку он уже сделал это, я удалил другой.

1 голос
/ 12 июня 2010

Разъяснение этого ответа: Это не совсем отвечает на вопрос , заданный, но реализация, которая была связана с выше, ужасно закодирована.Возможно, приведенная ниже реализация будет поточно-ориентированной.

Я не уверен на 100%, что это поточно-ориентированная, потому что я ее не тестировал (и я не могу придумать никакого реального использования этого шаблона)«потому что я думаю, что это сбивает с толку), но это более правильная реализация, похожая на Singleton, того, что вы указали выше, и может работать для достижения того, что вы хотели.Удачи.

Извините за вызовы Console.WriteLine(), я использовал для этого компилятор Snippet.

/// <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());
}
0 голосов
/ 12 июня 2010

Я думаю, что трудно увидеть использование такого класса, однако у меня есть универсальный класс, который я использую для 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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...