web-dev-qa-db-ja.com

必要なUIのみを更新するメソッドをさらに定義する必要がありますか、それともメソッドを減らして一部のUIを不必要に更新する必要がありますか?

たとえば、入力データとUIが1対1の関係にないとします。 enter image description here

html:

<script>
aChanged=function(){
};

bChanged=function(){
};

cChanged=function(){
};
</script>
a:<input id="a" onchange="aChanged()"/>,b:<input id="b" onchange="bChanged()"/>,c:<input id="c" onchange="cChanged()"/><br/>
a+b=<span id="a+b"></span><br/>b+c=<span id="b+c"></span><br/>a+c=<span id="a+c"></span>

「a」を変更すると、「a + b」と「a + c」を更新する必要があります。私の質問は、更新UI関数をどのように記述すればよいですか?

スタイル1:より多くのメソッドを定義しますが、更新にはUIのみが必要です:

aChanged=function(){
  updateAB();
  updateAC();
};

bChanged=function(){
  updateAB();
  updateBC();
};

cChanged=function(){
  updateBC();
  updateAC();
};

updateAB=function(){
  document.getElementById("a+b").innerHTML=Number(document.getElementById("a").value)+Number(document.getElementById("b").value);
};

updateBC=function(){
  document.getElementById("b+c").innerHTML=Number(document.getElementById("b").value)+Number(document.getElementById("c").value);
};

updateAC=function(){
  document.getElementById("a+c").innerHTML=Number(document.getElementById("a").value)+Number(document.getElementById("c").value);
};

スタイル2:より少ないメソッドを定義しますが、一部のUIを不必要に更新する可能性があります(例:変更aはb + cも更新する場合があります):

aChanged=function(){
  updateABC();
};

bChanged=function(){
  updateABC();
};

cChanged=function(){
  updateABC();
};

updateABC=function(){
  document.getElementById("a+b").innerHTML=Number(document.getElementById("a").value)+Number(document.getElementById("b").value);
  document.getElementById("b+c").innerHTML=Number(document.getElementById("b").value)+Number(document.getElementById("c").value);
  document.getElementById("a+c").innerHTML=Number(document.getElementById("a").value)+Number(document.getElementById("c").value);
};

どのスタイルを使うべきですか?

4
ocomfd

利点と欠点は状況に応じて異なるため、これに対する明確な答えはありません。頭に浮かぶ要因をいくつか挙げます。

以下の調査結果を要約すると、スタイル2は労力が少なくて済み、一般的にバグが少ないため、非常に優れています。ただし、スタイル1は、開発の労力よりもランタイムパフォーマンスを重視する場合に優れています(また、2つの間に意味のあるパフォーマンスの違いがあります)。


純粋な努力

5つの値があり、32の異なる合計を計算するとします(ナプキンの裏側、つまり、5つの値で実行できる個別の加算の数)。 5つの値はそれぞれ16の合計で使用され、他の16の合計では無視されます。

  • スタイル1を使用して、テキストボックス変更イベントごとに16のUpdateThisParticularSum()呼び出しを記述する必要があります。つまり、合計で80チェックです。 32個の異なるUpdateThisDistinctSum()メソッドがありますが、それらを合計80回呼び出す必要があります。
  • スタイル2を使用すると、UpdateEverythingAtOnce()メソッドは32個の値を再計算する必要があります。

この例では、値間の関係の量(それらを追加する方法または追加しない方法)が最大化されているため、すべてを手動で処理する必要があり、面倒になります。

32個の値があり、4つの異なる合計を計算するとします(=値間の関係の量を最小化します)。合計で各値が使用される頻度は不明ですが、均等な分布で各値が合計2回使用されると仮定すると、すべての合計で合計64個の使用値になります。

  • スタイル1を使用すると、テキストボックスの変更イベントごとに4つのUpdateThisParticularSum()呼び出しを作成する必要があります。つまり、合計で64チェックになります。 4つの異なるUpdateThisDistinctSum()メソッドがありますが、それらを合計64回呼び出す必要があります。
  • スタイル2を使用すると、UpdateEverythingAtOnce()メソッドは4つの値を再計算する必要があります。

どちらの場合も、スタイル1は常に行数が多くなります。与えられた量の値から計算する合計が多いほど、行数の増加が過剰になります。

勝者:スタイル2。


パフォーマンス

加算は、パフォーマンスコストを無視できる単純な計算です。 10秒かかる非常に複雑なものを計算しているとしましょう。私は引き続きそれらを「合計」と呼んで、私の回答との整合性を保ちますが、それらは任意の複雑な数学的タスクであると想定できます。

3つの値と3つの合計(例)

  • スタイル1では、各入力は2つの合計にのみ影響します。これは20秒再計算時間になります。
  • スタイル2では、各入力は3つすべての合計を再計算します。これは再計算時間になります。

32の値と4つの合計(私の例2)

  • スタイル1では、各入力は2つの合計にのみ影響します。これは20秒再計算時間になります。
  • スタイル2では、各入力は4つすべての合計を再計算します。これは40秒再計算時間になります。

5つの値と32の合計(私の例1)

  • スタイル1では、各入力は16の合計にのみ影響します。これは160秒再計算時間になります。
  • スタイル2では、各入力は32の合計すべてを再計算します。これは20秒再計算時間になります。

20の合計のうち2つだけに影響する特定の入力

  • スタイル1の場合、これは20秒再計算時間になります。
  • スタイル2の場合、これは200秒再計算時間になります。

ここではスタイル1の方が常に高速です。最悪の場合、すべての合計で入力が使用されると、同等のパフォーマンスになります(すべての合計を再計算するため)。

より多くの合計があり、notの合計が特定の入力の影響を受けるため、再計算の必要はありません。パフォーマンスの向上が大きくなります。

勝者:スタイル1。


バグ

スタイル1では、すべての合計をその入力値にリンクする必要があります。 3つの値と3つの合計を使用しています。 10個の値と10個の合計に対してこれを行うにはどうしたらよいかを考えてください。問題はすぐに管理不可能な割合にエスカレートします。
あなたがしなければならない仕事が多いほど、どこかで間違いを犯す可能性が高くなります。特に、繰り返しはあるが常に少しだけ異なるコードでは、どこかにコピー/貼り付けエラーが発生したり、間違ったタイミングで間違ったものを書き込んだりする可能性があります。

ただし、スタイル2では、合計とその入力値の間のリンクは必要ありません。リンクを省略し、代わりに「すべて再計算する」アプローチをとります。これの良いところは、バグを見つけるのがずっと簡単になるということです。すべての再計算が機能するか、どれも機能しません。

勝者:スタイル2。

2
Flater

常に3番目のオプションを使用して、 オブザーバーパターン を実装できます。 @Flaterが述べたように、これには長所と短所があり、選択するときに考慮する必要があります。

0
Tom