Играть! framework использует статику <lot>

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

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

Нам всегда говорили, что НИКОГДА НИКОГДА не использовать "статическую" в любой разработанной нами Java-программе, но когда я смотрю Play!... Ну... примерно половина методов статична. & Л; /& преувеличение GT;

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

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

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

Ответ 1

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

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

Ответ 2

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

Основная проблема заключается в том, что вам приходится обрабатывать несколько HTTP-запросов параллельно, а статические поля - "глобальные". Таким образом, для некоторых вещей вам понадобится один экземпляр для потока (или даже лучше, один экземпляр для HTTP-запроса), но некоторые из этих вещей возвращаются статическими методами в Play. Это работает, потому что Play! использует ThreadLocal -s сильно, и поэтому он решает проблему статики вне языка Java. Но это не все. Некоторые говорят, что методы контроллера по праву статичны. Конечно, но в простой Java это было бы неудобно, так как тогда вы не можете получить доступ к данным, зависящим от запроса, без какого-либо префикса, например req. в req.session, а затем вы все равно должны получить req откуда-то, как параметр статического контроллера, который еще более затрудняет. Тем не менее, в Play вы можете просто написать session и, как будто, это просто статические поля. Это потому, что в Play используется инструментарий байт-кода для изменения всех этих ссылок на статические поля на что-то умнее. Опять же, решение за пределами языка Java. Это не статические поля в конце.

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

Ответ 3

С очень кратким взглядом я бы сказал, что это имеет смысл: веб-запросы не имеют гражданства, поэтому нет объекта для получения запроса (= метод). Таким образом, сопоставление URI, такого как "/articles/archive? Date = 08/01/08 & page = 2", для статического метода, называемого archive(), я думаю, ваш класс приложения имеет смысл.

Ответ 4

ИЗМЕНИТЬ Теперь в Play 2.4, инъекция выполняется автоматически. Поэтому просто добавление @в начало пути контроллера в файле routes приведет к трюку:

GET     /                  @controllers.Application.index()

Для более старых версий (от 2.1 до 2.3) вам придется переопределить getControllerInstance в глобальном классе, как описано в Documentantion.

Ответ 5

Как и в любом программировании, никогда никогда не бывает правильного ответа. Как всегда. Всегда есть исключения, и правильный ответ всегда "зависит".

Это правда, что в чистом ОО (для которого я все) очень мало места для статики. Но также верно, что иногда они имеют смысл.

Классический пример - это утилиты. Конечно, было бы лучше, если бы мы могли просто добавить наш метод abs() к Integer. Но мы не можем; поэтому мы застряли с Math.abs(int i).

Я склонен думать, что это просто правильно, чтобы сделать метод статическим, если он не имеет никакого отношения к самому экземпляру. Например, в классе Person у вас может быть метод, который принимает список людей и возвращает число людей, у которых есть день рождения сегодня. Может быть, вы можете сделать это только в самом классе, если данные, необходимые для вычисления, являются частными (что-то, что понимает пурист OO;)), но все же метод явно не имеет отношения к одному экземпляру Person.

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

Я никогда не видел Play! но если вы скажете, что более 50% из них являются статическими, то я предполагаю, что он, вероятно, был плохо разработан. Это не исключение; много каркасов. Не позволяй ему сбить тебя. Определенно не учитесь на этом!
Но если он работает, вы все равно можете его использовать.

Ответ 6

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

Отказ от ответственности: я мало знаю о "игре!"

Ответ 7

Статические методы контроллера, безусловно, являются предметом беспокойства в Play! рамки, и после того, как я провел некоторое тестирование, это главная причина для меня не играть в Play! в проектах. Вы действительно можете увидеть это, где в проектах FOSS, где Play! используется. Тестирование контроллера практически отсутствует. Причина, с помощью статических методов, DI становится затруднительной. Именно здесь они должны были потратить еще больше времени на ASP.NET MVC, откуда Play! уже немного вдохновляет.

Обычно у вас есть такой конструктор:

public HomeController( IService service ) {
   _service = service;
}
public Index() {
   var data = _service.getData();
   return View( data );
}

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

В Play это становится очень тяжелым. Таким образом, тестирование модуля контроллера становится затруднительным. То есть для меня значительная проблема. Поэтому я хотел бы искать другие рамки, кроме Play! в мире Java. Черт, почему бы не пойти с оригиналом и просто использовать JRuby?

Ответ 8

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

Они каким-то образом соответствуют каждому возможному запросу HTTP, и точно так же, как этот HTTP-запрос полностью без гражданства.

При структурном программировании у вас есть процедуры, с одной стороны, и переменные с другой, но по парадигме ООП вы обрабатываете процедуры и переменные в целом.

То есть у вас есть и объект с методами экземпляра (процедуры) и переменными экземпляра.

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

Ответ 9

Я полагаю, что, по крайней мере, мы могли бы использовать одноэлементные объекты

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

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

Это не так. На самом деле, все в порядке.

Ответ 10

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

На самом деле я не согласен с вашим учителем.

Если объект не имеет состояния (то есть глобальных переменных), а просто содержит методы для примера, он не дает вам никаких преимуществ для использования объекта, а не статических методов. За исключением случаев, когда вы планируете добавить состояние позже (состояние, которое не должно быть общим), или если вы используете интерфейс и хотите легко переключаться с реализацией, проще использовать статические методы...

Сам JDK, общедоступность apache или многие фреймворки включают статические методы:

  • StringUtils
  • Pattern.matches(регулярное выражение, вход)

----------

На самом деле, я думаю, вам интересно, что относительно классов, таких как JPA.java: https://github.com/playframework/play/blob/master/framework/src/play/db/jpa/JPA.java

Они используют только статические методы и сохраняют статическое состояние. Это может быть странно, но на самом деле для меня это немного похоже на использование singleton, за исключением того, что методы используются вместо статического контекста вместо объекта. Основное различие заключается в том, что вам не нужно каждый раз называть getInstance().

Я думаю, что это было спроектировано так же, как и для удобства использования, потому что он не удобен для вызова "getInstance", и это круто, чтобы иметь возможность легко проводить сеанс повсюду (связанный с потоком) вместо того, чтобы вводить sessionFactory всюду с помощью xml или автоувеличивание...

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

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

  • В этом случае, когда вы вызываете методы JPA.xxx(), ваш код тесно связан с классом JPA для классов. Но я не думаю, что игра спроектирована так, что вы сможете легко переключаться с одного фреймворка на другой без по крайней мере некоторой переделки...

  • Это большая разница с спецификацией EJB3 или тому подобным: если менеджер объектов EJB3 использует статическую структуру, вам придется жестко связать свой код с реализацией, вызвав HibernateEntityManager.xxx() или ToplinkEntityManager.xxx(). В этом случае существует общий интерфейс (и мы не можем добавлять статические методы на интерфейсы).

----------

  • Этот класс не является частью спецификация, используемая на других рамки.
  • Класс JPA только что одна реализация: то, что сделано играть. И они, вероятно, не планируя сделать второй.
  • Таким образом, плотная связь с этим классом Play, в то время как вы используете Play Framework, кажется мне хорошо.

Ответ 11

Play использует функциональный подход, например node.js, и, возможно, делает "больше смысла" в Scala, чем в Например, Java, как Typesafe Stack. Как отмечали другие плакаты, Java расширяется с использованием инструментария байт-кода (a la Aspect J), чтобы вести себя более независимым/функциональным способом; Scala делает это по умолчанию.

Ответ 12

Если вы являетесь объективом, ориентированным на объектно-ориентированное программирование, вы не должны использовать методы/поля static, однако их можно безопасно использовать и не обязательно вызывать беспокойство IMHO.

Ответ 13

Одной из причин использования статических методов является статический импорт, который позволяет вам сократить нотацию и сделать код более удобочитаемым. Это особенно актуально при использовании таких библиотек, как Guava или Apache Commons, в которых у вас может быть много статических вызовов.

Методы нестатического контроллера теперь поддерживаются в Play 2.1 с помощью инъекции контроллера, поэтому не очень понятно, почему они не были с самого начала.

Ответ 14

Теперь вы можете использовать Spring DI внутри Play, см. fooobar.com/info/8002/.... Я использую его, и он отлично работает до сих пор.