Являются ли глобальные статические классы и методы плохими? - PullRequest
29 голосов
/ 30 июня 2010

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

Ответы [ 10 ]

45 голосов
/ 30 июня 2010

Глобальные данные плохие.Однако многих проблем можно избежать, работая со статическими методами.

Я собираюсь занять позицию Rich Hickey на этом и объяснить это следующим образом:

Чтобы построить самые надежные системы в C #, используйте статические методы иклассы, но не глобальные данные.Например, если вы передаете объект данных в статический метод, и этот статический метод не обращается к статическим данным, вы можете быть уверены, что с учетом этих входных данных выходные данные функции всегда будут одинаковыми.Это позиция, занятая Эрлангом, Лиспом, Clojure и всеми другими функциональными языками программирования .

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

Я знаю, что это будет горячо обсуждаться, поскольку это идет вразрез с мыслительным процессом ООП в C #, но я обнаружил, что чем больше статических методов я использую, тем чище и надежнее мой код.

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


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

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

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

10 голосов
/ 30 июня 2010

static не обязательно означает глобальный.Классы и члены могут быть static private, следовательно, применимы только к определенному классу.Тем не менее, слишком большое число public static членов вместо использования соответствующих способов передачи данных (вызовы методов, обратные вызовы и т. Д.), Как правило, плохой дизайн.

6 голосов
/ 30 июня 2010

Если вы пытаетесь быть пуристом в своем развитии ОО, статика, вероятно, не вписывается в шаблон.

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

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

Как дополнение к тому, что еще сказано, переменные final static просто хороши; константы это хорошая вещь. Единственное исключение - когда / если вам просто нужно переместить их в файл свойств, чтобы их было легче изменить.

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

Изменяемые статические переменные плохие, потому что это просто глобальное состояние. Лучшее обсуждение, которое я знаю об этом , здесь, под заголовком «Почему глобальных переменных следует избегать, когда они не нужны» .

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

2 голосов
/ 30 июня 2010
public class Foo
{
    private static int counter = 0;

    public static int getCounterValue()
    {
         return counter;
    }
    //...
    public Foo()
    {
        //other tasks
        counter++;
    }
}

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

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

2 голосов
/ 30 июня 2010

Статические методы используются для реализации черт в Scala. В C # методы расширения (которые являются статическими) выполняют эту роль в part . Это можно увидеть, как заявляют сторонники DCI, как «форма полиморфизма более высокого порядка» .

Кроме того, для реализации функций могут использоваться статические методы. Это то, что F # использует для реализации модулей . (А также VB.NET .) Функции полезны для (неудивительно) функционального программирования. И иногда они просто так, как что-то должно быть смоделировано (например, «функции» в классе Math). Опять же, C # подходит близко здесь.

2 голосов
/ 30 июня 2010

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

Нет таких проблем с статическими методами .

То есть статические поля (переменные).Если вы объявите в классе статическое поле public , это будет действительно глобальная переменная, и это будет плохо.

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

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

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

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

0 голосов
/ 30 июня 2010

Не совсем.На самом деле Static определяет, когда, где и как часто создается объект, а не кто имеет к нему доступ.

...