コードの読みやすさについて語る記事

意見表明

上記のコードでは、左側の実装が優れていると思いますか、それとも右側の実装が優れていると思いますか? あなたのコードは左派ですか、それとも右派ですか? まず最初に言っておきますが、この例はあまり良くありませんが、非常に良い例だと思います。なぜなら、この例は極端ではないからです。しかし、このような例について詳しく説明すると、より明確になる可能性があります。私の見解では、これは、この記事で続く視点でもあり、右側にある傾向があります。もちろん、この例では、左側のコードは非常に簡潔であるのに対し、右側のコードは少し不必要に複雑であると思われるかもしれません。この視点の背後にある考え方は次のとおりです。

a. 右側のコードはよりスケーラブルで、責任の境界が明確で、層が豊富です。

b. 右側のコードはより一般的であり、人間の言語に近いものです

c. 右側のコードの方が、メソッドの意図をより早く知ることができます (これについてはここで説明します。サンプルが単純なので、左側のコードもメソッドの意図をより早く知ることができると思われるかもしれません。お話ししましょう)ここでそれについて説明します 1. メソッドの実装がもう少し複雑な場合、左側は少し理解するのが難しくなります; 2. 一見すると、右側の意図はより直接的ですが、ここでの例はいくつかあるかもしれません。 (秒) ざっと見ただけでは意見の相違もあるかもしれませんが、この命題自体はまだオープンエンドだと思いますし、クローズドエンドの質問であれば、関連する書籍でどのようにコード化するか明確に定義されているはずです。誰もが弁証法的に読み続け、疑問を分析できることを願っています。

読みやすさの理解

読みやすさと理解について話す前に、まずリファクタリングについて話しましょう。私たちはリファクタリングを頻繁に行いますが、最短で 1 か月、最長で 1 年かかることもあります。私たちは主に次の目標のためにリファクタリングを行います: 1. コードをより速く実行できるようにする。 2. コードをよりクリーンで合理化する; 3. いくつかのメソッドを抽象化し、いくつかのパターンを使用して、コードをより再利用可能でスケーラブルにする; 4. コードをよりスムーズに読めるようにする; たとえば、この時点で、皆さんに別の質問をしたいと思います。上記の目標の中で、最も優先度が高いのはどれだと思いますか?

個人的に言えば、過去にリファクタリングを行ったときは、パフォーマンスを考慮してシナリオが少なく、簡素化のためにリファクタリングをしませんでした。簡素化は再構築プロセス中に付随的に与えられたものであり、むしろモデルの調整について メソッドの抽象化と析出、呼び出しレベルの整理、DAO層、モデル層、マネージャー層、ビズ層、サービス層といったおなじみの階層構造 なお、純粋なリファクタリングは基本的にはありませんより良いコードを作成するため。

現時点では、ビジネス技術チームの開発の観点から見ると、読みやすさがコードの最優先要件です。

可読性とは、コードがその意図を伝える能力のことです。これは、コードが意図したとおりに動作すると仮定すると、そのコードが何をしているのかを理解するのが非常に簡単であることを意味します。

[可読性とは、保守者がコードの意図をよく理解でき、実際のコード実行ロジックは保守者が直感的に感じた意図に従って実際に実行されることを意味します]

かつて、コンパイラがそれほど完成度もインテリジェントでもなかったときも、どのようなコード、どのような構文、呼び出しを使用すればコードの実行速度を最大化できるかを考えていました。当時は、それを学ぶのが本当に楽しかったです。このような小さな改善は非常に「プロフェッショナル」であると感じますが、そのようなプロ意識の発展により、基本的にコンパイラは現在私たちよりも優れた処理を行うことができるため、私たちはマシンとどのように付き合っていくかに重点を置いています。コンパイラに完全に引き継がれていますが、現時点でさらに行う必要があるのは、コードの背後にあるリーダー (あなたまたは他の誰かかもしれません) と通信する方法です。

現在、開発要件を繰り返すとき、私たちが費やす時間のほとんどはコードを書くことではなく、コードとそのコードの上流および下流のコード ロジックを理解することに費やされます。それから無意識のうちに著者をチェックしに行きます〜

私たちがよく話題にする保守性という言葉は、変更を加える際に上流と下流、または関連するコードをどれだけ読む必要があるかに反映されている可能性があります。対象範囲が広ければ広いほど、間違いを犯したり、潜在的な可能性を見逃したりする可能性が高くなります。変更される可能性が高ければ高いほど保守性は低くなりますが、別の観点から見ると、変更を加えるとコードの可読性が低下し、時間がかかるほど、関数またはモジュールのこの部分の保守性が低くなります。

したがって、可読性はメンテナンスと反復の効率と安定性に関連する重要な要素です。

可読性を向上させる方法

視点を示す際に、可読性のメリットとして、人に近い言葉(大衆的表現)、手法の意図(明確な意図)、階層性(階層性)の3つの側面をすでに述べました。

1. 流行の表現

最も一般的な表現は、「コードを書く前に疑似コードを書く習慣があった」というものだと思います。疑似コードは、コードの形式で非常に共同作業者に優しい表現です。次の例を見てください (既存のプロジェクト コードから見つかりました) )。

この例から、最も一般的な表現はどれですか? これはコメント 1 ~ 9 であり、その後に各コメントの下にメソッドの名前が続きます (中国語から英語への翻訳はそれほど本物ではない可能性があるため)。

私たちのコードで最もユーザーフレンドリーなものはコメントです (ただし、コメントの有効期限が切れていると、事故が発生することがあります)。コメントの下にある対応するメソッド名は、必ずしも人々にとってそれほどフレンドリーではない可能性があります。理由の 1 つは、私たちがそうしていないことです。英語に翻訳することは、翻訳能力が限られている場合にピンイン + 英語を混ぜることがあるため、実際には簡単ではありません。メソッド名を定義するときに、行われた内容が中途半端にしか説明されていないか、非常に抽象的で、何かを得たかのように見え、見たようで見ていないようでした。

ポピュラーな表現の前提はレイヤー、抽象化、カプセル化です。これについて詳しく話しましょう。次の例を体験できます。

このコードは人気があると考えられていますか? おそらく、各行の意味は理解できるかもしれませんが、全体として、これが何を決定するのかはわかりません(もちろん、私は巧妙に注釈を付けました。実際、この注釈の英語名は、The best Definition of です)この if ステートメントの条件が抽象化されるメソッド)

ここでの一般的な表現の定義には 2 つの側面が含まれます: 1. 後でコードを読む人が理解できるほど親しみやすく、直感的でスムーズに理解できること; 2. このメソッドの動作を説明するのに十分な正確さ。規則、変数/メソッド/クラスの合理的な命名、明確に定義されたファイル名、標準化された形式、スペースと空行の使用、注釈などはすべて、後で他の人がコードを簡単に読むのに役立ちます。

2. 自分の意図を明確にする

明確な意図は本質的に現実と期待の一致です: 1. 現実: コード作成者はこのメソッドの特定の実装を書いています; 2. 期待: コードを読む人がこのメソッドを見たときに頭の中で期待しているという認識; どのようにこの 2 つは一致しますか? 一致する場合、このコードには明確な意図があり、副作用はないと定義します。

副作用とは副作用であり、明確に定義されたメソッドの下での引き込み行為があるかどうかという意味でも理解できますが、このようなことは実際にコード内で多くコミットされており、誰もがコミットすべきではないと考えているものですが、多かれ少なかれ、文章を書くときにそうする人がいますが、私は無意識のうちにそれに気づきませんでした。次の例を見てください。非常に典型的なものです。

キャッシュと tair をより頻繁に使用するため、tair の従来の更新戦略は、読み取りミスの後にソースをトレースした後に書き戻すことであり、その後、名前によってそれらの 90% 以上が getXXXFromCache であることが保証されますが、更新は内部で行われます。ただし、この問題に戻りますが、チーム全体で合意に達した場合、その合意が合意になった場合、それは副作用の範囲に含まれない可能性がありますが、ここでは例を示しているだけです。

上記のカテゴリは、メソッド名がメソッドの内部実装を明確に表現していないカテゴリに属しますが、実際には関数型プログラミングのカテゴリに属する​​カテゴリがあります(FP 自体は別の分野なので、ここで説明します) FP では、入力パラメータは変更できず、複数回の実行後の結果は一貫していなければならないという厳しい要件と仕様があります (フレームワーク実装におけるコンテキスト転送に基づくプロセス指向プログラミング手法)はこのリストには含まれていません)、次の例を見てください。

コードは比較的長いため、他のコードを削除しました。入力パラメータのこの変更は比較的目に見えませんが、本質的に FP の原則に違反しています。同時に、後で反復する人はこのロジックを知りません。ここで変更されたリクエストのメンバーは後続のプロセスで重要な処理オブジェクトになる可能性があるため、非常にトラブルに陥りやすいですが、後の反復の生徒がこのメンバー変数がインターフェイスの入力パラメーターと一致している必要があると期待している場合、彼は次のようになります。状況が私の想像を少し超えていることに気付きました。この時点では、私はアーサスするかデバッグするかのどちらかです。

副作用に関する最大の問題は、間違いの慣性よりも大きいです。なぜなら、後続の要件の反復を行う際、私たちは皆、前世代の作成者の設計、意図、構造を信じているからです。現時点では、意図の伝達ミスが例外を引き起こし、さらには同時に、この抜け穴は慣性思考に隠れて存在するため、この問題のトラブルシューティングは依然として非常に困難です。

3. 階層構造

ここで説明する階層構造は、複雑なメソッド内のコード階層であり、以前に説明したアプリケーション層の階層構造ではありません。例から始めましょう:

このメソッドは freeTieClip に内部的に実装されており、2 つのカプセル化されたメソッド、つまり make_item と add_item を呼び出します。このメソッドの前に、ショッピング カートのアイテムの走査があります。実際、array_index と for ループは、後の 2 つのメソッドと同じメソッドに属すべきではありません最初の 2 つは直接パススルー呼び出し (. を介した呼び出しとして理解できます) であり、後者は関数呼び出しに属するため、抽象化のレベルは次のようになります。

この freeTieClip メソッドの階層構造最適化メソッドも非常に単純で、最初の 2 つのパススルー呼び出しのメソッドをカプセル化します。

次に、remove_item_by_name メソッドを追加して、名前を指定してショッピング カートからアイテムを削除する場合、一般的なロジックは次のとおりです。

では、このメソッドはどの階層構造にあるべきでしょうか? 考えられる結果は次のとおりです。

メソッド名のビジネス セマンティクスからは、上の新しい層も最上位の層も適切ではありません。直観的に言えば、base に属する下の新しい層が実装されるため、最下位の層の方が適しているはずです。最終的な階層は次のとおりです。

例で説明した階層化手法は、実際の参考として使用できます。それほど厳密に行う必要はありません。ただし、この考え方は参考として非常に役立ちます。少なくとも、曖昧で定義が難しい可読性を提供します。 . 設計と実装は方法論を提供します。

導入時の提案

上記はいくつかの定義と階層化された方法を示していますが、その一部は理解に依存し、他の部分は練習に依存してゆっくりと理解して熟練する必要があります。可読性を向上させ、可読性を改善する必要があるコードを特定するために、ここでは純粋に実際の操作を目的としたいくつかのヒントを紹介します。

1.5つのライン

a. 直接的に説明すると、メソッドの実装は 5 行を超えてはならず、これは非常に極端な要件ですが、この仕様に従う代わりに、この標準を使用すると、最適化できる潜在的なコードを特定でき、悪臭を嗅ぐのに役立ちます。

2.コールまたはパスのどちらか

a. これは上記の階層化に似ていますが、階層化ほど論理的に厳密ではありません。これは単に最終的な識別可能なロジックです。Java では、基本的な操作として . シンボル呼び出しを使用し、特定のメソッドを呼び出すことができます。次の図に示すように、同じメソッド内で 2 つのメソッドを呼び出すことは避けてください。

3.純粋な条件を使用する

a. 純粋な条件とは、条件の操作に追加の影響がないことを意味します。これは fp の要件と一致します。この条件判定を複数回実行すると、1. 結果はべき等であり、2. 他の暗黙的な動作はありません。純粋な判断、副作用なし。

4.最初だけなら

a. メソッドに if ステートメントがある場合は、メソッドの先頭に置くようにします。メソッド本体の途中にある場合は、if ステートメント全体をメソッドに分割する必要があります。

5.コメントを避ける

a. コメント (メソッド宣言以外のコメント) を避けるのは理想的な要件ですが、これらのヒントから導き出されるロジックは次のとおりです: 1. 優れたコードは、自身の役割を非常に直接的に示すことができます; 2. コメントは時間に敏感であり、コメントは時間とともに変化します。コードの反復によりメンテナンスが失われ、古くなり、不正確になります; 3. 誤解を招く不正確なコメントは、その後に比較的大きな影響を及ぼします。

b. 同様に、アノテーションが付けられたコード ブロックを再検査して、最適化の余地があるかどうかを確認できます。

コード生成を組み合わせる

読みやすさのためのリファクタリングは、実際には、メソッドの一貫性を高め、階層をより合理的なものにするためにコード構造を再編成することです。現在、業界で最も一般的に使用されているコード生成ツールは github copilot です。基礎となるコード生成ツールは GPT3 に基づいています。実際の強みは、いわゆる基本的なメソッド生成のカテゴリーにあります。ビジネス コードの生成には、ビジネスとビジネスの理解が必要であるため、ビジネス メソッドの生成は、直接使用するよりも難しいはずです。これは、現在のさまざまな種類のコパイロットを考慮しています。トレーニング データ セット たとえば、これを達成することは基本的に不可能です。

上記の階層構造の分割から、実際には、Copilot は上記の「ショッピング カートの基本操作層」と「商品の基本操作層」のメソッドに対応するコードを比較的うまく生成でき、より優れた機能を備えているはずです。コード受け入れ率、およびこのタイプの方法は、単一のテストを通じて実装の正確性を確認するのが比較的簡単です。

上記を踏まえると、次のビジネスチームのコーディング方法は、次のような変化をもたらすだろうと個人的に感じています。 ビジネステクノロジーの学生は、主にメソッドの定義(メソッドの責任を含む)を含む、ビジネスセマンティクスから一般的なプログラミング言語セマンティクスへの変換を実装します。実装される関数の定義)、メソッドの定義(主にビジネス ルールと要件に基づく)、メソッド呼び出しの失敗または例外処理など、その後、特定のサブメソッドの内部実装を実行できます。さまざまなコード生成ツールを通じて出力され、対応する単一のテストがツールを通じて生成されます。おそらく、さらに一歩進んで、ビジネス製品がコード実行プロセスを定義する場合、技術系の学生はプログラミングを行う必要はなく、デバッグのみを行う必要があります。生成されたコードが正しいかどうかを確認する作業。

結論

プログラマとして、私たちは記述するコードに対していくつかの要件があります: 1. コードは正常に実行でき、ビジネス要件を満たすことができる; 2. 記述するコードの構造は、現在のアプリケーションまたは現在のアーキテクチャの仕様と仕様に準拠している必要があります。パッケージ仕様、ネーミング仕様、フォーマット仕様など、ネストは 3 レベルを超えてはならず、1 つのメソッドは 10 行を超えてはなりません。 3. 作成するコードは比較的可読性が高く、他のプログラマーがコードを非常に簡単に読み取ることができます (このコードは、これは、コードを 1 行ずつ読んで、コードで表現されているビジネス ロジックを推測するという意味ではありませんが、コードのロジックと設計意図を理解するのは非常に直感的です)。

可読性の高いコードを書くことはスキルですが、それは雰囲気や土壌に大きく左右されます。本質的には誰でも可読性の高いコードを書くことができるはずです。それは、積極的にそれに気づいていないためである場合もあれば、惰性で「」に従っている場合もあります。ここで私が個人的にお勧めするのは、初めてコードを実装し、ビジネス要件を満たすためのセルフテストを完了してから、戻ってすぐに独自のコードを読みやすく再構築することです。このコストは比較的高くなります。再構築の範囲を上流と下流の関連コードの一定の範囲に少し拡張できれば、それはより参考になると思いますが、上記の表現に基づいて、皆様からの提案を歓迎します。

著者 | 江丹陽

元のリンク

この記事は Alibaba Cloud のオリジナル コンテンツであり、許可なく複製することはできません。

OpenAI が ChatGPT Voice Vite 5 をすべてのユーザーに無料で公開、正式にリリース オペレーターの魔法の操作: バックグラウンドでネットワークを切断、ブロードバンド アカウントを非アクティブ化、ユーザーに光モデムの変更を強制 Microsoft オープン ソースの ターミナル チャット プログラマーが ETC 残高を改ざんし、年間 260 万元以上を横領 Redis の父が使用する Pure C 言語コードは、Telegram Bot フレームワークを実装しています あなたがオープンソース プロジェクトのメンテナである場合、この種の返答にどこまで耐えることができますか? Microsoft Copilot Web AI は 12 月 1 日に正式にリリースされ、中国の OpenAI をサポートします 元 CEO 兼社長の Sam Altman 氏と Greg Brockman 氏が Microsoft に加わりました Broadcom は VMware の買収に成功したと発表しました
{{名前}}
{{名前}}

Supongo que te gusta

Origin my.oschina.net/yunqi/blog/10150848
Recomendado
Clasificación