Играй! фреймворк использует статику


Waaah, игра! база имеет много статических методов. Где я хожу в школу, нам сказали никогда чтобы использовать любую статику, но играть! использует его, как будто завтра не наступит. Это как-то нормально? Если да, то почему?

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

нам всегда говорили, однако, НИКОГДА чтобы использовать ' static в любой Java-программе, которую мы разработали, но когда я смотрю на игру! ... Что ж... около половины методов являются статическими. преувеличение>

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

Итак, я должен быть обеспокоен этим? Сделали так, как играют! разработчики запрограммировали его сделать так, чтобы вся эта статика не представляла проблемы?

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

14 76

14 ответов:

Play использует статические методы только тогда, когда это имеет смысл:

  • на уровне контроллера, потому что контроллеры не являются объектно-ориентированными. Контроллеры действуют как сопоставитель между миром HTTP (то есть без состояния и на основе запроса/ответа) и уровнем модели, который полностью ориентирован на объект.
  • в слое модели для заводских методов, таких как findAll(), count(), create (), которые, конечно же, не зависят от каких-либо конкретных экземпляров
  • в какой-то пьесе.библиотеки.* учебные занятия что обеспечивает чисто утилитарные функции

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

ключевая проблема заключается в том, что вы должны обрабатывать несколько HTTP-запросов параллельно, а статические поля являются "глобальными". Таким образом, вам понадобится один экземпляр на поток (или даже лучше, один экземпляр на HTTP-запрос) для определенных вещей, но некоторые из этих вещей возвращаются статические методы в игре. Это работает, потому что играть! использует ThreadLocal-s сильно, и поэтому он решает проблему статики за пределами языка Java. Но это еще не все. Некоторые говорят, что методы контроллера по праву статичны. Конечно, но в простой Java это было бы неудобно, так как тогда вы не можете получить доступ к конкретным данным запроса без какого-либо префикса, например req. in req.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. я использую его, и он отлично работает до сих пор.