私はメモを書くマスターではないので、昨日それを述べるために「熱中」を試みました。 しかし、「熱い追求」で調和のとれた順序で考えを構築することは不可能で簡単でした。
さらに、個人的な経験から、説明したアプローチは、一見非常に単純に思えますが、統計的にはそうではないことが判明しました。 「単純なもの、最も複雑なもの」というよく知られている言葉は、この場合に当てはまります。
このアプローチの「実用的な」アプリケーションは、無条件の反射になるまで、許容される「不正確さ」がその実装前でさえ顕著になるまで、努力と骨の折れる努力を必要とします。
したがって、同じ問題を「11回目」につまずいて、「11回目」にその同じ解決策を観察して、この「アプローチ」を書面で書くことは、それを「スキル」としてさらに統合するのに役立つと信じています。
これに関連して、このメモをここに公開することで、2番目の「ショットウサギ」が他の誰かがそのような状況を取り除くのに役立つと期待しています。
UPD3に感謝dimka_ben :「シングルスレッド」とは、特定の個人の思考の特性を指します。
そのため、2人のプログラマがいます。 普通の人、彼らは多くを知っている、尊厳をもって働く。
UPD1 : bachinのコメントからアドバイスに移動:
#define Nikita「ナンバーワンのプログラマー」
#define Denis "programmer number two"
どちらもUIを使用し、どちらもブラウザーのJavaScriptコードを記述します。 両者は互いのコードを理解し、深刻な問題なしに修正します。
しかし同時に、次の状況は何度も繰り返されます。デニスがニキータのコードを修正した場合、彼は初めて成功することはありません。 ニキータは、遅延や問題なく、常にデニスのコードをすぐに修正します。
ここで、デニスは単に「悪い」と思うでしょう。 しかし、実際には、これは完全に真実ではなく、単に「異なる」ものであり、さまざまなことに出くわしました。 そして今、彼らは「同じこと」をしています。
そして、ニキータが休暇に入った瞬間がやってきました。 当然のことながら、状況はすぐに悪化し、デニスはコードを編集する必要がありました。
彼はそれを3回作り直しました。 30行のコードでほぼ丸1日。 このコードは彼にとって馴染み深いものであり、数か月間はあまり変化しませんでした。
そして、それは修正でさえなく、わずかな改良であり、3つの可能なユースケースの1つの場合のメッセージが必要でした。
彼が初めて「メッセージ」を発表したとき、他の2つのユースケースが落ちたというバグがJiraに現れました。 彼はエラーを修正しましたが、Jiraでは2つのバグがすぐに現れ、もはや必要な「メッセージ」がなく、3番目のケースが機能していませんでした。 その結果、これが数回発生し、合計10個のバグが蓄積されました。
この状況はすでに身近なものだったため、いつ、どのような特定の条件でこれが繰り返されたかを思い出すことにしました。
これは常にほぼ同じ状況で起こり、ほとんど変わらないことがわかりました:
- UIはユーザーイベント(アクション)を処理します。ボタンが押されると、一般的にリストから選択されます-「インタラクティブ」。
- 通常、状況は非常に単純であり、5分で修正できると思われる場合は「基本」アルゴリズムとさえ言えます。
- 異なるユースケースを処理する際に、1つのメソッドまたは1つの関数が使用されます。 つまり 同じ「アルゴリズムへのエントリポイント」ですが、ユーザーアクションのシーケンスが異なります。 多くの場合、異なる画面からでも。
前回、デニスは3つのボタンの状況に身を置きました。
- レコードの「作成」画面で「保存」および「保存してさらに作成」、
- 編集画面で保存します。
3つのボタンすべてで、Nikitaは単一のハンドラーに設定されました。 3つのボタンはすべて1つのメソッドに「収束」しました。 同様の、しかしわずかに異なるアルゴリズムシーケンスを実行する3つの異なる組み合わせが判明しました。 このメソッドには、IFステータスを介して利用可能な他のシーケンスもいくつか含まれていました。 1つのメソッドのユースケースの総数が7だったため、Denisはさらに時間がかかりました。
Nikitaがなぜこのようなコードをエラーなしで記述し、デニスが後で修正できないのかを理解しようとすると、「外部球体のダイナミクス」のカテゴリからは構成されていないにもかかわらず、基本的な矛盾があるという結論に達しました。
ニキータは人生の半分の間、アプリケーションを実行する前にコンパイルが必要な厳密に型指定されたプログラミング言語を使用していました。
デニスは何よりもタイピングの弱いスクリプト言語で働いていました。彼の生涯はJavaScriptを主言語として使っていたと言えます。
Nikitaは、入力変数の異なるセットを使用して、メソッドの再定義のレベルでOOPを理解しました。 デニスは、プロトタイプに基づいた継承を問題なく実装しました。
Nikitaはマルチスレッドアプリケーションを使用していました。 Denisは、Node.JSの一部としてマルチスレッドの実装を処理しようとしていました。
おもしろい写真になりました:
- デバッグ中のNikitaは、このコードが異なるユースケースで機能すると考えるかもしれません。
- デニスは、バグの束を受け取った後にのみいくつかのユースケースがあることを思い出します。
つまり、デニスは、複数の異なるユーザーの行動が同じアルゴリズムに収束する状況を「即座に」認識しません。
違いのこの「出発点」を理解したので、私はデニスのコードをより詳しく見ることにしました。突然、彼は「一般的な」方法を使用せず、「共有する」コードを書きません。
ニキータとは異なり、彼は異なる方法で「共有コード」を書くことが判明しました。 もちろん、彼は繰り返されるものを別々のメソッドに取りますが、すでに「ユースケースへのユーザーエントリポイント」と呼んでいるものは、常に1つの別のメソッドで実装されています。
それから私は彼に尋ねました:「なぜあなたはこれをしているのですか?」
答えは私に衝撃を与えました:「だから私はここで何か他のものがうまくいくことを決して忘れない ここでは他に説明はありません。」
つまり、1つのメソッドのフレームワーク内に2つ目の「入力」ユースケースが出現する状況に直面するとすぐに、コードを2つに分割し、関連する別のメソッドの「繰り返し」部分を削除しました。 そして通常、彼はアルゴリズムについて考え、彼が書くことを分析しながらこれをしました。
したがって、「デバッガ」には、ユーザーからの一連のアクションを処理する唯一の実装である「デバッガ」が存在することが判明しました。
そして、彼は何かを忘れたり見逃したりする可能性があるという事実に決して直面しませんでした。 単に忘れることはありませんでした。
その瞬間、彼がNikitaの「共有コード」を修正し始めたとき、彼の「シングルスレッド」アプローチは壊れていました。
そして、ニキータがそのような状況にあったかどうか確かめることにしました。 奇妙なことに、それは判明しましたが、そうです。 彼は、対応するバグが現れた直後にそれらに対処しました。 つまり、習慣のおかげで、彼はいくつかのユースケースがここに収束する可能性があることを単に覚えていましたが、間違いも免れませんでした。
次に、Denisの「バグ」を分析しましたが、彼のコードにはそのようなバグはまったくないことがわかりました。 変更が必要になるまで、すでに機能しているものに戻ることはありません。 いいえ、彼にもエラーがありましたが、異なるユースケースへのエントリポイントが同じメソッドであったという事実とは関係ありませんでした。 彼はそのコードを持っていませんでした。
同様の状況で、デニスはニキータ自身のアプローチを修正するのにニキータ自身よりもはるかに多くの時間を費やしていることが判明しましたが、デニスは自分のコードにはそのような問題はまったくありません。
最後の疑問が残った-なぜニキータもそのような状況に陥るのか。 これを理解しようとして、私は言語自体について考えました。 JavaScriptはシングルスレッドです。 そして、デニスは常に1つのスレッドと「デバッグ」で、「1つのスレッド」でのみ考えます。 ニキータは多くの状況を一度に考えますが、「ユースケースのミキシング」の際に彼でさえミスをすることがあります。
デニスは、彼のこの機能を知っており、デバッグするものがないことを確認しようとします。
Nikitaはコードを書くだけです。 彼には何も考えないようです。
このアプローチを何と呼び、どこから来たのかわかりません。 これはKISSの原則の1つかもしれません。多分それは優雅な劣化によるものかもしれませんし、それはUnixの方法の一部かもしれません(1つのアクションですが、「良い」)。
ところで、ウィキには、 en.wikipedia.org /wiki/ Separation_of_concernsに似たものがありますが、これが正確かどうかはわかりません。
しかし、いずれにせよ、「ナンバー2」は一度に1つのものしか壊せないのが好きです。「ナンバー1」がまったく壊れて、一度に壊れるのが嫌いです。
UPD2 : zloddeyに感謝、多分それはSRP