「すべてを修正」デザインパターンとは何ですか?


74

linuxdevcenter.comのStephen Figginsによるこの2003年の記事では、Bram CohenのBitTorrentは「すべてを修正」デザインパターンを使用していると説明されています。

どちらもBitTorrentを把握するのを難しくしますが、研究に値するあまり一般的ではないアプローチは、Cohenのi等性の使用です。プロセスを複数回適用してもそれ以上変更されない場合、プロセスはprocess等です。Cohen氏は、「すべてを修正」と呼ばれるデザインパターンを使用すると言います。これは、何が変わるかを実際に気にすることなく、多くの変更に反応できる機能です。彼は、「あなたは起こった出来事に注意し、そしてこの非常にwritten等な方法で書かれたすべてを修正する関数を呼び出し、起こっているかもしれないことをすべてクリーンアップし、ゼロからすべてを再計算する」と説明する。べき等性は困難な計算を簡単にしますが、少し複雑になります。コールが変更される場合、それが常に明確になるとは限りません。事前に知る必要はありません。関数を自由に呼び出すことができますが、

これは一見するとかなりいいですね。

ただし、べき等の「すべてを修正」関数を呼び出すと、効率を犠牲にしてシステムの堅牢性を向上させ、潜在的に収容システムを混乱させる可能性があります(慎重に計画して実行するプロセスを好む可能性があります)。

ただし、以前に使用したとは言えません。また、彼のアプリケーションのソースをオンラインで見つけることはできません(ただし、これに基づいていると主張するこのソースは見つかりました)。また、この記事以外で参照することもできません(そして、私のgoogle-fuはかなり良いと思います)が、SOApatterns.orgで「べき等機能」のエントリを見つけました。

このアイデアは別の名前でよく知られていますか?

「すべてを修正」デザインパターンとは何ですか?長所と短所は何ですか?


4
名前は、関数の固定小数点x = f(x)のアイデアへの参照でもあると思います。何回fxに適用しても、結果は同じです。正しい結果が得られたら、正しい結果を再処理すると同じ正しい結果が返されます。
9000

7
誰でも任意の名前を付けることができますが、それが有名なソフトウェアパターンになるわけではないことに注意してください。べき等は、それ自体がよく知られた概念です。ここで創造的に使用されているように見えます。
ロバートハーヴェイ

1
これは、メインイベントループがMac OSでどのように実装されたかを思い出させます。これは、任意のイベントに応答する単一の機能であり、通常、すべてのコントロールの状態をテストし、必要に応じてUI全体を更新するように構成されていました。I等、確かに。
ルーカス

3
This sounds quite nice on the face of it. 本当に?私には恐ろしいですね!
マイケル

3
@Michaelパッケージマネージャーが嫌いですか?彼らは同じコンセプトで、より小さなスケールで動作します:システムに見せたいものをマークし、「すべてを修正」を実行し、必要に応じてインストール/削除/アップグレードしますが、変更があった場合にのみ行うことができます。
イズカタ

回答:


100

かなり複雑なHTMLページがあるとします。1つのドロップダウンで何かを選択すると、別のコントロールが表示されたり、3番目のコントロールの値が変更されたりする場合があります。これにアプローチする方法は2つあります。

  1. そのコントロールのイベントに応答し、必要に応じて他のコントロールを更新する、各コントロールごとに個別のハンドラーを作成します。

  2. ページ上のすべてのコントロールの状態を調べ、すべてを修正する単一のハンドラーを作成します

2番目の呼び出しは「べき等」です。繰り返し呼び出すことができ、コントロールが常に適切に配置されるためです。一方、コールが失われたり繰り返されたりすると、最初のコールに問題が生じる場合があります。たとえば、ハンドラの1つがトグルを実行する場合です。

2番目の呼び出しのロジックはもう少しわかりにくくなりますが、1つのハンドラーを記述するだけで済みます。

また、両方のソリューションをいつでも使用でき、必要に応じて「すべてを修正する」機能を「安全のために」呼び出すことができます。

2番目の方法は、状態がさまざまなソース、たとえばユーザー入力とサーバーからのレンダリングに由来する場合に特に便利です。ASP.NETでは、ページをレンダリングするたびに「すべてを修正」機能を実行するだけなので、この手法はポストバックの概念と非常によく合います。

イベントが失われたり繰り返されたり、さまざまなソースから状態を取得したりしたことを述べたので、このアプローチがBitTorrentのような問題空間にどのようにうまくマップされるかは明らかだと思います。

短所?明らかな欠点は、常にすべてを調べるのは効率が悪いため、パフォーマンスが低下することです。しかし、BitTorrentのようなソリューションは、スケールアップではなくスケールアウトに最適化されているため、そのようなことには適しています。解決しようとしている問題によっては、適切でない場合があります。


9
MVCは「すべてを修正」の典型であるように思えます。モデルを変更してからビューを最初から再描画すると、アクションが影響を与える可能性のある部分を推測しようとせずに、ビューが完全に再描画されます。
マチューM.17年

3
これは、Saltstack、Ansible、Nixなどのシステムの背後にある原理に本質的に似ています。構成の説明があれば、理論的には複数の多様なシステムを同じ最終状態にすることができます。
小次郎

1
なつみ 反応しそう差分の仮想DOMはそれだけで実際の変更で実際のDOMを更新しない以外、フロントエンドの開発にかなり普及しているものと同様である、
Izkata

2
@Izkata React以上に、この答えは私にReduxのことを考えさせました。
ケビン

2
「すべてを修正する」とべき等は異なるものであると指摘すると便利です。「すべてを修正する」は通常、べき等です(しかし、そうする必要はありません)。ペナルティ-2回実行しても同じ結果が得られます。
ハンス・ピーターStörr17年

15

この記事は少し古くなっていると思います。これを読んだとき、これはまったく正統的でも新しいアイデアでもないからです。このアイデアは、実際には単なるObserverの実装である場合、別のパターンとして提示されます。当時のことを考えてみると、相互に依存するデータを含むさまざまなパネルを備えたやや複雑なインターフェイスの背後にあるロジックに取り組んだことを覚えています。ユーザーは値を変更したり、最適化ルーチンを実行したりすることができ、それらのアクションに基づいて、UIが必要に応じてリッスンして更新するイベントが生成されました。開発中に、特定のパネルが必要なときに更新されないという問題がいくつかありました。修正(設計内にとどまる)は、他のイベントからイベントを生成することでした。最終的に、すべてが正常に機能するまでに、ほとんどすべての変更により、すべてのパネルが更新されました。特定のパネルを更新する必要があるときに隔離しようとする複雑さは、すべて無駄でした。とにかく問題ではありませんでした。事実上、時期尚早の最適化でした。すべてをすべてを更新する単一のイベントに折りたたむだけで、時間と労力を大幅に節約できます。

「すべてを修正」またはすべてを更新する方法で設計された無数のシステムがあります。行を追加/更新してからDBを再クエリするすべてのCRUDインターフェイスを考えてください。これはエキゾチックなアプローチではなく、明らかな非賢いソリューションです。2003年には、それが「パターンフィーバー」の高さだったことに気づかなければなりません。私が言えることから、人々は新しいパターンの命名が名声と富への道になると考えていました。誤解しないでください。パターンの概念は、抽象でソリューションを説明するのに非常に役立つものだと思います。ちょっと物事は少しレールから外れました。それは一般的にパターンの概念について多くの皮肉を作成したため、それは残念です。これを「非正統的」な解決策として語ることが理にかなっているのは、この文脈においてのみです。それ' ■ORMまたはDIコンテナの正統性に似ています。これらのツールが存在するずっと前に人々がソフトウェアを構築していたにもかかわらず、それらを使用しないことは非正統的と見なされ、多くの場合、これらのツールは過剰です。

「すべてを修正する」に戻ります。簡単な例は、平均の計算です。簡単な解決策は、数値を合計し、値の基数で除算することです。番号を追加または変更する場合、最初からやり直します。合計と数字のカウントを追跡し、誰かが数字を追加すると、カウントを増やして合計に追加します。これで、すべての数値を再度追加することはありません。範囲を参照し、その範囲内の単一の値を変更する数式でExcelを使用したことがある場合、「すべてを修正」パターンの例があります。つまり、その範囲への参照を持つ数式は、その値は関連していました(例:sumif()のようなものを使用)。

これは、これが特定のコンテキストで賢明な選択ではないということではありません。平均的な例では、更新をサポートする必要があるとしましょう。ここで、古い値を何らかの方法で知り、合計をデルタだけ変更する必要があります。分散環境または同時実行環境でこれを行うことを検討するまで、これは実際にそれほど難しくありません。今、あらゆる種類の厄介なタイミングの問題に対処する必要があり、おそらく再計算よりもはるかに遅くなる大きなボトルネックを作成することになります。

ここでの結論は、「すべてを修正する」または「すべてを更新する」アプローチがはるかに簡単になることです。より洗練されたアプローチを機能させることができますが、はるかに複雑であるため、欠陥が発生する可能性が高くなります。さらに、多くのコンテキストで、「すべてをリフレッシュ」アプローチの方が効率的です。たとえば、コピーオンライトアプローチは、シングルスレッドアプローチでは一般に低速ですが、同時実行性が高い場合、ロックを回避できるため、パフォーマンスが向上します。また、効率的な方法で変更をまとめてバッチ処理できる場合もあります。そのため、ほとんどの問題では、それができない特定の理由がない限り、すべてをリフレッシュするアプローチから始めて、必要になったらもっと複雑なことをすることを心配するでしょう。


2
私はExcelが再計算するすべてのセルをトリガする方法があります理由だけである、変化に依存している細胞を再計算する意向かなり確信している:superuser.com/questions/448376/...私はだろうと仮定(「すべてのものを修正します」 )
アーロンホール

@AaronHallもしそうなら、それは本当に悪い実装です。私は定期的に、たとえば60,000個のセルを計算するために15〜30分間、7個のCPUの100%を消費するのを監視しています。計算は複雑ではありません。Pythonの起動を含め、数秒でシートのすべてを実行できるPythonプログラムを頻繁に作成しました。これは、どのくらい時間がかかるかについての私の最善の推測でした。それは私が推測する他の何かかもしれません。また、Excelには、この機能の原因である可能性のある非常に古いバグが多数あります。
ジミージェームズ

1
@AaronHallそのユーザーでも、シートで自動計算が無効になっている可能性があります。エンターキーを押すたびに15分の余裕がないので、大きなワークブックでこれを頻繁に行います。
ジミージェームズ

@AaronHall私はもう少し考えて、あなたはポイントを持っています。私の仮定はおそらく広範すぎる。私は自信を持って何かに焦点を当てて答えを更新しました。
JimmyJames

2
@JimmyJames:私が意図したことは、最善のアプローチは状況に応じて大きく異なり、「すべてを修正」は「個々の変更ごとにすべてを熱心に修正する」と「すべての変更が完了した後にすべてを怠fixに修正する」に細分できることです「。
supercat

4

それが「デザインパターン」であるかどうかはわかりませんが、Puppet、Chef、またはPowershell DSCの流れに沿って、このタイプの動作を終了状態構成または望ましい状態構成として分類します

これらのソリューションは、通常、質問で説明されているビジネスロジックレベルではなく、システム管理レベルで動作しますが、事実上同じパラダイムです。このようなツールは通常、本質的に宣言的ですが、手続き型コードまたはスクリプトにも同じ原則を適用できます。


1

私はこれをユーザーインターフェイス内で主に使用しています。良い点は、一度書くだけで、最も単純なものから最も難しいものまですべてを等しく処理できることです(たとえば、ユーザーが画面を回転する場合、またはユーザーがウィンドウのサイズを変更する場合はラップトップ/デスクトップで、事実上すべてが変更される場合) )。

効率を心配する理由はあまりありません。ユーザーインターフェイスでは、高価なものは、移動されたアイテムの再描画などです。通常、各アイテムの位置と大きさの計算は非常に高速です。確認する必要があるのは、アイテムが属する場所に正確に留まる必要があることがわかったときは、それを移動するためのコードは実行されないということだけです。実際の変更は、とにかくやらなければならなかったすべてのことです。


0

リアクティブプログラミングの原理のように聞こえます。「すべてを修正」は、現在の「コア」状態を見て、影響を受けるはずのその他すべての「計算済み状態」を伝播します。この導出を最適化すると、a-la Reactの高効率に達する可能性があります。単純に行うと、パフォーマンスは最適ではないかもしれませんが、それでも十分高速です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.