私は小さなソフトウェア会社のインターンであり、典型的なうなり声の仕事をしています。実際の開発者が行っている多くのタスクは私の頭の上の問題ですが、私はようやく実際の「アクション」を見て、自分でコードを書くことができました。このタスクはおそらく私には少し難しすぎると認めますが、結局、コードを管理し、コードは機能しました。私のメンターがコードレビューをしているとき、彼は私に「男、この部分は醜い」と言っていました。 「なんで?何かおかしいの?」と言ったら彼は答えた、「いいえ、コードは機能しますが、クリーンなコードではありません」。クリーンなコードの概念は、私が以前に何度か遭遇したものであり、特に今では、プロの開発者をぶらぶらさせているためです。しかし、コードを「クリーン」にするのは正確には何ですか?つまり、基準は何ですか?
私は正式な数学で聞いたことがありますが、「美しい」証明は、理想的にはできるだけ明確で短いものであり、創造的な手法を使用するものです。多くの人々は、文学において、「良い」文学とは、感情を「感じる」ことができる程度に、楽にそしてエレガントに感情を表現できるものであることを知っています。しかし、コードを「感じる」ことはできず(少なくとも私はできません)、短いコードが必ずしも最適ではない(非常に非効率的である可能性がある)か、最も効率的な方法が常に優先される(非常に長く複雑になる可能性があるため)。それで、それは何ですか!コードを「クリーン」にする理由を教えてください。
私の見積もりでは、クリーンなコードには次の特性があります。
SOLIDのような原則やTDDのような慣行は、これらの目標を達成するために長い道のりを歩むことができます。また、ほとんどのソフトウェアのダイナミクスと同様に、それらは必ずしも相互に互換性があり、常にトレードオフがあります。
また、パフォーマンスの高いコードはクリーンなものとは正反対であるため、パフォーマンスについてはまったく触れていません。
ロバート・ハーヴェイは素晴らしい答えを持っていると思いますが、私が最も重要な部分であると私が信じるものを拡大したいと思います:
- 明確で理解しやすい
良いコードを書くには多くのことが必要です。しかし、後でreadingコードの読み取りと書き込みに多くの時間を費やしていることがわかります。明確で理解しやすいコードを書くことは、最終的にすべての時間を簡単かつ短時間で読むことができるため、クリーンなコードの概念にとって非常に重要です。
適切にフォーマットされている必要があります。標準を選び、一貫している。お好みの言語で他のスタイルガイドを見てください。あなたやあなたのチームに最適なものを選び、それを文書化して一貫性があるにします。
クラス名、メンバー名、変数名は、それらが何をしているかを表現し、説明するものでなければなりません。意味のない名前は避けてください。名前付けは、プログラミングを正しく行うのが最も難しいことの1つであり、多くの場合、作業しているドメインに固有のものになります。
短くしてください。コードを読んでいる男/女は、小説を読みたくありません。彼らは、機能のしくみや問題の解決方法を理解したいと考えています。 それらを明確にしてください。機能の小さな部分を表現方法に抽象化し、大きな部分がどのように機能するかについての短い説明的な「ストーリー」を構築します。
クリーンなコードを書くには多くのことが行われます。しかし、私の意見では、それを明確かつ理解しやすくすることは、あなたが実行できる単一の最も重要なことです。
ロバート・マーティンの本も読んでください。
私の答えはロバート・ハーベイの答えほど建設的ではありません。しかし、開発中に使用しているいくつかのオプションを追加できます。パフォーマンスの問題を考慮すると、実際に公開するときに回避または削除する必要があるものもあります。
他の答えに加えて、コードについて実際に感じる方法があるかもしれません。感じて、私は本能的にコードと対話することを意味します。
まず、コード自体の書式設定は、コードの読み取りに役立ついくつかの基本的な原則を使用することで、人々が読みやすく理解しやすくなります。 Gestalt Principlesは、人間が何かをより迅速かつ簡単に理解するのに役立ちます(データの視覚化に大きく適用されます)。コメントを揃えたり、スペースや空白行を適切な場所に配置したりするなど、これらの原則を使用することで、直感的なレベルでコードをより簡単に読み取ることができます。
私のコーディング規約とフォーマットの多くは、潜在意識レベルで最初に読みやすくすることに基づいています。
どちらがより読みやすく感じますか?
int x; //This is an x
string foo; //Foo here
MyObject baz; //Instance of MyObject
int x; //This is an x
string foo; //Foo here
MyObject baz; //Instance of MyObject
[〜#〜]編集[〜#〜]
長い宣言を持つことについてのマイケルのコメントへ。私たちの心は寛大なので、法律は厳密に従う必要はありません。
int x; //This is an x
string foo; //Foo here
MyObject baz; //Instance of MyObject
MyTypeWithSomeAwfullyLongName bar;
long UUID; //The Law can be broken and still help
Law of Proximityは、ほとんどの人が2番目のバージョンを好むことを意味します。データを整理するための列とテーブルがあるのも同じ理由です。
対称の法則に基づく別の例
function fooBarLongMethodName() {
return null;
}
function fooBarLongMethodName()
{
return null;
}
対称の法則によれば、心はオブジェクトを対称的で中心点の周りに形成するものとして知覚します。オブジェクトを対称的な偶数の部分に分割することは、知覚的には楽しいことです。
したがって、2番目の例で対称性を確認して、開き括弧と閉じ括弧の両方を一列に表示できることは、心にとってより喜ばしいことです。
これらの例は、直感的にコードを読みやすくします。しかし、利用するのに時間がかかる学習パターンもあります。これらは、過去の経験の法則に基づいています。
次に、特定のコードの意図を理解し、それが正しく使用されていないことを(特に、以前のコードを調査したり、多くのことを知ったりする必要なく)把握します。 この記事は、変数の名前付けについて説明しているので、変数が正しく使用されていないときに名前から確認できます。この命名と使用のパターンが習慣的になると、他のコードの多くを調査する必要なく、サイトごとにコードの問題を認識することができます。
最後に、これらはCode Smellsのより大きなアイデアにつながります。コードに現れる特定のパターンは、通常、コードのどこかに問題があることを示しているという考え。これは時々「この単体テストのコードは醜いです、なぜそれが必要なのですか?」という感情として現れます。そして、その質問への答えは、おそらく「ああ、あなたはすべてにシングルトンを使用している」でしょう。これは教えることも学ぶことも最も難しく、おそらく経験だけが伴うでしょう。
だから、これがなぜまたはどのように人々がコードを「美しい」、「良い」、または「醜い」と考えることができるかに関する他の答えを拡大するのに役立つことを願っています
クリーンなコードの重要性についての短い回答を追加します。それは、他の回答で接線的に引き起こされただけだからです。
「クリーンなコード」は重要です。なぜなら、製品または製品ラインの全寿命の間、数週間かけてそのモジュールを作成したことがあるかもしれませんが、コードベースで数年または数十年は「存続」するからです。
だから多分通常:
クリーンなコードを作成することで、5年以内にコードをレビューおよび更新する必要がある人々の作業を軽減します。そして、場合によっては、その人があなたになります!
(私はすでに「そのコードを書いただろうか?」と思っていて、バージョン管理システムをチェックインすることにより、それは実際には数年前の私でした...)
ここで、スタイル/レイアウト、つまりコードの外観に関するいくつかの回答に気づきました。 cleanであるコードとtidyであるコードの間には、区別すべき点があると思います。両方が理想的ですが、最初の方が重要です。
類推として、私は自分のキッチンを片付けることに決めるかもしれません(皿を積み重ねる、並べ替える、食器棚の瓶を並べ替えるなど)。コードと同じ-テキスト、フォーマット、空白、命名規則、小さいファイルへの分解などを調整できます。
それがあなたのコードがクリーンであることを意味するものはありません-そして私が後で料理する/私のコードをコンパイルするとき、私はまだバグを受け取るかもしれません(胃のバグ/セグメンテーション違反、私のアナロジーはうまく保持しています...)
もちろんバグを殺すこともできますが(沸騰水、石鹸/パッチ、ハック)、バグを完全に回避する方がはるかに優れています。つまり、コードをクリーンにすることです。したがって、ニーズに合わせてキッチンを設計し、十分なスペースを確保し、透明なワークトップを用意する/別の肉と野菜のまな板を使用するなど/うまく要素を考慮した設計 単一の責任の原則 、 [〜 #〜] kiss [〜#〜] 、 [〜#〜] yagni [〜#〜] など。アナロジーは崩れます。それは、できる前にキッチンを整頓する必要があるためですクック。一方、デザインがクリーンである限り、コンパイルして機能させるために整頓されたコードは必要ありません。
それは、平均的な開発者があなたのキッチン/コードをナビゲートしてすべてがどこにあるかを理解するのに少し時間がかかることを意味しますが、少なくともそれは可能ですが、サルモネラ菌と大腸菌のスワスを見るのは不可能ですキッチンの表面。シンクの下の食器棚に抗菌スプレーの明らかなボトルがいくつかあるので、彼らがそれを見つけることを期待しているので、彼らはそれがないことを信頼できます。解決する問題の標準的な方法でコードを設計しました。
今(純粋な意見):経験の浅い開発者(彼らの年功序列が何であるかは問題ではありません)は、汚れについてもっと心配すべきであるとき、整頓に気を取られます。
私(および他のほとんどの人)によると、それはコードの読みやすさに完全に依存します。
コードを読んで理解できれば、問題がないか、問題があります。 良いネーミングと他のものはもちろん重要です。しかし、残念なことに、可読性は主にデータ構造またはプログラミング言語における人の技術的理解に依存します。
簡単な例:私がC++でプログラムを書いたと想像してください。 C++ 11 標準に追加された新機能に魅了され、関数型プログラミングを使用してプログラムを記述しました。コンテナ全体のすべてのループと反復処理を、アキュムレート(リデュース、フォールド)、変換(マップ)、任意の(フィルター)、カリー化などに置き換えました。
今、このプログラムは概念と言語機能を知っている人にとってはクリーンで簡潔です。残念ながら、関数型プログラミングについて知らない、あるいは知らない人は苦労するでしょう。彼らは、コードが混乱したAPIを不必要に使用し、理解するのが複雑であると言います。これらのことはループを使用して行うことができます。ループはより明確でクリーンです。彼らはまだ彼らが立っている場所としては正しいですが、コードは実際には優れています。したがって、読みやすさと清潔さは個人に依存します。
これらすべてが実際に何を意味するのかを疑問に思っている場合は、アカデミックプログラミングからの変更のために、まず、意味のある変数と関数名を用意する必要があります。
次に、コードはわかりやすいように整理する必要があります。つまり、コードの分離を理解する必要があります(人々がMVCを好む理由を理解する)。モデルに機能的なものを配置する必要があり、ビューでは、フロントエンドとコントローラーがそれらをすべてプラグインするために使用されるものだけを持ちます。あなたのコードを読むようになると、これらの分離は実際に彼らが迅速な更新などのために欲しいビットに集中するのを助けます。
第3に、モジュールレベルで編成する必要もあります。給与や口座などの他のモジュールにチケットアルゴリズムなどの関数を含めないでください。モジュールとモジュールを簡単に削除できるようにモジュールを設計する必要もあります。システムは機能しなくても機能するはずです(つまり、モジュールを簡単にプラグインすることもできます)。
最後に、ヘルパー関数をすべてのモジュールから分離して、どこからでも呼び出せるようにすることもお勧めします。
また、さまざまなデザインパターンを見て、コードをより整理し、管理しやすくするために、それらを使用する方法を学ぶ必要があります。
S.O.L.I.Dについては、すでに読んでいるかどうかはわかりません。パターン。しかし、私はそのような質問にはもっと具体的な答えが必要だと思います。 Doom 3ソースコードレビュー をご覧ください。ゲーム開発に慣れていない場合でも、コードを理解できます。私の意見では、これはCleanコードの例です。