検索
ホームページウェブフロントエンドjsチュートリアルif elseからjavascriptで大文字と小文字をabstraction_javascriptに切り替えるスキル

私の答えは、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 ヒットを実行するブランチは次のとおりです:


{
"result": "ok",
"command": "message",
"content": {
"from" : "CatChen",
"content": "Hello!"
}
}


この JSON ヒットは簡単に正解できます。 /* チャット メッセージをレンダリング */ (チャット メッセージを表示) このブランチ。それで、どうやってこの判断を下したのか知りたいのですが?まず、case "ok": ブランチにヒットするかどうかを確認し、結果がヒットするかどうかを確認する必要があります。次に、case "message": ブランチにヒットするかどうかを確認し、結果もヒットするかどうかを確認する必要があります。 case "system message" を確認する必要はありません。 ; 次に、if の条件にもヒットせず、else if の条件にもヒットしないため、else 分岐にヒットします。
問題がわかりましたか?なぜ他の部分を見て、この JSON がこのブランチにヒットすると言えないのでしょうか? else 自体には条件が含まれていないため、条件を意味するだけです。それぞれの else の条件は、その前の if と else if の否定とその後の AND 演算の結果です。言い換えれば、この 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 には、この命令の構築方法を決定する他の簡単な分岐がある場合があります。
この利点は、ブランチ間の入れ子関係が解消され、各ブランチが独自のコンテキスト内でのみ正しい状態を維持する必要があることです。たとえば、getFactory は名前付き関数になりました。そのため、この関数内の分岐は、getFactory が実際に呼び出されるコンテキストに注意を払うことなく、getFactory という名前によって暗示されるコントラクトを実装するだけで済みます。
抽象をパターン マッチングに変換します
もう 1 つの方法は、この複雑な論理演算をパターン マッチングに変換することです:


Network.listen({
"result": "ok",
"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.
声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
JavaScriptの進化:現在の傾向と将来の見通しJavaScriptの進化:現在の傾向と将来の見通しApr 10, 2025 am 09:33 AM

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

javascriptの分解:それが何をするのか、なぜそれが重要なのかjavascriptの分解:それが何をするのか、なぜそれが重要なのかApr 09, 2025 am 12:07 AM

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

pythonまたはjavascriptの方がいいですか?pythonまたはjavascriptの方がいいですか?Apr 06, 2025 am 12:14 AM

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

JavaScriptをインストールするにはどうすればよいですか?JavaScriptをインストールするにはどうすればよいですか?Apr 05, 2025 am 12:16 AM

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

クォーツでタスクが開始される前に通知を送信する方法は?クォーツでタスクが開始される前に通知を送信する方法は?Apr 04, 2025 pm 09:24 PM

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

JavaScriptでは、コンストラクターのプロトタイプチェーンで関数のパラメーターを取得する方法は?JavaScriptでは、コンストラクターのプロトタイプチェーンで関数のパラメーターを取得する方法は?Apr 04, 2025 pm 09:21 PM

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

WeChat MiniプログラムWebViewでVUE.JSダイナミックスタイルの変位が失敗した理由は何ですか?WeChat MiniプログラムWebViewでVUE.JSダイナミックスタイルの変位が失敗した理由は何ですか?Apr 04, 2025 pm 09:18 PM

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

TamperMonkeyで複数のリンクの同時GETリクエストを実装し、順番に戻る結果を決定する方法は?TamperMonkeyで複数のリンクの同時GETリクエストを実装し、順番に戻る結果を決定する方法は?Apr 04, 2025 pm 09:15 PM

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

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

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

ホットツール

mPDF

mPDF

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

SublimeText3 Linux 新バージョン

SublimeText3 Linux 新バージョン

SublimeText3 Linux 最新バージョン

MantisBT

MantisBT

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

SublimeText3 中国語版

SublimeText3 中国語版

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

Safe Exam Browser

Safe Exam Browser

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