コードの匂いはクラシックです。
においがするのは、編集または改善できる場合が多いためです。
これらの臭いのほとんどは、何かが間違っている可能性があることを示しているだけです。したがって、それ自体を修正する必要はありません…(ただし、調べておく必要があります)。
前 コードの匂い
以前のコードの匂い (パート i ~ XXVIII) はすべてここにあります。
続けましょう...
Code Smell 141 - IEngine、AVehicle、ImplCar
野生の IEngine を見たことがありますか?
TL;DR: クラスに接頭辞や接尾辞を付けないでください
問題
- 可読性
- バイジェクション断層
- 実装名
ソリューション
- プレフィックスとサフィックスを削除する
- オブジェクトに名前を付ける
環境
一部の言語には、データ型、抽象クラス、またはインターフェイスに関連するカルチャ規則があります。これらの名前は、理解するのが難しい認知翻訳をモデルにロードします。
私たちはキスをしなければなりません。
サンプルコード
間違い
public interface IEngine { void Start(); } public class ACar { } public class ImplCar { } public class CarImpl { }
右
public interface Engine { void Start(); } public class Vehicle { } public class Car { }
検出
- [×]自動
シソーラスがあれば、厄介な名前を指すことができます。
例外
C# では、インターフェイスの名前に "I" を付けるのが一般的です。これがないと、それがインターフェイスなのかクラスなのかがわからないからです。
これは言語の匂いです。
タグ
- ネーミング
結論
モデルには実名を使用してください。
関係
より詳しい情報
クレジット
UnsplashのTim Mossholderによる写真
問題に直面したときに、「分かった、正規表現を使用する」と考える人もいます。現在、彼らには 2 つの問題があります。
ジェイミー・ザウィンスキー
Code Smell 142 - コンストラクターでのクエリ
ドメイン オブジェクトでデータベースにアクセスするのは、コードの匂いです。コンストラクターでそれを行うと、二重の臭いがします。
TL;DR: コンストラクターは、オブジェクトを構築 (およびおそらく初期化) する必要があります。
問題
- カップリング
- 副作用
ソリューション
- 重要なビジネス ロジックを偶発的な持続性から切り離します。
- 永続化クラスでは、コンストラクタ/デストラクタ以外の関数でクエリを実行します。
環境
レガシ コードでは、データベースがビジネス オブジェクトから正しく分離されていません。
コンストラクターには副作用があってはなりません。
単一責任の原則に従って、有効なオブジェクトのみを構築する必要があります。
サンプルコード
間違い
public class Person { int childrenCount; public Person(int id) { childrenCount = database.sqlCall("SELECT COUNT(CHILDREN) FROM PERSON WHERE ID = " . id); } }
右
public class Person { int childrenCount; // Create a class constructor for the Main class public Person(int id, int childrenCount) { childrenCount = childrenCount; // We can assign the number in the constructor // Accidental Database is decoupled // We can test the object } }
検出
- [x]半自動
私たちのリンターは、コンストラクターの SQL パターンを見つけて警告することができます。
タグ
- カップリング
結論
関心の分離が鍵であり、結合は堅牢なソフトウェアを設計する際の主な敵です。
より詳しい情報
クレジット
<span> Unsplash のCallum Hillによる写真</span>
私の考えでは、データ構造とその不変条件を正しく理解すれば、ほとんどのコードは自動的に記述されます。
ピーター・デウスト
Code Smell 143 - データの塊
いくつかのオブジェクトは常に一緒です。分けてみませんか?
TL;DR: まとまりのあるプリミティブ オブジェクトを一緒に移動させる
問題
- 悪い結束
- 重複コード
- 検証の複雑さ
- 可読性
- 保守性
ソリューション
- 抽出クラス
- 小さなオブジェクトを見つける
環境
この匂いは、原始的な強迫観念と友達です。
2 つ以上のプリミティブ オブジェクトが結合され、ビジネス ロジックが繰り返され、オブジェクト間に規則が存在する場合、既存の全単射の概念を見つける必要があります。
サンプルコード
間違い
public class DinnerTable { public DinnerTable(Person guest, DateTime from, DateTime to) { Guest = guest; From = from; To = to; } private Person Guest; private DateTime From; private DateTime To; }
右
public class TimeInterval { public TimeInterval(DateTime from, DateTime to) { // We should validate From < To From = from; To = to; } } public DinnerTable(Person guest, DateTime from, DateTime to) { Guest = guest; Interval = new TimeInterval(from, to); } // Even Better... public DinnerTable(Person guest, Interval reservationTime) { Guest = guest; Interval = reservationTime; }
検出
- [x]半自動
結束パターンに基づく検出は、いくつかのリンターで利用できます。
タグ
- 凝集
結論
動作を適切な場所にグループ化し、プリミティブ データを非表示にします。
関係
より詳しい情報
クレジット
UnsplashのDynamic Wangによる写真
ソフトウェアの核心は、ユーザーのドメイン関連の問題を解決する能力です。他のすべての機能は、重要ではあるかもしれませんが、この基本的な目的をサポートしています。
エリック・エヴァンス
Code Smell 144 - 代替可能なオブジェクト
NFTについてはよく耳にします。これで、Fungible の概念をマスターできました。
TL;DR: MAPPERを尊重してください。現実世界で代替可能なものを代替可能にし、その逆も同様です。
問題
- バイジェクション断層
- オーバーデザイン
ソリューション
- ドメインの代替可能な要素を特定する
- それらを交換可能としてモデル化する
環境
ウィキペディアによると:
Fungibility は、個々の単位が本質的に交換可能であり、各部分が別の部分と区別できない財または商品の特性です。
ソフトウェアでは、代替可能オブジェクトを他のオブジェクトに置き換えることができます。
オブジェクトを実際のオブジェクトにマッピングするとき、部分的なモデルを忘れて設計を上書きすることがあります。
サンプルコード
間違い
public class Person implements Serializable { private final String firstName; private final String lastName; public Person(String firstName, String lastName) { this.firstName = firstName; this.lastName = lastName; } } shoppingQueueSystem.queue(new Person('John', 'Doe'));
右
public class Person { } shoppingQueueSystem.queue(new Person()); // The identity is irrelevant for queue simulation
検出
- [×]マニュアル
これはセマンティックな匂いです。
モデルが正しいかどうかを確認するには、モデルを理解する必要があります。
タグ
- オーバーデザイン
結論
代替可能なものは代替可能にし、その逆も同様です。
簡単に聞こえますが、設計スキルが必要で、偶発的な複雑さを避ける必要があります。
クレジット
UnsplashのAndrey Metelevによる写真
人々はコンピューター サイエンスは天才の芸術だと思っていますが、実際の現実はその逆で、小さな石の壁のように、多くの人がお互いに積み重なることを行っているだけです。
ドナルド・クヌース
Code Smell 145 - 短絡ハック
読みやすさの近道としてブール値評価を使用しないでください。
TL;DR: 副作用関数にブール比較を使用しないでください。
問題
- 可読性
- 副作用
ソリューション
- 短絡をIFに変換
環境
頭の良いプログラマーは、ハッキーであいまいなコードを書くのが好きですが、この改善に関する強力な証拠がない場合でも同様です。
時期尚早の最適化は常に可読性を損ないます。
サンプルコード
間違い
userIsValid() && logUserIn(); // this expression is short circuit // Does not value second statement // Unless the first one is true functionDefinedOrNot && functionDefinedOrNot(); // in some languages undefined works as a false // If functionDefinedOrNot is not defined does // not raise an error and neither runs
右
if (userIsValid()) { logUserIn(); } if(typeof functionDefinedOrNot == 'function') { functionDefinedOrNot(); } // Checking for a type is another code smell
検出
- [x]半自動
関数が純粋でないかどうかを確認し、短絡を IF に変更できます。
実際のリンターの中には、この問題について警告するものがあります
タグ
- 時期尚早の最適化
結論
賢く見せようとしないでください。
私たちはもう50代ではありません。
チーム開発者になりましょう。
関係
クレジット
UnsplashのMichael Dziedzicによる写真
コンピューターは信じられないほど賢いことを行う能力を備えた愚かな機械ですが、コンピュータープログラマーは信じられないほど愚かなことを行う能力を備えた賢い人々です。要するに、それらは完全に一致しています。
ビル・ブライソン
次の記事: さらに 5 つのコードの匂い。