HTTPリクエスト/レスポンスオブジェクトは不変である必要がありますか?


10

ほとんどのWebアプリケーションは要求/応答パラダイムに基づいていると言っても安全だと思います。PHPは、これらのオブジェクトを正式に抽象化したことがありません。1つのグループがこれを変更しようとしています: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');

初期情報を変更する必要はありません。ただし、リクエストが渡されると、処理情報を追加する必要が生じることがよくあります。たとえば、特定のリクエストに対して実行するアクションを決定するURLマッチャーがあるとします。

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

実際にアクションを実行するのは、下流プロセスの責任です。不変の要求をラップする変更可能なRequestAttributesCollectionを使用することもできますが、実際には少し扱いに​​くい傾向があります。また、属性コレクションを除いて、不変のリクエストを持つこともできます。例外も扱いにくい傾向があります。この種の要件に対処した経験はありますか?


それが必要な元の要求/応答だけの場合は、c'torに設定され、二度と触れられないオブジェクトのクローンを保存できます。変異させることもできますが、必要なときにいつでもオリジナルにアクセスできます。これはおそらく、より良いIMOでした。
mpen 2015

回答:


4

不変の要求/応答オブジェクトを使用すると、どのような利点がありますか

私は@MainMaの声明に同意します。読みやすさのわずかな利点が柔軟性の欠如の可能性を補うかどうかはわかりません」個人的には、PHP HTTP Request一時オブジェクトまたはPHP HTTP Response一時オブジェクトを不変に強制することの実用的で有用な側面はありません。

この種の要件に対処した経験はありますか?

  1. MicrosoftのWindows Presentation Foundationフレームワークでは、フリーズ可能なオブジェクトの概念が導入されています。凍結すると、そのようなオブジェクトは

    • 不変(変更が試みられると例外をスローします)、
    • より高速に使用できます(プロパティゲッターは、もう "空想的な"私の価値は何か "の決定を行う必要がありません)。
    • 消費するメモリが少ない(内部ヘルパーのデータ構造やキャッシュなどは、時間とスペースの効率が最も高い表現に削減できます)
    • そして共有可能

    GUI速度の最適化として使用されますが、コンセプト自体は、その利点を含め、他の場所にも適用できます。

  2. Nancy(「.NetとMonoでHTTPベースのサービスを構築するための軽量で儀式の良いフレームワーク」)は、コミットコメントの1つにおける不変性の利点について説明ています。

    ...キャッシュがオフの場合、キャッシュは不変であると見なすことができます。つまり、ロックがないため、パフォーマンスがより高速になります(ただし、ヒットはそれほど大きくありません)...

    私は不変性に関するその他の注目すべきコメントを見つけられませんでしたが、再利用可能な、キャッシュ可能なレスポンスオブジェクトの利点は、に適用される場合がありますPHPだけでなく

上記はトピックから外れた回答のように見えるかもしれませんが、私は他に何も認識していません。そのため、不変性の要件は人為的な問題であり、むしろ好みやコーディングスタイルなどの問題だと思います。


1
ありがとう。どちらの回答も参考になりました。オブジェクトを凍結するという概念が私の考えを明確にするのに役立ったので、私はあなたのものを受け入れることにしました。不変の凍結された応答オブジェクトが作成されます。オブジェクトを送信する直前の時点で、オブジェクトは複製され、凍結されません。配信指向のヘッダー(キャッシュ、コアなど)の束を追加できます。その後、オブジェクトをフリーズして送信できます。
Cerad 2015

7

不変オブジェクトには、一般的にいくつかの利点があります。

  • 最も重要なのは、並行して実行されるコードで不変オブジェクトを簡単に使用できることです。これは、「不変性がPHPの世界で実際に使われていない」理由も説明しています。

  • 状態の一貫性は簡単に取得できます。

  • オブジェクトは操作しやすく、より自然です。

重要なことは、オブジェクトが存続期間中にどの程度変更する必要があるかです。不変オブジェクトに変更を加えるたびに、追加のインスタンスを作成する必要があり、メモリ(およびおそらくCPUサイクル)の点ですぐにコストがかかります。これはまた、string不変であるほとんどのプログラミング言語がStringBuilder、C#などのある種の可変文字列用の別のクラスを作成し、文字列が多くの小さな部分から連結され、各部分が動的に追加される状況に対応するためです。

クライアント側のライブラリ(HTTPリクエストを送信してレスポンスを受信する)では、HTTPリクエストとレスポンスを不変にするのが理にかなっています。一部のリクエストはFluentインターフェイスで構築できますが、これは主な使用法ではありません。とにかく応答は変更されないので、不変性は理にかなっています。

サーバー側のライブラリー(HTTP要求の受信と応答の送信)では、要求は不変である可能性がありますが、応答が可能であるかどうかはわかりません。データ自体はストリーム(一部の人にとっては、以下を参照)は応答オブジェクトを強制的に変更可能にすることができ、ヘッダー自体は、スクリプトの実行中に、応答が開始されるまで「オンザフライ」で追加できますクライアントに送信されます。

どちらの場合も、並列実行がないことを考えると、可読性のわずかな利点が柔軟性の欠如の可能性を補うかどうかはわかりません。

Evert PotによるPSR-7に関するより完全な記事も必ずお読みください。この記事では、とりわけ、そのような不変性が問題となるケースの1つよりもストリーミングする必要がある長い応答について説明しています。個人的には、私は要点を理解していません。IMHO、不変オブジェクトにストリームを含めることを禁止するものはありません(たとえば、FileReaderオブジェクトは、時間とともに変化する可能性があるファイルを読み取っても、不変である可能性があります)。PythonのFlaskフレームワークは、イテレータを返すことによって大きな応答(または生成に時間がかかる応答)に関して異なるアプローチを使用ます。


1
IMOについて言及する価値のある利点の1つは、不変オブジェクトがある場合、プライベートコピーで作業しているかどうかを自問する必要がないことです。自由に変更したり、変更が他のオブジェクトに影響する可能性がある別のオブジェクトが所有する参照を変更したりできます。
フィリップ

@フィリップ:私見、Java.NETの最大の欠点の1つは、呼び出し元が自由に変更できる新しいオブジェクトへの参照を返すメソッドと、内部にアタッチされているか、内部にカプセル化されている参照を返すメソッドを区別するための規則がないことです。その状態を操作するために変更される可能性のある状態、および内部状態に接続されている、または接続されている可能性があるオブジェクトへの参照を返す状態。どのような種類の参照が返されるかを知らなければ、堅牢で効率的なコードを書くことはできませんが、それを示す規則はありません。
スーパーキャット2015

答えてくれてありがとう。それは私が考えていたことをかなり確認したので、それは正しいに違いない。xmoyxrの答えを受け入れることにしました。彼が私が以前に遭遇したことがないオブジェクトのフリーズの概念を提起したからです。
Cerad 2015
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.