Каждый раз, когда я общаюсь с опытными программистами, они говорят о том, что глобальные переменные являются плохой практикой из-за отладки или эксплойтов безопасности. У меня есть простой список строк, которые я хочу загрузить из текстового файла и получить доступ к различным методам в моей форме. Раньше я просто инициализировал указанную переменную сверху, внутри моего класса формы и использовал ее в разных методах. Я всегда стараюсь уменьшить эту практику, когда могу, и только инициализировать эти переменные, когда они мне действительно нужны. Это плохая практика для этого или более опытные программисты делают это тоже? Существует ли стандартный шаблон шаблона проектирования, поэтому вам не нужно использовать «глобальные переменные» в верхней части формы?Что такое хороший шаблон дизайна, чтобы избежать использования глобальной переменной в верхней части основной формы?
ответ
Как вы говорите о C#, и это полностью объектно-ориентированный язык программирования, нет никакого способа объявить глобальные переменные .
В языке объектно-ориентированного типа C#, плохо практика может быть имитируя глобальные переменные используя статические классы:
public static class Global
{
public static string Value1 { get; set; }
public static int Value2 { get; set; }
}
... позже получить или установить эти значения из других классов. Определенно, это плохая практика, потому что государство должно удерживаться конкретными и значимыми объектами.
Обычно, в отличном/идеальное решение ООП, вы должны пройти такие значения из класса в конструкторах класса с помощью:
public class X
{
public int Value1 { get; set; }
public void DoStuff()
{
Y y = new Y(this);
y.DoChildStuff();
}
}
public class Y
{
public class Y(X parent)
{
Parent = parent;
}
public X Parent { get; }
public void DoChildStuff()
{
// Do some stuff with Parent
}
}
Или же, вы могли бы пройти страны предоставляют аргументы в какой-то метод:
public class Y
{
public void DoChildStuff(X parent)
{
// Do some stuff with "parent"
}
}
Поскольку вы передаете состояния с ссылочными типами, если какой-либо из методов в цепочке принимает решение об изменении Parent.Value1
с другим значением, все объекты, имеющие ссылку на то же самое X
объект получит новый X.Value1
.
Некоторые ребята могут утверждать, что мы обычно строим объекты конфигурации, которым принадлежит множество свойств, к которым обращаются другие произвольные объекты, не так ли? BTW, конфигурация - концепция per se, не так ли? И мы обычно классифицировать значение конфигурации, используя состав:
public class ApplicationConfiguration
{
public DatabaseConfiguration Database { get; } = new DatabaseConfiguration();
public StorageConfiguration Storage { get; } = new StorageConfiguration();
}
public class DatabaseConfiguration
{
public string ConnectionString { get; set; }
}
public class StorageConfiguration
{
public string TemporalFileDirectoryPath { get; set; }
public string BinaryDirectoryPath { get; set; }
}
Так позже мы впрыснуть конфигурации приложения, где нам это нужно:
// Please note that it's a VERY hypothetical example, don't take
// it as an actual advise on how to implement a data mapper!!
public class DataMapper
{
public DataMapper(ApplicationConfiguration appConfig)
{
AppConfig = appConfig;
}
public ApplicationConfiguration AppConfig { get; }
private IDbConnection Connection { get; }
public void Connect()
{
// We access the configured connection string
// from the application configuration object
Connection = new SqlConnection(AppConfig.Database.ConnectionString);
Connection.Open();
}
}
В общем, и так как я люблю сравнение реального мира и программирования что вы никогда не очищаете свою комнату, и вы бы использовали один ящик для хранения каждого инструмента, который вам может понадобиться в какой-то день. Однажды вам понадобится отвертка из всей коробки, и вы знаете, что это внутри ... Но вам нужно бросить все в коробку на землю и разгадать беспорядок, прежде чем найти бесценную отвертку, чтобы выполнить какую-то домашнюю задачу.
Или представьте, что вы купили инструментарий для хранения ваших инструментов по порядку, и как только вам понадобится отвертка, вы знаете, что это на панели инструментов и в разделе, где вы храните отвертки.
Вы знаете, что второй подход является самым разумным. То есть, когда вы разрабатываете программное обеспечение, вам нужно разрабатывать разумные архитектуры, а не большой беспорядок несвязанных данных и поведения, работающих вместе.
И если автор случайно вводит/создает новую конфигурацию, вся вещь падает в сложном беспорядке, тогда как простая статика никогда не может иметь этой проблемы, и, несмотря на то, что ваш один сценарий панели инструментов намного чище, чем поиск одного элемента, хранящегося в один из нескольких сотен наборов инструментов, каждый из которых содержит только 1 или 2 элемента. (Больше работы, гораздо более беспорядочно, гораздо более подвержено ошибкам.) – Rob
@Rob Вы преобразовываете исключение в правило. Ваше описание - * ошибка *, не так ли? Вы не можете создать решение на основе «что делать, если я ошибаюсь». Если вы допустили такую ошибку, исправьте ее! Это все. И обычно вы собираетесь использовать контейнер IoC/DI, где вы будете определять эту конфигурацию один раз, и он будет автоматически вводиться в любом месте (т. Е. Он всегда будет одним и тем же экземпляром во время жизненного цикла приложения). –
@Rob Кроме того, когда вы * вводите конфигурацию *, вы можете настроить, чтобы определенные области вашего приложения могли использовать разные конфигурации. Представьте себе ту ситуацию, когда определенные области должны работать с базой данных A и другими с B. Со статической конфигурацией это было бы трудно реализовать, а конфигурация * впрыска * облегчала жизнь. В чем проблема для вас, это может быть преимуществом в некоторых сценариях! –
Это только плохая практика, если используется для передачи значений, которые должны/могли быть параметрами. Используйте private/internal, чтобы ограничить область использования таких переменных. Что касается отладки, проблем нет. (Только плохие программисты говорят, что все глобальные переменные плохие.) – Rob
Если этот список является полем внутри вашей формы - это не глобальная переменная. – Evk
Я думаю, что лучше создать класс, чтобы получить данные из текстового файла и выставить список, который используется в нескольких формах. –