Любой хороший способ получить один экземпляр вместо использования Singleton (в C #) - PullRequest
2 голосов
/ 25 апреля 2011

Раньше я использовал синглтон, чтобы получить один экземпляр, но другие отказались от него из-за некоторых недостатков в тестировании.В чем недостаток?Есть ли какой-нибудь альтернативный способ получения глобального экземпляра?


Так нормально ли мне создавать только один одноэлементный класс Global в приложении в качестве глобального концентратора?так что я могу поместить отдельные экземпляры любого другого класса в Global.Instance.

Ответы [ 4 ]

4 голосов
/ 25 апреля 2011

Хорошо, почему синглеты плохие, вы можете прочитать здесь: Что такого плохого в синглетах?

Специально для тестирования: типичный шаблон синглтона выглядит следующим образом

class MyClass
{
    private static MyClass m_Instance = new MyClass();
    public static MyClass Instance
    {
        get { return m_Instance; }
    }
}

Теперь представьте, что вам нужно выполнить целую кучу тестов, включающих MyClass.Instance.Этот класс переносит состояние, и вам обычно требуется способ его сброса между тестами, чтобы каждый тест мог начинаться с чистого начального состояния.Теперь вы можете добавить метод Reset(), но это означает, что вы добавляете код в свой класс только для возможности его тестирования, что нежелательно.

Что использовать вместо этого: Ну, синглтон сам по себеэто не совсем плохо.Проблема, к которой это приводит, состоит в том, что это облегчает написание кода следующим образом:

class SomeClass
{
    public void SomeMethod()
    {
        ...
        MyClass.Instance.DoSomething();
    }
}

Теперь вы создали неявную зависимость от экземпляра singleton, который вы не можете легко сломать.Одним из подходов, который решает эту проблему, является внедрение зависимостей (о котором уже упоминалось):

class SomeClass
{
    public SomeClass(MyClass myClass)
    {
        m_MyClass = myClass;
    }

    public void SomeMethod()
    {
        ...
        m_MyClass.DoSomething();
    }
}

, и вы можете сделать:

var someClass = new SomeClass(MyClass.Instance);

в вашей программе и

var someClass = new SomeClass(new MyClass());

для тестирования.

Так что синглтоны не так уж и плохи, а иногда и являются подходящим инструментом для правильной работы, однако вы должны быть осторожны с их использованием.

1 голос
/ 25 апреля 2011

Тестируемость - это, как я вижу, основная трудность, для решения которой в некоторой степени у нас есть контейнеры для единства.
Проверка контейнера Unity http://unity.codeplex.com/

0 голосов
/ 25 апреля 2011

Попробуйте вместо этого использовать то, что называется шаблоном «окружающий контекст». Этот пример взят из превосходной инъекции зависимостей Марка Симана в .NET. Этот шаблон дает вам простоту использования синглтона, а также тестируемость. Важным моментом здесь является наличие того, что называется хорошим «значением по умолчанию» (то есть DefaultTimeProvider, показанным в примере). Еще одна вещь, которую следует учитывать, это не злоупотреблять этим шаблоном, в большинстве случаев вы можете внедрить различные зависимости в конструктор класса. Эту схему следует использовать только для задач, которые пересекаются во всем приложении.

public abstract class TimeProvider
{
    private static TimeProvider current;
    static TimeProvider()
    {
        TimeProvider.current = new DefaultTimeProvider();
    }
    public static TimeProvider Current
    {
        get { return TimeProvider.current; }

        set
        {
            if (value == null)      
            {         
                throw new ArgumentNullException("value");    
            }              
            TimeProvider.current = value; 
        }
    }
    public abstract DateTime UtcNow { get; }
    public static void ResetToDefault()
    {
        TimeProvider.current = new DefaultTimeProvider();
    }
}
0 голосов
/ 25 апреля 2011

Я не вижу проблем с тестируемостью и синглетонами.также я не вижу, как DI может заменить их.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...