においがするのは、編集または改善できる場合が多いためです。
これらの臭いのほとんどは、何かが間違っている可能性があることを示しているだけです。したがって、それ自体を修正する必要はありません…(ただし、調べておく必要があります)。
以前のコードの匂い (パート i - XXIX) はすべてここで見つけることができます。
続けましょう...
コメントはコードの匂いです。ゲッターは別のコード臭です。何だと思う?
TL;DR: ゲッターを使用しないでください。ゲッターにコメントしないでください
数十年前、私たちはすべての方法についてコメントしていました。些細なことでも。
コメントは、重要な設計上の決定のみを説明する必要があります。
pragma solidity >=0.5.0 <0.9.0; contract Property { int private price; function getPrice() public view returns(int) { /* returns the Price */ return price; } }
pragma solidity >=0.5.0 <0.9.0; contract Property { int private _price; function price() public view returns(int) { return _price; } }
メソッドがゲッターであり、コメントがあるかどうかを検出できます。
関数にはコメントが必要です。これは誤ってゲッターであり、コメントは設計上の決定に関連しています
ゲッターにコメントしないでください。
それらは真の価値をもたらさず、コードを肥大化させます。
UnsplashのReimond de Zuñigaによる写真
ほとんどのコメントを避けるために、コードは非常に表現力豊かでなければなりません。いくつかの例外がありますが、間違っていることが証明されるまで、コメントは「表現の失敗」と見なすべきです。
ロバート・マーティン
Util クラスは、プロトコルを収集するのに最適です。
TL;DR: クラスに偶発的なプロトコルを追加しないでください
私たちは、見つけた最初のクラスにプロトコルを入れる傾向があります。
問題ない。
リファクタリングするだけです。
public class MyHelperClass { public void print() { } public void format() { } // ... many methods more // ... even more methods public void persist() { } public void solveFermiParadox() { } }
public class Printer { public void print() { } } public class DateToStringFormatter { public void format() { } } public class Database { public void persist() { } } public class RadioTelescope { public void solveFermiParadox() { } }
ほとんどのリンターはメソッドをカウントして警告します。
クラスとプロトコルを分割することは、小さくて再利用可能なオブジェクトを優先するための良い方法です。
UnsplashのMarcin Simonidesによる写真
メンテナンスによって悪化させられないほど大きく、ねじれ、複雑なコードはありません。
ジェラルド・M・ワインバーグ
私たちは未来の自分のために借金をします。返済時期です。
TL;DR: コードに TODO を残さないでください。それらを修正してください!
コード内で TODO に遭遇します。それらを数えます。
私たちはめったにそれに対処しません。
私たちは技術的負債を負い始めました。
次に、借金+利息を支払います。
数か月後、元の借金よりも多くの利息を支払います。
public class Door { private Boolean isOpened; public Door(boolean isOpened) { this.isOpened = isOpened; } public void openDoor() { this.isOpened = true; } public void closeDoor() { // TODO: Implement close door and cover it } }
public class Door { private Boolean isOpened; public Door(boolean isOpened) { this.isOpened = isOpened; } public void openDoor() { this.isOpened = true; } public void closeDoor() { this.isOpened = false; } }
TODO を数えることができます。
TODO を数えることができます。
ほとんどのリンターはそれを行います。
それらを減らす政策が必要です。
TDD を使用している場合は、欠落しているコードをすぐに記述します。
このコンテキストでは、TODO は、Depth First 開発を行って訪問するオープン パスを記憶する場合にのみ有効です。
UnsplashのEden Constantinoによる写真
プロジェクトの最初の 90% を完了したら、残りの 90% を完了する必要があります。
マイケル・アブラッシュ
私たちのコードはより堅牢で読みやすくなっています。しかし、敷物の下に NULL を隠します。
TL;DR: Null と undefined は避けてください。それらを回避する場合、オプションは必要ありません。
Optional Chaining 、 Optionals 、 Coalescence 、およびその他の多くのソリューションは、悪名高い null に対処するのに役立ちます。
コードが成熟し、堅牢になり、null がなくなったら、それらを使用する必要はありません。
const user = { name: 'Hacker' }; if (user?.credentials?.notExpired) { user.login(); } user.functionDefinedOrNot?.(); // Seems compact but it is hacky and has lots // of potential NULLs and Undefined
function login() {} const user = { name: 'Hacker', credentials: { expired: false } }; if (!user.credentials.expired) { login(); } // Also compact // User is a real user or a polymorphic NullUser // Credentials are always defined. // Can be an instance of InvalidCredentials // Assuming we eliminated nulls from our code if (user.functionDefinedOrNot !== undefined) { functionDefinedOrNot(); } // This is also wrong. // Explicit undefined checks are yet another code smell
これは言語機能です。
検出して削除できます。
多くの開発者は、null 処理でコードを汚染しても安全だと感じています。
実際、これは NULL をまったく扱わないよりも安全です。
Nullish Values 、 Truthy 、 Falsy もコードの匂いです。
もっと上を目指して、よりクリーンなコードを作る必要があります。
良い点: コードからすべての null を削除します。
悪い点: オプションのチェーンを使用します。
醜い:ヌルをまったく扱わない。
Code Smell 69 - ビッグバン (JavaScript とんでもないキャスティング)
Unsplashのengin akyurtによる写真
怪物と戦う彼は、それによって怪物にならないように気をつけているかもしれません。そして、深淵をじっと見つめていれば、深淵もまたあなたを見つめている。
ニーチェ
すべての開発者は属性を等しく比較します。彼らは間違っています。
TL;DR: エクスポートして比較するのではなく、比較するだけです。
私たちのコードでは、属性比較が頻繁に使用されています。
私たちは行動と責任に焦点を当てる必要があります。
他のオブジェクトと比較するのは、オブジェクトの責任です。私たちのものではありません。
時期尚早のオプティマイザーは、これはパフォーマンスが低いことを教えてくれます。
彼らに本当の証拠を求めて、より保守しやすい解決策と対比すべきです。
if (address.street == 'Broad Street') { if (location.street == 'Bourbon St') { // 15000 usages in a big system // Comparisons are case sensitive
if (address.isAtStreet('Broad Street') { } // ... if (location.isAtStreet('Bourbon St') { } // 15000 usages in a big system function isAtStreet(street) { // We can change Comparisons to // case sensitive in just one place. }
構文ツリーを使用して属性比較を検出できます。
他の多くの匂いと同様に、プリミティブ型にも適切な用途があります。
責任を 1 か所に置く必要があります。
比較もその一つです。
ビジネス ルールの一部が変更された場合、 1 つのポイントを変更する必要があります。
UnsplashのPiret Ilverによる写真
ソフトウェアで最も重要なのは動作です。それはユーザーが依存するものです。ユーザーは、私たちが振る舞いを追加することを好みますが (それが彼らが本当に望んでいたものである場合)、彼らが依存する振る舞いを変更または削除すると (バグを導入します)、彼らは私たちを信頼しなくなります。
マイケル・フェザーズ
次の記事: さらに 5 つのコードの匂い。