В каких ситуациях статический метод является хорошей практикой?

Другая опция, реализовывая шаблон разработки Итератора:

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

Итератора Думает на этом. Предположим, что все работает просто великолепно, и Вы скопировать/вставить повсеместно "для" предложения. И внезапно как часть требований, необходимо выполнить итерации всех дней, но пропустить некоторых из них (как в календаре, пропустите праздники, выходные, пользовательские и т.д.)

, необходимо было бы создать "отрезанное" новое и использовать Календарь вместо этого. Затем ищите и замените весь свой for's.

В ООП, это могло быть достигнуто с помощью шаблона Итератора.

От Wikpedia:

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

, Таким образом, идея состоит в том, чтобы использовать конструкцию как это:

        DateTime fromDate = DateTime.Parse("1/1/2009");
        DateTime toDate   = DateTime.Parse("12/31/2009");

        // Create an instance of the collection class
        DateTimeEnumerator dateTimeRange = 
                              new DateTimeEnumerator( fromDate, toDate );


        // Iterate with foreach
        foreach (DateTime day in dateTimeRange )
        {
            System.Console.Write(day + " ");
        }

И затем в случае необходимости Вы могли создать подклассы для реализации различных алгоритмов, тот, который использует AddDay (1), другой, который использует AddDay (7) или другой что простой Календарь использования вместо этого. И т.д. и т.д.

идея состоит в том, чтобы понизить связь между объектами.

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

, базовое внедрение, конечно, использовало бы для.

public class DateTimeEnumerator : System.Collections.IEnumerable
{
    private DateTime begin;
    private DateTime end;

    public DateTimeEnumerator ( DateTime begin , DateTime end ) 
    {
        // probably create a defensive copy here... 
        this.begin = begin;
        this.end = end;
    }
    public System.Collections.IEnumerator GetEnumerator()
    {
        for(DateTime date = begin; date < end; date = date.AddDays(1))
        {
            yield return date;
        }
    }
}

Просто идея :)

37
задан Community 23 May 2017 в 11:47
поделиться

9 ответов

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

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

Что касается того, что вы не являетесь "OO"). "- не все, что вы пишете на обычно объектно-ориентированном языке, должно быть" чистым "объектно-ориентированным языком. Иногда не-объектно-ориентированный путь просто более прагматичен и приводит к более простому коду. У Эрика Липперта есть отличный пост об этом в блоге, который, к сожалению, я не могу найти прямо сейчас. Тем не менее, в этом посте есть комментарий, который имеет отношение к делу. Здесь говорится о методах расширения, а не о статических методах, но принцип тот же.

Методы расширения часто критикуются. как "недостаточно ООП". Это кажется мне ставить тележку впереди лошади. Цель ООП - предоставить рекомендации по структурированию крупных программных проектов, написанных команды людей, которым не нужно знать внутренние детали каждого чужая работа, чтобы быть продуктивный. Цель C # - быть полезный язык программирования, который позволяет нашим клиентам быть продуктивными на наших платформах. Очевидно, что ООП - это оба полезны и популярны, и мы поэтому постарался упростить программа в стиле ООП на C #. Но цель C # не "быть ООП язык ". Мы оцениваем особенности на основе от того, полезны ли они нашим клиентов, а не в зависимости от того, строго соответствовать некоторым абстрактным академический идеал того, что делает язык объектно-ориентированный. Хорошо с радостью беру идеи от oo, функциональный, процедурный, императивный, декларативно, как бы то ни было, пока мы может сделать последовательный, полезный продукт это приносит пользу нашим клиентам.

64
ответ дан 27 November 2019 в 04:15
поделиться

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

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

19
ответ дан 27 November 2019 в 04:15
поделиться

Подумайте об этом на мгновение. В объектно-ориентированном кодировании каждый отдельный вызов функции на самом деле выглядит так:

метод (объект this, объект arg1, объект arg2) где это объект, который вы вызываете. Все, что на самом деле представляет собой синтаксический сахар. Кроме того, он позволяет четко определять область действия переменных, поскольку у вас есть объектные переменные и т. Д.

Статические методы просто не имеют параметра this. Т.е. вы передаете переменные и, возможно, получаете результат обратно. 1.) - это основная причина, по которой люди их избегают, вы не можете создать интерфейс для статического метода (пока), поэтому вы не можете имитировать статический метод для его тестирования.

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

Имейте в виду, вы не могли ' t удалить это без взлома:

static void Main(string[] args)
{
}

Код, запускающий ваше приложение, ДОЛЖЕН быть вызван БЕЗ ссылки на объект. Таким образом, они дают вам гибкость, выбор их использования в сценарии будет зависеть от ваших требований.

6
ответ дан 27 November 2019 в 04:15
поделиться

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

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


(без иронии)

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

4
ответ дан 27 November 2019 в 04:15
поделиться

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

Это типично для JDK объекты, а также все объекты, поступающие из внешних библиотек, а также примитивные типы .

2
ответ дан 27 November 2019 в 04:15
поделиться

Я часто использую статические фабричные методы вместо или в сочетании с общедоступными конструкторами.

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

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

Sun использует этот подход в

Class.forName("java.lang.Integer");

и

Boolean.valueOf("true");
2
ответ дан 27 November 2019 в 04:15
поделиться

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

Рассмотрите класс Calendar , который имеет набор статических методов getInstance , каждый из которых возвращает экземпляры с желаемым TimeZone и / или Locale , либо по умолчанию.

2
ответ дан 27 November 2019 в 04:15
поделиться

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

  1. некоторые шаблоны проектирования основаны на статических методах, например, синглтонах:

    Config.GetInstance ();

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

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

1
ответ дан 27 November 2019 в 04:15
поделиться

Служебные классы могут быть статическими. Как в другом примере выше, с экранированием строк. Проблема заключается в том, что эти классы utils выполняют функции, которые мы хотели бы имитировать. Например, класс FileUtils в сообществе apache - часто бывает так, что я хочу имитировать взаимодействие файлов без необходимости играть с реальными файлами. Если бы это был класс экземпляра, это было бы легко.

1
ответ дан 27 November 2019 в 04:15
поделиться
Другие вопросы по тегам:

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