Должны ли объекты HTTP Request / Response быть неизменными?

10

Я думаю, можно с уверенностью сказать, что большинство веб-приложений основаны на парадигме запрос / ответ. В PHP никогда не было формальной абстракции этих объектов. Одна группа пытается изменить это: https://github.com/php-fig/fig-standards/blob/master/proposed/http-message.md

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

Кроме того, неизменность никогда не завоевывала популярность в PHP.

Какие преимущества видят люди в использовании неизменяемых объектов запроса / ответа?


Предположим, вы возвращаете объект json.

$response = new JsonResponse($item);

Красиво и просто. Но оказывается, что запрос был запросом общего доступа к ресурсам (CORS). Код, который генерирует ответ, не должен заботиться, но где-то вниз по течению это процесс, который добавит необходимые заголовки Access-Control. Есть ли преимущество в сохранении исходного ответа и создании нового с дополнительными заголовками? Или это строго вопрос стиля программирования.

Объект запроса немного интереснее. Это начинается с того же:

$request = new Request('incoming request information including uri and headers');

Исходная информация не должна быть изменена. Однако, поскольку запрос get передается, часто возникает необходимость добавить дополнительную информацию для обработки. Например, у вас может быть средство сопоставления URL-адресов, которое решает, какое действие следует выполнить для данного запроса.

$request->setAttribute('action',function() {});

Фактически выполнение действия является обязанностью нисходящего процесса. Вы можете иметь изменяемый RequestAttributesCollection, который оборачивает неизменяемый запрос, но на практике это немного неловко. Вы также можете иметь запрос, который является неизменным, за исключением коллекции атрибутов. Исключения тоже бывают неловкими. Есть опыт работы с такими требованиями?

Cerad
источник
Если вам нужен только исходный запрос / ответ, мы можем сохранить клон объекта, который устанавливается в c'tor, а затем никогда не затрагивается снова. Вы можете изменить его, но при этом получить доступ к оригиналу. Это наверное было бы лучше IMO.
mpen

Ответы:

4

Какие преимущества видят люди в использовании неизменяемых объектов запроса / ответа?

Я согласен с высказыванием @ MainMa « Я не уверен, компенсирует ли небольшое преимущество читабельности возможное отсутствие гибкости », и лично я не вижу каких-либо практических и полезных аспектов, заставляющих PHP HTTP Requestвременные объекты или PHP HTTP Responseвременные объекты быть неизменяемыми

Есть опыт работы с такими требованиями?

  1. Windows Presentation FoundationКаркас Microsoft представляет концепцию замораживаемых объектов . После замерзания такие предметы становятся

    • неизменный (генерировать исключения при попытке изменения),
    • быстрее использовать (получателям собственности больше не нужно принимать какие-то причудливые решения «какова моя ценность?»),
    • потребляет меньше памяти (внутренние вспомогательные структуры данных и кэши и т. д. могут быть сокращены до их наиболее эффективного с точки зрения времени и пространства представления)
    • и поделился

    Хотя она используется для оптимизации скорости графического интерфейса, сама концепция применима и в других местах, включая ее преимущества

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

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

    Я не нашел какие - либо другие примечательные комментарии о неизменности, но польза от многократного использования, кэшируемых объектов реагирования может применяться к PHPа

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

xmojmr
источник
1
Спасибо. Оба ответа были информативными. Я решил принять твое, потому что понятие замораживания предметов помогло прояснить мое мышление. Создан неизменный замороженный объект ответа get, так как некоторая точка непосредственно перед отправкой объекта get клонируется и разморожается. Могут быть добавлены группы заголовков, ориентированных на доставку (кэши, cors и т. Д.). Затем объект может быть заморожен и отправлен в путь.
Cerad
7

Неизменяемые объекты в целом имеют несколько преимуществ.

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

  • Государственную согласованность легче получить.

  • С объектами легко работать, они более естественны.

Важным моментом является то, насколько объект должен измениться в течение срока его службы - каждое изменение неизменяемого объекта требует создания дополнительного экземпляра, который может быть слишком дорогим с точки зрения памяти (и, возможно, циклов ЦП). По этой же причине большинство языков программирования, в которых stringнеизменяемость, заканчивают тем, что имеют другой класс для некоторой изменяемой строки, такой как StringBuilderв C #, для реагирования на ситуации, когда строки объединяются из множества мелких частей, каждая часть добавляется динамически.

В библиотеке на стороне клиента (отправка HTTP-запроса и получение ответа) имеет смысл сделать HTTP-запрос и ответ неизменными: хотя некоторые запросы могут создаваться с использованием свободного интерфейса, это не основное применение. Ответ в любом случае не изменится, поэтому неизменность имеет смысл.

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

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

Обязательно прочитайте более полную статью Эверта Пота о PSR-7 . В статье, среди прочего, объясняется, что один из случаев, когда такая неизменность является проблематичным, касается длинных ответов, которые следует передавать в потоковом режиме . Лично я не вижу смысла: ИМХО, ничто не запрещает неизменяемому объекту содержать поток (например, FileReaderобъект может быть неизменным, даже если он читает файл, который может меняться со временем). Платформа Flask в Python использует другой подход, когда речь идет о больших ответах (или ответах, которые требуют времени для генерации) путем возврата итератора.

Арсений Мурзенко
источник
1
Одно из преимуществ, которое также стоит упомянуть IMO, заключается в том, что когда у вас есть неизменяемые объекты, вам не нужно спрашивать себя, работаете ли вы с частной копией, вы можете свободно изменять или ссылаться на другой объект, если изменения могут повлиять на другие объекты.
Филипп
@Philipp: ИМХО, одним из самых больших недостатков в Java.NET является отсутствие соглашения, позволяющего различать методы, которые возвращают ссылки на новые объекты, которые вызывающий может изменить по желанию, и методы, которые возвращают ссылки, которые присоединены или инкапсулируют внутренние состояние, которое может быть изменено для манипулирования этим состоянием, и состояние, которое возвращает ссылки на объект, который может или может быть присоединен к внутреннему состоянию. Невозможно написать надежный и эффективный код, не зная, какие ссылки должны возвращать вещи, но не существует соглашения, указывающего это.
Суперкат
Спасибо за ответ. Это в значительной степени подтвердило то, что я думал, так что это должно быть правильно. Я решил принять ответ xmoyxr, потому что он поднял концепцию замораживания объектов, с которыми я раньше не сталкивался.
Cerad