私の答えは、else が 2 つ以上ある場合、または case が 3 つ以上ある場合は switch です。しかし、コード内で if else を使用したり、大文字と小文字を切り替えたりするのは普通のことですよね?間違っている! 3 つ以上の分岐がある if else および switch ケースのほとんどは、ハードコーディングすべきではありません。
複雑な分岐はどこから来るのですか?
まず最初に議論したいのは、なぜ従来のコードには非常に多くの複雑な分岐が存在するのかということです。これらの複雑な分岐は、コードの最初のバージョンには存在しないことがよくあります。設計者がまだある程度の経験を持っていると仮定すると、将来拡張する必要がある領域を予測し、抽象インターフェイスを予約する必要があります。
しかし、コードが数回反復された後、特に要件の詳細を数回調整した後、複雑な分岐が表示されます。要件に対する詳細な調整は、多くの場合、UML には反映されず、コードに直接反映されます。たとえば、メッセージは当初、チャット メッセージとシステム メッセージの 2 つのカテゴリに分類されていましたが、これらは自然にメッセージ カテゴリの 2 つのサブカテゴリとして設計されました。しかし、ある日、要件が詳細に調整されることがあります。システム メッセージの一部は重要なので、そのタイトルを赤色で表示する必要があります。このとき、プログラマは、次のような変更を行うことがよくあります。
システム メッセージ クラスに重要な属性を追加します。
タイトルの色を制御するために、対応するレンダリング メソッドに重要な属性に関するブランチを追加します
プログラマはなぜそのような変更を行ったのでしょうか?おそらくそれは抽象的であるべきだと彼が気づいていなかったからでしょう。要件には「一部のシステム メッセージは重要である」と記載されているため、命令型プログラミング言語でより多くのトレーニングを受けたプログラマにとって、最初に思いつくのはフラグ ビットです。フラグ ビットは重要なものとそうでないものを区別できます。 。 重要。同氏は、この要件が「システム メッセージは 2 つのカテゴリ、重要なものと重要でないものに分類される」という別の方法で解釈される可能性があるとは予想していませんでした。このように解釈すると、システム メッセージは抽象化する必要があることがわかりました。
もちろん、プログラマは抽象化が可能であることを知っていても、何らかの理由で抽象化を行わないことを選択する可能性もあります。非常に一般的な状況は、プロジェクトの進行と引き換えにコードの品質を犠牲にすることをプログラマに強いるというものです。このフォームの変更を 10 回実行する場合、10 個のブランチを作成する方が速いですか。プロパティとブランチを追加する方がはるかに簡単です。それとも10個の抽象化ですか?違いは明らかです。
もちろん、if else が多すぎると、「switch case に変更したらどうだろう」と立ち上がる賢い人もいるでしょう。場合によっては、各ブランチが相互に排他的であると仮定すると、これによりコードの可読性が実際に向上します。しかし、スイッチケースの数が増えると、コードも読めなくなります。
複雑な分岐の欠点は何ですか
複雑な分岐の欠点は何ですか?例として、Baidu Hi Web バージョンの古いコードのセクションを取り上げます。
switch (json.result) {
case " ok":
switch (json.command) {
case "message":
case "systemmessage":
if (json.content.from == ""
&& json.content .content == "キック") {
/* 切断 */
} else if (json.command == "systemmessage"
|| json.content.type == "sysmsg" ) {
/* システム メッセージをレンダリングします */
} else {
/* チャット メッセージをレンダリングします */
}
break;
このコードは理解するのが難しくないので、簡単な質問をします。次の JSON ヒットを実行するブランチは次のとおりです:
"command": "message",
"content": {
"from" : "CatChen",
"content": "Hello!"
}
}
この JSON ヒットは簡単に正解できます。 /* チャット メッセージをレンダリング */ (チャット メッセージを表示) このブランチ。それで、どうやってこの判断を下したのか知りたいのですが?まず、case "ok": ブランチにヒットするかどうかを確認し、結果がヒットするかどうかを確認する必要があります。次に、case "message": ブランチにヒットするかどうかを確認し、結果もヒットするかどうかを確認する必要があります。 case "system message" を確認する必要はありません。 ; 次に、if の条件にもヒットせず、else if の条件にもヒットしないため、else 分岐にヒットします。
!(json.content.from == "" && json.content.content == "キック") && !(json.command == "systemmessage" || json.content.type == " sysmsg")
外側の 2 つのスイッチ ケースをオンにします。この分岐の条件は次のとおりです:
json.result == "ok" && (json.command == "message" || json.command == "systemmessage") && !(json.content.from == "" && json.content.content == "キック") && !(json.command == "systemmessage" || json.content.type == "sysmsg")
ここに繰り返しのロジックがあります。省略すると、次のようになります。
json.result == "ok" && json.command == "message" && !(json.content.from == "" && json.content.content == "キック") && ! (json.content.type == "sysmsg")
単純な 4 文字の else からこのような長い一連の論理演算式を導き出すのに、どれだけの労力を費やしたでしょうか?しかも、この表現はよく見ないと何を言っているのか分かりません。
ここで、複雑なブランチの読み取りと管理が困難になります。 if else を含む switch ケースに直面していると想像してください。合計 3 つのケースがあり、それぞれのケースに 3 つの else があり、各分岐とその前提条件がすべて含まれています。すべての祖先分岐は非 then-AND の結果です。
複雑な分岐を避ける方法
まず第一に、複雑な論理演算を避けることはできません。リファクタリングの結果は同等のロジックになるはずです。私たちにできることは、コードを読みやすく、管理しやすくすることだけです。したがって、複雑な論理演算を読みやすく管理しやすくする方法に焦点を当てる必要があります。
クラスまたはファクトリーへの抽象化
オブジェクト指向設計に慣れている人にとって、これは複雑な論理演算を分割し、それらを異なるクラスに分散することを意味するかもしれません:
switch (json.result) {
case "ok":
var Factory = commandFactories .getFactory(json.command);
var command = Factory.buildCommand(json);
break;
少なくともブランチが短くなり、コードが読みやすくなりました。このスイッチケースはステータスコード分岐のみを処理します。「ok」ステータスコードをどのように扱うかは他のクラスの問題です。 getFactory 内には、この命令がどのファクトリを選択するかの選択を作成することに重点を置いた一連の分岐がある場合があります。同時に、buildCommand には、この命令の構築方法を決定する他の簡単な分岐がある場合があります。
抽象をパターン マッチングに変換します
もう 1 つの方法は、この複雑な論理演算をパターン マッチングに変換することです:
"command": "message",
"content": { " from": "", "content": "kicked" }
}, function(json) { /* 切断 */ });
Network.listen([{
"result": " ok ",
"command": "message",
"content": { "type": "sysmsg" }
}, {
"result": "ok",
" command": "systemmessage"
}], function(json) { /* システム メッセージをレンダリング */ });
Network.listen({
"result": "ok",
" command": "message",
"content": { "from$ne": "", "type$ne": "sysmsg" }
}, function tion(json) { /* チャットメッセージをレンダリングする*/ });
Is it much clearer now? The first case is to be kicked offline and must match the specified from and content values. The second case is to display system messages. Since the system messages are slightly different in the two versions of the protocol, we need to capture two different JSONs, and any one that matches is considered a hit. The third situation is to display chat messages. Since system messages and kick-off instructions are special chat messages in the old version of the protocol, in order to be compatible with the old version of the protocol, these two situations must be excluded from the display of chat messages, so Just use the suffix "$ne" (meaning not equal) for matching.
Since the listen method is context-free, each listen independently declares what kind of JSON it matches, so there is no implicit logic. For example, to capture chat messages, you must explicitly exclude from == "" and type == "sysmsg", which does not need to be inferred from the context if else.
Using pattern matching, you can greatly improve the readability and maintainability of your code. Since what we want to capture is JSON, we use JSON to describe what each branch wants to capture, which is much clearer than a long logical operation expression. At the same time, every modification on this JSON is independent, and modifying one condition does not affect other conditions.
Finally, how to write such a pattern matching module is beyond the scope of this article.

JavaScriptの最新トレンドには、TypeScriptの台頭、最新のフレームワークとライブラリの人気、WebAssemblyの適用が含まれます。将来の見通しは、より強力なタイプシステム、サーバー側のJavaScriptの開発、人工知能と機械学習の拡大、およびIoTおよびEDGEコンピューティングの可能性をカバーしています。

JavaScriptは現代のWeb開発の基礎であり、その主な機能には、イベント駆動型のプログラミング、動的コンテンツ生成、非同期プログラミングが含まれます。 1)イベント駆動型プログラミングにより、Webページはユーザー操作に応じて動的に変更できます。 2)動的コンテンツ生成により、条件に応じてページコンテンツを調整できます。 3)非同期プログラミングにより、ユーザーインターフェイスがブロックされないようにします。 JavaScriptは、Webインタラクション、シングルページアプリケーション、サーバー側の開発で広く使用されており、ユーザーエクスペリエンスとクロスプラットフォーム開発の柔軟性を大幅に改善しています。

Pythonはデータサイエンスや機械学習により適していますが、JavaScriptはフロントエンドとフルスタックの開発により適しています。 1. Pythonは、簡潔な構文とリッチライブラリエコシステムで知られており、データ分析とWeb開発に適しています。 2。JavaScriptは、フロントエンド開発の中核です。 node.jsはサーバー側のプログラミングをサポートしており、フルスタック開発に適しています。

JavaScriptは、最新のブラウザにすでに組み込まれているため、インストールを必要としません。開始するには、テキストエディターとブラウザのみが必要です。 1)ブラウザ環境では、タグを介してHTMLファイルを埋め込んで実行します。 2)node.js環境では、node.jsをダウンロードしてインストールした後、コマンドラインを介してJavaScriptファイルを実行します。

Quartzタイマーを使用してタスクをスケジュールする場合、Quartzでタスク通知を事前に送信する方法、タスクの実行時間はCron式によって設定されます。今...

JavaScriptプログラミング、プロトタイプチェーンの関数パラメーターの理解と操作のJavaScriptのプロトタイプチェーンの関数のパラメーターを取得する方法は、一般的で重要なタスクです...

WeChatアプレットWeb-ViewでVue.jsを使用する動的スタイルの変位障害がvue.jsを使用している理由の分析...

複数のリンクの同時ゲットリクエストを作成し、結果を返すために順番に判断する方法は? TamperMonkeyスクリプトでは、複数のチェーンを使用する必要があることがよくあります...


ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

mPDF
mPDF は、UTF-8 でエンコードされた HTML から PDF ファイルを生成できる PHP ライブラリです。オリジナルの作者である Ian Back は、Web サイトから「オンザフライ」で PDF ファイルを出力し、さまざまな言語を処理するために mPDF を作成しました。 HTML2FPDF などのオリジナルのスクリプトよりも遅く、Unicode フォントを使用すると生成されるファイルが大きくなりますが、CSS スタイルなどをサポートし、多くの機能強化が施されています。 RTL (アラビア語とヘブライ語) や CJK (中国語、日本語、韓国語) を含むほぼすべての言語をサポートします。ネストされたブロックレベル要素 (P、DIV など) をサポートします。

SublimeText3 Linux 新バージョン
SublimeText3 Linux 最新バージョン

MantisBT
Mantis は、製品の欠陥追跡を支援するために設計された、導入が簡単な Web ベースの欠陥追跡ツールです。 PHP、MySQL、Web サーバーが必要です。デモおよびホスティング サービスをチェックしてください。

SublimeText3 中国語版
中国語版、とても使いやすい

Safe Exam Browser
Safe Exam Browser は、オンライン試験を安全に受験するための安全なブラウザ環境です。このソフトウェアは、あらゆるコンピュータを安全なワークステーションに変えます。あらゆるユーティリティへのアクセスを制御し、学生が無許可のリソースを使用するのを防ぎます。

ホットトピック



