Играть!фреймворк использует <lot>статики - PullRequest
76 голосов
/ 04 марта 2011

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

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

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

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

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

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

Ответы [ 14 ]

95 голосов
/ 04 марта 2011

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

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

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

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

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

15 голосов
/ 04 марта 2011

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

8 голосов
/ 14 декабря 2013

РЕДАКТИРОВАТЬ Теперь в Play 2.4, инъекция выполняется автоматически.Поэтому, просто добавив @ в начале пути контроллера в файле routes, вы поймете:

GET     /                  @controllers.Application.index()

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

5 голосов
/ 04 марта 2011

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

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

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

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

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

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

4 голосов
/ 29 октября 2012

Методы статического контроллера, безусловно, являются проблемой для 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!в мире Java.Черт возьми, почему бы не пойти с оригиналом и просто использовать JRuby?

4 голосов
/ 04 марта 2011

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

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

3 голосов
/ 05 марта 2011

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

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

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

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

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

2 голосов
/ 04 марта 2011

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

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

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

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

1 голос
/ 17 мая 2012

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

...