Использование статического метода и переменных - хорошо против плохо - PullRequest
9 голосов
/ 08 сентября 2011

Я занимаюсь разработкой веб-приложения на C # и asp.net.

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

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

Пример моего кода

public class utilities
{
    public static string utilVariable1 = "Myvalue";
    public static string utilVariable2 = "Myvalue";
    public static string utilVariable3 = "Myvalue";
    :
    public static string utilVariableN = "Myvalue";


    public static string UtilMethod1()
    {
         //do something
    }

    public static string UtilMethod2()
    {
         //do something
    }

    public static string UtilMethodN()
    {
         //do something
    }
}

Ответы [ 5 ]

12 голосов
/ 08 сентября 2011

В классах static нет ничего неправильного, хотя обычно они не должны иметь состояния (полей).Использование полей public static означает, что это не так, поэтому кажется, что вы слегка злоупотребляете ключевым словом static.Если ваш класс должен иметь состояние, то это должен быть обычный нестатический класс, и вы должны создавать его экземпляры.В противном случае единственными открытыми полями, видимыми в классе, должны быть const (рассмотрим класс Math с такими константами, как Math.PI - хорошее использование static методов и полей).

Другойрассмотрение сплоченность .Методы обычно существуют в одном классе, потому что они так или иначе тесно связаны.Опять же, класс Math является хорошим примером;все там связано с математикой.В какой-то момент вы захотите разделить ваш глобальный служебный класс на несколько более мелких, более сфокусированных.См. Википедия , где приведены некоторые примеры сплоченности. Похоже, ваше использование подпадает под «Случайное сплочение (наихудшее)».

6 голосов
/ 08 сентября 2011

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

Лично я фанат шаблона Singleton .

2 голосов
/ 08 сентября 2011

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

Отличным примером этого былПроект, который я перенял у коллеги.Был 1 класс, названный Методами.Он содержал более 10 тыс. Строк методов.
Затем я отнес их к ок.20 файлов, и структура была восстановлена.

Большинство методов из этого проекта проверяли пользовательский ввод, который можно легко переместить в static class Validation.

Одна ужасная вещь, которую я заметил, этоизменяемые публичные и статические переменные.Это плохо по нескольким причинам:

  1. Неправильное поведение, потому что, если какой-то метод изменяет это, хотя он не должен этого делать, он заставляет другие методы вести себя ненадлежащим образом, и это действительно трудно отследитьdown / debug.
  2. Параллелизм, как мы будем обеспечивать безопасность потоков?Мы даем это всем методам, которые работают с этим?Скажите, если это тип значения, что мы позволим им заблокировать?Что если какой-то метод забудет сделать его потокобезопасным?
  3. Возможность расширения (надеюсь, вы понимаете, что я имею в виду), если у вас есть, например, данные статического класса, в которых хранятся все эти общедоступные статические переменные, чтоты не должен былОн может сохранить это один раз, если, например, вы можете немного изменить структуру приложения и сказать, что хотите сделать возможной загрузку двух проектов на одном экране, это очень трудно сделать возможным, поскольку вы не можете создать дваэкземпляры статического класса.Существует только один класс, и он останется таким.

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

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

Публичные и статические переменные допустимы, если они на самом деле не являются переменными.
Два способа сделать это - пометить их как постоянные (модификатор const) или только для чтения (модификатор readonly).

Пример:

public class UtilitiesClass
{
    internal UtilitiesClass() { }

    public void UtilityMethod1()
    {
        // Do something
    }
}

// Method 1 (readonly):
public static readonly UtilitiesClass Utilities = new UtilitiesClass();

// Method 2 (property):
private static UtilitiesClass _utilities = new UtilitiesClass();
public static UtilitiesClass Utilities
{
    get { return _utilities; }
    private set { _utilities = value; }
}

Преимущество метода 1 заключается в том, что вам вообще не нужно беспокоиться о безопасности потоков, значение не может измениться.
Метод 2 не является поточно-ориентированным (хотя это не так сложно сделать), но он имеет преимущество, заключающееся в том, что сам статический класс может изменять ссылку на класс утилит.

2 голосов
/ 08 сентября 2011

static само по себе неплохо. Методы, которым не требуется доступ к каким-либо переменным или методам-членам, всегда должны быть объявлены как статические. Таким образом, читатель кода сразу видит, что метод не изменит переменные или методы-члены.

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

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

1 голос
/ 08 сентября 2011

Нет, это не очень хорошая практика для больших приложений, особенно если ваши статические переменные являются изменчивыми, так как тогда они фактически являются глобальными переменными, запахом кода, который объектно-ориентированное программирование должно было «решить».

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

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

Наконец, если ваше приложение довольно большое и / или сложное, вы можете рассмотреть такие решения, как контейнер Inversion of Control, которые могут уменьшить зависимость от глобального состояния. Тем не менее, общеизвестно, что веб-формы ASP.Net сложно интегрировать в такую ​​среду, поскольку сама структура очень тесно связана.

...