2014-02-13 3 views
2

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

Хотя я не согласен с этим аргументом, я также не вижу другого выбора. Даже если я конвертирую их в методы экземпляра и получаю доступ через экземпляр singleton, экземпляр будет доступен некоторой статической функцией.

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

Заранее спасибо.

+0

Это не проблема. Я не вижу, что здесь происходит со статическими полями. Они подходят для функций полезности и констант. –

+0

Посмотрите на методы, которые вы рассматриваете как статические, и задайте следующие вопросы: Нужно ли сохранять состояние между последовательными вызовами этого метода или связанными с ним методами? Всегда ли вывод этого метода зависит от любых вызовов или настроек, которые произошли до его вызова? Если ответы на оба нет, то статический метод, вероятно, хорошо. Обратите внимание, однако, что, если вы переопределяете множество базовых функций HTTP-сервера, вам будет намного лучше использовать инфраструктуру, которая уже выполняет все низкоуровневые вещи для вас. – chrylis

ответ

3

Вы совершенно правы, что в конечном счете все выполняется со статического метода main(). И многие функции подходят для статичности, например. простые методы, например, на java.lang.Math. Скорость и использование памяти не являются проблемами - статический метод не занимает больше памяти или работает медленнее, чем любой другой метод. Внутри это точно так же, как и любой другой метод, но определяется и выполняется на экземпляре класса вместо экземпляра класса.

Проблема, которую я обнаружил со статическими методами, заключается в том, что легко избежать скольжения в некоторых конкретных предположениях (например, где находится каталог), что затрудняет повторное использование функции в другом месте. Это также может стать намного сложнее проверить код. Когда вы тестируете устройство, вы, как правило, хотите иметь возможность тестировать, не занимая много времени) I/O - например. путем издевательства или вырезания частей ввода-вывода. Если ваш метод не позволяет этого, это намного сложнее. Одиночные классы могут вызывать аналогичные трудности тестирования.

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

Также стоит упомянуть, что вокруг существующих классов полезности есть такие Apache Commons IO, Google Guava и т. Д. Они хорошо написаны, сильно используются и хорошо протестированы. Вы можете рассмотреть их, прежде чем изобретать колесо.

0

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

MyFileReader.readFile("C:/file.txt"); 

выглядит лучше, чем:

MyFileReader mfr = new MyFileReader(); 
mfr.readFile("C:/file.txt"); 

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

+0

Итак, классы ввода-вывода, такие как 'FileReader' или' BufferedReader', реализованы нестационарным способом из-за производительности? – Christian

+0

Другие классы используют их как экземпляры. Существует разница в производительности, но опять же, 'Files.readAllLines()' существует. – christopher

+0

@Christian Нет, эти классы реализованы как экземпляры, потому что вы обычно хотите больше работать с состоянием, чем «сразу прочитать весь этот файл», и что-то вроде этого «MyFileReader» будет использовать экземпляры ввода-вывода с состоянием в своих статических методах. – chrylis

1

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

  • это позволит вам сделать конструктор private, который вместе с классом, помеченный как final ясно говорит, что этот класс является библиотека
  • он позволяет вам импортировать методы статически, как import static SomeClass.someMethod;, так что вам не нужно писать имя класса снова и снова
  • Я действительно сомневаюсь, что производительность - большая проблема, если вы не собираетесь там 1000 методов (что действительно плохой дизайн в любом случае)
+0

Почему downvote? Что не так с моим asnwer? –

1

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

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

Оба подхода (избегайте статического электричества любой ценой/сделайте все статичным) являются плохими.

1

Вы испытываете свой код?

С тестированием, немилость static стала очевидным:

  • вы не можете издеваться статические методами 1: Если вы Util класса открывает файл, то вы необходимо иметь этот файл при тестировании.
  • Вы не можете заменить статические методы.
  • вы не можете создавать более специализированные версии этих методов путем подклассификации классов Util (а затем изменения того, какой класс вводится контейнером CDI).

Если вы строите истинную библиотеку утилиты, которая вряд ли изменится (например, Apache Commons), сделать метод использования экземпляра и использовать одиночка.

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


Развейте: Static Methods are Death to Testability


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

+0

Иногда выбора просто нет, например, метод, выполняющий некоторые манипуляции с строками (без использования или даже изменения глобального состояния). Мы не можем расширять String. Что теперь? – Ingo

+0

Там, в ответе: * «Если вы не создаете настоящую библиотеку утилиты, которая вряд ли изменится (например, Apache Commons), используйте методы экземпляра и используйте одиночные списки». * Если вы создаете библиотеку (например, StringUtils'), то, во что бы то ни стало, используйте статические методы. Но если вы создаете методы утилиты (просто чтобы избежать дублирования кода), и вы будете использовать их, то не делайте их «статическими». Вам не обязательно. Если в тестах вы хотите использовать фактическую версию (вместо макета), используйте их. Проблема с 'static' заключается в том, что такого выбора нет. – acdcjunior

+0

Когда вы говорите «действительно пользуйтесь одиночками», я предполагаю, что вы хотели сказать «do * not * use singletons», верно? –

2

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

Есть два типа «статических методы»:

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

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

0

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

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

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

Смежные вопросы