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);
};
どのスタイルを使うべきですか?
利点と欠点は状況に応じて異なるため、これに対する明確な答えはありません。頭に浮かぶ要因をいくつか挙げます。
以下の調査結果を要約すると、スタイル2は労力が少なくて済み、一般的にバグが少ないため、非常に優れています。ただし、スタイル1は、開発の労力よりもランタイムパフォーマンスを重視する場合に優れています(また、2つの間に意味のあるパフォーマンスの違いがあります)。
純粋な努力
5つの値があり、32の異なる合計を計算するとします(ナプキンの裏側、つまり、5つの値で実行できる個別の加算の数)。 5つの値はそれぞれ16の合計で使用され、他の16の合計では無視されます。
UpdateThisParticularSum()
呼び出しを記述する必要があります。つまり、合計で80チェックです。 32個の異なるUpdateThisDistinctSum()
メソッドがありますが、それらを合計80回呼び出す必要があります。UpdateEverythingAtOnce()
メソッドは32個の値を再計算する必要があります。この例では、値間の関係の量(それらを追加する方法または追加しない方法)が最大化されているため、すべてを手動で処理する必要があり、面倒になります。
32個の値があり、4つの異なる合計を計算するとします(=値間の関係の量を最小化します)。合計で各値が使用される頻度は不明ですが、均等な分布で各値が合計2回使用されると仮定すると、すべての合計で合計64個の使用値になります。
UpdateThisParticularSum()
呼び出しを作成する必要があります。つまり、合計で64チェックになります。 4つの異なるUpdateThisDistinctSum()
メソッドがありますが、それらを合計64回呼び出す必要があります。UpdateEverythingAtOnce()
メソッドは4つの値を再計算する必要があります。どちらの場合も、スタイル1は常に行数が多くなります。与えられた量の値から計算する合計が多いほど、行数の増加が過剰になります。
勝者:スタイル2。
パフォーマンス
加算は、パフォーマンスコストを無視できる単純な計算です。 10秒かかる非常に複雑なものを計算しているとしましょう。私は引き続きそれらを「合計」と呼んで、私の回答との整合性を保ちますが、それらは任意の複雑な数学的タスクであると想定できます。
3つの値と3つの合計(例)
32の値と4つの合計(私の例2)
5つの値と32の合計(私の例1)
20の合計のうち2つだけに影響する特定の入力
ここではスタイル1の方が常に高速です。最悪の場合、すべての合計で入力が使用されると、同等のパフォーマンスになります(すべての合計を再計算するため)。
より多くの合計があり、notの合計が特定の入力の影響を受けるため、再計算の必要はありません。パフォーマンスの向上が大きくなります。
勝者:スタイル1。
バグ
スタイル1では、すべての合計をその入力値にリンクする必要があります。 3つの値と3つの合計を使用しています。 10個の値と10個の合計に対してこれを行うにはどうしたらよいかを考えてください。問題はすぐに管理不可能な割合にエスカレートします。
あなたがしなければならない仕事が多いほど、どこかで間違いを犯す可能性が高くなります。特に、繰り返しはあるが常に少しだけ異なるコードでは、どこかにコピー/貼り付けエラーが発生したり、間違ったタイミングで間違ったものを書き込んだりする可能性があります。
ただし、スタイル2では、合計とその入力値の間のリンクは必要ありません。リンクを省略し、代わりに「すべて再計算する」アプローチをとります。これの良いところは、バグを見つけるのがずっと簡単になるということです。すべての再計算が機能するか、どれも機能しません。
勝者:スタイル2。
常に3番目のオプションを使用して、 オブザーバーパターン を実装できます。 @Flaterが述べたように、これには長所と短所があり、選択するときに考慮する必要があります。