Как я могу избежать глобального состояния?

для вашего примера, все три типа выполняются асинхронно. единственное отличие состоит в том, что в третьем примере вы предварительно сгенерировали все 10 сопрограмм и отправили в цикл вместе. поэтому только последний дает выход случайным образом.

10
задан Jon Lin 13 June 2012 в 20:47
поделиться

3 ответа

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

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

Два основных преимущества: один, тестирование чертовски много легче, и два, Ваше приложение намного более слабо связывается. Вы полагаетесь на способность программировать против интерфейса класса, а не его реализации.

12
ответ дан 3 December 2019 в 22:40
поделиться

Следует иметь в виду, включают ли Ваши тесты фактические ресурсы, такие как базы данных или файловые системы затем, что Вы делаете, интеграционные тесты, а не модульные тесты. Интеграционные тесты требуют некоторой предварительной установки, тогда как модульные тесты должны смочь работать независимо.

Вы могли изучить использование платформы внедрения зависимости, такой как замок Windsor, но для простых случаев Вы можете занимать середину дорожного подхода, такого как:

public interface ISettingsProvider
{
    string ConnectionString { get; }
}

public class TestSettings : ISettingsProvider
{        
    public string ConnectionString { get { return "testdatabase"; } };
}

public class DataStuff
{
    private ISettingsProvider settings;

    public DataStuff(ISettingsProvider settings)
    {
        this.settings = settings;
    }

    public void DoSomething()
    {
        // use settings.ConnectionString
    }
}

В действительности Вы, скорее всего, читали бы из файлов конфигурации в своей реализации. Если Вы подлежите ему, полноценная платформа DI с выгружаемыми конфигурациями является способом пойти, но я думаю, что это, по крайней мере, лучше, чем использование Globals. ConnectionString.

2
ответ дан 3 December 2019 в 22:40
поделиться

Большой первый вопрос.

Короткий ответ: удостоверьтесь, что Ваше приложение является функцией от ВСЕХ своих исходных данных (включая неявные) к ее выводам.

Проблема, которую Вы описываете, не походит на глобальное состояние. По крайней мере, не изменяемое состояние. Скорее что Вы описываете, походит на то, что часто упоминается как "проблема Конфигурации", и она имеет много решений. При использовании Java можно хотеть изучить легкие инжекционные платформы как Guice. В Scala это обычно решается с implicits. На некоторых языках Вы сможете загрузить другую программу для конфигурирования программы во времени выполнения. Это - то, как мы раньше настраивали серверы, записанные в Smalltalk, и я использую менеджер окон, записанный в Haskell по имени Xmonad, конфигурационный файл которого является просто другой программой Haskell.

1
ответ дан 3 December 2019 в 22:40
поделиться
Другие вопросы по тегам:

Похожие вопросы: