オプションの属性を空のコレクションに変換し、クリーンで安全で多形なコードを提供し、数十億ドルのエラーを排除します。
TL;DR:無効化可能なオプション属性を空のコレクションに置き換え、ゼロチェックを排除し、ポリモルフィズムを悪用します。
TL;DR:無効化可能なオプション属性を空のコレクションに置き換え、ゼロチェックを排除し、ポリモルフィズムを悪用します。
問題解決 ↓↓
- ゼロ参照例外
- 過剰条件論理とIFS
- 脆弱な操作ミス
- オプション属性
- 複雑な認証コード
- ポリモリズム違反
関連コード 臭い
ステップ↓
- Collections である可能性のある無効なオプション属性を識別する
- 単一の無効なオブジェクトを空のコレクションに置き換える
- これらのオプション属性に関連するすべての null チェックを削除する
- 単一オブジェクトではなくコレクションで作業する方法を更新
サンプルコード
前の↓↓
public class ShoppingCart {
private List<Item> items = new ArrayList<>();
private Coupon coupon = null;
public void addItem(Item item) {
this.items.add(item);
}
public void redeemCoupon(Coupon coupon) {
this.coupon = coupon;
}
public double total() {
double total = 0;
for (Item item : this.items) {
total += item.getPrice();
}
// This a polluted IF and null check
if (this.coupon != null) {
total -= this.coupon.getDiscount();
}
return total;
}
public boolean hasUnsavedChanges() {
// Explicit null check
return !this.items.isEmpty() || this.coupon != null;
}
public boolean hasCoupon() {
return this.coupon != null;
}
}
public class ShoppingCart {
private final List<Item> items = new ArrayList<>();
// This version uses Optionals
// Not all programming languages support this feature
private Optional<Coupon> coupon = Optional.empty();
public void addItem(Item item) {
items.add(item);
}
public void redeemCoupon(Coupon coupon) {
// You need to understand how optionals work
this.coupon = Optional.ofNullable(coupon);
}
public boolean hasUnsavedChanges() {
return !items.isEmpty() || !coupon.isPresent();
}
public boolean hasCoupon() {
return coupon.isPresent();
}
}
その後↓
public class ShoppingCart {
private List<Item> items = new ArrayList<>();
// 1. Identify nullable optional attributes
// that could be collections
// 2. Replace single nullable objects with empty collections
private List<Coupon> coupons = new ArrayList<>();
public void addItem(Item item) {
this.items.add(item);
}
// Step 4: Work with collection
// instead of single nullable object
public void redeemCoupon(Coupon coupon) {
this.coupons.add(coupon);
}
// Step 4: Simplified logic without null checks
public double total() {
double total = 0;
for (Item item : this.items) {
total += item.getPrice();
}
// 3. Remove all null checks
// related to these optional attributes
for (Coupon coupon : this.coupons) {
total -= coupon.getDiscount();
}
return total;
}
// Consistent behavior with empty collections
public boolean hasUnsavedChanges() {
// 4. Update methods to work with collections
// instead of single objects
return !this.items.isEmpty() || !this.coupons.isEmpty();
}
// 3. Remove all null checks
// related to these optional attributes
// Collection-based check instead of null check
public boolean hasCoupon() {
return !this.coupons.isEmpty();
}
}
タイプ↓
- (x)半自動
セキュリティ ️
このリファクタリングは、コレクション属性のすべてのアクセスポイントを制御する場合に一般的に安全です。
外部のコードが null 値を期待しないことを確認し、内部の API に対処する必要があります。
再現化は、同じ外部の行動を維持し、内部の論理を簡素化する。
すべての構築者と工場の方法がコレクションを適切に初期化していることを確認する必要があります。
なぜコードが良いのか?
refactored code 削除Null Pointer 例外条件複雑さを減らす。
空のコレクションと非空のコレクションは、ポリモルフ的に振る舞い、均一に扱うことができます。
コードは、コレクションが常に存在する(少なくとも空っぽ)で、同じ操作に反応するので、より予測可能になります。
方法の実装はより短くなり、ゼロ処理よりもビジネス論理に焦点を当てている。
このアプローチは、あなたのドメインモデルで違法な州を代表できないようにすることの原則と一致しており、より強力で維持可能なコードにつながります。
空のコレクションと非空のコレクションpolymorphic.
では、どのようにしてバリエーションを改善するのか?️
現実世界では、コンテナは空っぽの時でも存在します。
オプションのコレクションをゼロではなく空のコレクションとして表示することにより、より正確な現実モデルを作成します。
ゼロは現実世界には存在しないし、常に破る。バイエクション.
これにより、現実世界のコンセプトとあなたのコンピュータ・モデル間の1対1の相応性を維持し、良いコンピュータ・モデルを作成します。マップ.
nulls の代わりにコレクションを返すと、コレクションの値も削減します。カプセル.
️制限
このリファクタリングは、null が「空」とは異なる意味を持つ場合に適切ではない場合があります。
すべてのコードパスがコレクションを一貫して初期化することを確認し、混合した null と 空の状態を避ける必要があります。
リハーサル AI
Suggested Prompt: 1. コレクションになる可能性のある無効なオプション属性を識別する 2. 単一無効なオブジェクトを空のコレクションに置き換える 3. これらの無効な属性に関連するすべての無効チェックを削除 4. 単一のオブジェクトではなくコレクションで動作する方法を更新 5. 空のコレクションと非空のコレクションが一貫して動作することをテストする
Suggested Prompt: 1. コレクションになる可能性のある無効なオプション属性を識別する 2. 単一無効なオブジェクトを空のコレクションに置き換える 3. これらの無効な属性に関連するすべての無効チェックを削除 4. 単一のオブジェクトではなくコレクションで動作する方法を更新 5. 空のコレクションと非空のコレクションが一貫して動作することをテストする
Without Proper Instructions |
With Specific Instructions |
---|---|
タグ ️
- ゼロ
レベル
- (x) 中間
関連記事↓↓
こちら↓↓↓
クレジット↓
この記事は、Refactoringシリーズの一部です。