Играй! фреймворк использует статику
Waaah, игра! база имеет много статических методов. Где я хожу в школу, нам сказали никогда чтобы использовать любую статику, но играть! использует его, как будто завтра не наступит. Это как-то нормально? Если да, то почему?
Мы (7 человек и я) планируем использовать играть! фреймворк для проекта с участием веб-приложения. Мы решили сделать это с игрой! поскольку это выглядит довольно весело, все мы уже знаем Java, и задание довольно сложно, поэтому мы хотели сосредоточиться на фактическое задание вместо того, чтобы также научиться программировать на другом языке.
нам всегда говорили, однако, НИКОГДА чтобы использовать ' static в любой Java-программе, которую мы разработали, но когда я смотрю на игру! ... Что ж... около половины методов являются статическими. преувеличение>
Я полагаю, по крайней мере, мы могли бы использовать одноэлементные объекты (используя Scala, например ^^) для программирования нашего проекта, но меня очень беспокоит, сколько там статики на самом деле находятся в рамках себя.
Итак, я должен быть обеспокоен этим? Сделали так, как играют! разработчики запрограммировали его сделать так, чтобы вся эта статика не представляла проблемы?
(например, этой теме имеет разглагольствования о том, почему статические члены следует избегать любой ценой.)
14 ответов:
Play использует статические методы только тогда, когда это имеет смысл:
- на уровне контроллера, потому что контроллеры не являются объектно-ориентированными. Контроллеры действуют как сопоставитель между миром HTTP (то есть без состояния и на основе запроса/ответа) и уровнем модели, который полностью ориентирован на объект.
- в слое модели для заводских методов, таких как findAll(), count(), create (), которые, конечно же, не зависят от каких-либо конкретных экземпляров
- в какой-то пьесе.библиотеки.* учебные занятия что обеспечивает чисто утилитарные функции
Play framework не является хорошей демонстрацией того, когда использование статики уместно, и это не доказывает, что ваш учитель был неправ. Игра является своего рода обманом, решает вопросы статики за пределами языка Java.
ключевая проблема заключается в том, что вы должны обрабатывать несколько HTTP-запросов параллельно, а статические поля являются "глобальными". Таким образом, вам понадобится один экземпляр на поток (или даже лучше, один экземпляр на HTTP-запрос) для определенных вещей, но некоторые из этих вещей возвращаются статические методы в игре. Это работает, потому что играть! использует
ThreadLocal
-s сильно, и поэтому он решает проблему статики за пределами языка Java. Но это еще не все. Некоторые говорят, что методы контроллера по праву статичны. Конечно, но в простой Java это было бы неудобно, так как тогда вы не можете получить доступ к конкретным данным запроса без какого-либо префикса, напримерreq.
inreq.session
, и тогда вы все еще должны получитьreq
откуда-то, как параметр метода статического контроллера, который даже больше хлопот. Еще в игре вы можете просто написатьsession
и вроде бы они просто статические поля. Это потому, что Play использует инструментарий байт-кода, чтобы изменить все эти статические ссылки на поле на что-то более умное. Опять же, решение вне языка Java. Это не статические поля в конце.так что, в общем, избегайте неокончательной статики. Игры магия для вас, поэтому не бойтесь их в этом случае.
С очень краткого взгляда я бы сказал, что это имеет смысл: веб-запросы не имеют состояния, поэтому есть и нет объекта для получения запроса (=метод). Таким образом, сопоставление URI, такого как "/articles/archive?date=08/01/08&page=2 " к статическому методу под названием
archive()
о, думаю, класс приложений имеет смысл.
EDIT Теперь в игре 2.4, инъекции делается автоматически. Поэтому просто добавьте @ в начале пути контроллера в файл
routes
сделает трюк:GET / @controllers.Application.index()
для более старых версий (2.1-2.3) вам придется переопределить getControllerInstance в глобальном классе, как описано в Documentantion.
как и все в программировании, никогда это не правильный ответ. Так же, как всегда. Всегда есть исключения, и правильный ответ всегда 'это зависит'.
Это правда, что в чистом OO (который я все для) Есть очень мало места для статики. Но это также правда, что иногда они просто имеют смысл.
классический пример-это утилитарные методы. Конечно, было бы лучше, если бы мы могли просто добавить наш
abs()
метод Целое число. Но мы не можем, поэтому мы застряли сMath.abs(int i)
.Я склонен думать, что это просто правильно сделать статический метод, если он не имеет ничего общего с самим экземпляром. Например, в классе
Person
, у вас может быть метод, который берет список людей и возвращает количество людей, у которых сегодня день рождения. Возможно, вы можете сделать это только в самом классе, если данные, необходимые для вычисления, являются частными (что-то, что пурист OO поймет ;)) но все же метод явно не имеет отношения к одному человеку экземпляр.другое дело, внутренние классы. Вы часто хотите сделать их статическими, если вам не нужна связь с содержанием типа.
Я никогда не видел играть! но если вы говорите, что более 50% из них статичны, то я предполагаю, что это, вероятно, плохо спроектировано. Это не исключение, много рамок. Не позволяй этому тебя расстроить. Определенно не учитесь у него!
Но если это сработает, вы все равно можете использовать его.
основная проблема заключается в том, что статические методы имеют доступ только к другим статическим методам и полям, что приводит к "статическому цеплянию", в результате чего статические методы должны встречаться с остальной частью приложения (которая содержит его сотрудников) через общие статические поля, что приводит к негибкости.
отказ от ответственности: я не знаю много о 'играть!-
статические методы контроллера, безусловно, являются областью беспокойства с игрой! фреймворк, и после проведения некоторых тестов, это главная причина, по которой я не играю! в проектах. Вы действительно можете увидеть это, где в проектах FOSS, где играют! предназначенный. Существует мало или нет тестирования контроллера. Причина, с помощью статических методов, DI становится трудно. Именно здесь они должны были провести еще больше времени ASP.NET MVC, откуда играть! уже занимает немного вдохновение.
обычно у вас есть такой конструктор:
public HomeController( IService service ) { _service = service; } public Index() { var data = _service.getData(); return View( data ); }
затем вы используете DI для внедрения реализации IService в контроллер. Дело в том, что в ваших тестах вы можете создать экземпляр IService непосредственно перед запуском контроллера, а затем проверить результат на основе только что созданного IService.
в игре это становится очень трудно. Таким образом испытание блока регулятора будет трудным. Это, на мой взгляд, существенная проблема. Поэтому я бы как правило, ищут другие рамки, чем играть! в мире Java. Черт, почему бы не пойти с оригиналом и просто использовать JRuby?
метод статики в игре главным образом использован в методах действия регуляторов. Эти методы предназначены только для извлечения необходимых данных из модели и предоставления их представлениям.
они каким-то образом соответствуют каждому возможному http-запросу, и, как и эти http-запросы, полностью не имеют состояния.
в структурном программировании у вас есть процедуры с одной стороны, и переменные с другой, но в парадигме ООП вы рассматриваете процедуры и переменные как целый.
то есть у вас есть и объект с методами экземпляра (процедурами) и переменными экземпляра.
но действия контроллера не имеют состояния, то есть они получают все переменные из запроса (возможно, также из кэша, но в этом случае вам нужен какой-то идентификатор сеанса, который, наконец, поступает из запроса). Таким образом, действия контроллера похожи на процедуры stateles, и именно поэтому они не особенно вписываются в парадигму ООП, как это делают модели.
Я полагаю, по крайней мере, мы могли бы использовать объекты Singleton
синглтон в Java не имеет большого значения, чем использование всех статических. Там не так много, чтобы хранить как состояние, а также. Я думаю, вам не стоит беспокоиться об этом.
Итак, я должен быть обеспокоен этим? Сделали так, как играют! разработчики запрограммировали его сделать так, чтобы вся эта статика не представляла проблемы?
Он не будет. На самом деле, это ладно.
Я также удивлен количеством статических методов в игре, но почему бы и нет, если он работает нормально...
на самом деле я не согласен с вашим учителем.
Если объект не имеет состояния (т. е. глобальных переменных), но просто содержит методы для exemple, это не дает вам никаких преимуществ для использования объекта, а не статических методов. Кроме тех случаев, когда вы планируете добавить состояние позже (состояние, которое не должно быть общим), или если вы используете интерфейс и хотите легко переключаться реализации, проще использовать статические методы...
сам JDK, Apache commons или многие фреймворки включают статические методы:
- StringUtils
- узор.совпадения (регулярное выражение,ввод)
----------
на самом деле я думаю, вам интересно, что такое классы, как JPA.Ява: https://github.com/playframework/play/blob/master/framework/src/play/db/jpa/JPA.java
Они используют только статическое методы и сохранить статическое состояние. Это может быть странно, но на самом деле для меня это немного похоже на использование синглтона, за исключением того, что методы используются в статическом контексте вместо объекта. Основное отличие заключается в том, что вам не нужно вызывать getInstance() каждый раз.
Я думаю, что это было разработано так для удобства использования, потому что это не удобно для пользователя, чтобы вызвать "getInstance", и это здорово, чтобы иметь возможность легко получить сеанс везде (связанный с потоком) вместо инъекции sessionFactory везде с xml или autowiring...
поэтому, возможно, правило должно заключаться в том, чтобы избегать использования статики, за исключением тех случаев, когда вам все равно о плотной связи.
на этот случай, когда вы звоните JPA.xxx () методы, ваш код тесно связан с классом JPA Play framework. Но я не думаю, что игра разработана так, чтобы вы могли легко переключаться с одного фреймворка на другой без какой-либо переделки...
Это большая разница со спецификацией EJB3 или что-то вроде этого: если методы ejb3 entity manager где статические, вы были бы вынуждены плотно связать свой код реализация путем вызова HibernateEntityManager.xxx () или ToplinkEntityManager.xxx(). В этом случае существует общий интерфейс (и мы не можем добавлять статические методы на интерфейсы).
----------
- этот класс не является частью спецификация используемая на другом интегрированные системы.
- класс JPA имеет только одна реализация: тот, который сделал играть. И они, вероятно, не планирую сделать второй.
- таким образом a в обтяжку сцепление с этим игровым классом, пока вы используете Play framework, выглядит ОК для меня.
игра принимает функциональный подход, как узел.js например, и, возможно, имеет "больше смысла" в Scala, чем в Java, как Typesafe Stack толкает, например. Как указывали другие плакаты, Java расширяется с использованием инструментария байт-кода (A La Aspect J), чтобы вести себя более безгосударственным/функциональным способом; Scala делает это по умолчанию.
Если вы являетесь пуристом объектно-ориентированного программирования, вы не должны использовать
static
методы / поля, однако они могут быть использованы безопасно, и не должны быть причиной для беспокойства ИМХО.
одной из причин использования статических методов является статический импорт, который позволяет сократить нотацию и сделать код более читаемым. Это особенно верно при использовании служебных библиотек, таких как Guava или Apache Commons, в которых у вас может быть много статических вызовов.
нестатические методы контроллера теперь поддерживает в Play 2.1 с помощью инъекции контроллера, так что не очень понятно, почему они не были там с самого начала.
теперь вы можете использовать Spring DI в Play, см. https://stackoverflow.com/a/16552598/10433. я использую его, и он отлично работает до сих пор.