161 olvasmányok

Refactoring 029 - Hogyan helyettesítsük a NULL-t a gyűjtéssel

által Maximiliano Contieri6m2025/06/02
Read on Terminal Reader

Túl hosszú; Olvasni

Helyettesítse a visszavonható opcionális attribútumokat üres gyűjteményekkel, hogy megszüntesse a null-ellenőrzéseket és kihasználja a polimorfizmust.
featured image - Refactoring 029 - Hogyan helyettesítsük a NULL-t a gyűjtéssel
Maximiliano Contieri HackerNoon profile picture

Átalakítsa az opcionális attribútumokat üres gyűjteményekké a tisztább, biztonságosabb és polimorfabb kód érdekében, kihagyva a milliárd dolláros hibát

TL;DR: Helyettesítse a visszavonható opcionális attribútumokat üres gyűjteményekkel, hogy megszüntesse a null ellenőrzéseket és kihasználja a polimorfizmust.

TL;DR: Helyettesítse a visszavonható opcionális attribútumokat üres gyűjteményekkel, hogy megszüntesse a null ellenőrzéseket és kihasználja a polimorfizmust.

Problémák megoldása

  • Zéró referencia kivételek
  • Túlzott feltételes logika és IF-k
  • törékeny hibák kezelése
  • Opcionális tulajdonságok
  • Komplex érvényesítési kód
  • Polimorfizmus megsértése

Lépések

  1. Határozza meg a törölhető opcionális attribútumokat, amelyek gyűjtemények lehetnek
  2. Egyetlen törölhető objektumok helyettesítése üres gyűjteményekkel
  3. Távolítsa el az összes null ellenőrzést ezekhez az opcionális attribútumokhoz kapcsolódóan
  4. Módszerek frissítése a gyűjteményekkel való munkavégzéshez az egyes objektumok helyett

Kódex

Mielőtt

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();
    }
}

Ezt követően 🙂

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();
  }
}

Típus

  • [x] félautomatikus

Biztonság ️

Ez a refaktorozás általában biztonságos, ha az összes hozzáférési pontot a gyűjtési attribútumokhoz vezérli.


Meg kell győződnie arról, hogy a külső kód nem várja a null értékeket, és foglalkozni kell a belső API-kkel.


A refaktorozás ugyanazt a külső viselkedést tartja fenn, miközben egyszerűsíti a belső logikát.


Ellenőrizze, hogy az összes gyártó és gyári módszer megfelelően kezdeményezi-e a gyűjteményeket.

Miért jobb a kód?

Az újrafogalmazott kód megszüntetiNull pont kivételekCsökkenti a feltételes összetettséget.


Az üres és nem üres gyűjtemények polimorf módon viselkednek, lehetővé téve, hogy egyenletesen kezeljék őket.


A kód egyre kiszámíthatóbbá válik, mivel a gyűjtemények mindig léteznek (legalábbis üresek), és ugyanazokra a műveletekre reagálnak.


A módszertani megvalósítások rövidebbek lesznek, és inkább az üzleti logikára összpontosítanak, mintsem a null kezelésre.


A megközelítés összhangban van azzal az elvvel, hogy az illegális államok nem képviselhetők a domain modellben, ami robusztusabb és karbantarthatóbb kódot eredményez.


Az üres és nem üres gyűjteményekpolymorphic.

Hogyan javítja a bijection? ️

A valós világban még akkor is léteznek konténerek, amikor üresek.


Ha az opcionális gyűjteményeket üres gyűjteményként jeleníti meg, nem pedig nullként, akkor a valóság pontosabb modelljét hozza létre.


A nulla nem létezik a valós világban, és mindig megszakítja aBiokémia.


Ez megtartja a valós koncepciók és a számítási modell közötti egy-egy megfelelést, ami jóTérkép.


Ha a nullok helyett a gyűjteményt adja vissza, aCsatlakoztatás.

Korlátozások ️

Előfordulhat, hogy ez a refaktorozás nem alkalmas, ha a null szemantikus jelentése eltér az "üres" szótól.


Biztosítania kell, hogy az összes kód útvonala következetesen kezdeményezze a gyűjteményeket, hogy elkerülje a kevert null és üres állapotokat.

Reaktorok AI

Javasolt utasítás: 1. Határozza meg a törölhető opcionális attribútumokat, amelyek gyűjtemények lehetnek 2. Helyettesítse az egyetlen törölhető objektumokat üres gyűjteményekkel 3. Távolítsa el az ezekhez az opcionális attribútumokhoz kapcsolódó összes null-ellenőrzést 4. Frissítse a módszereket a gyűjteményekkel való munkavégzéshez az egyes objektumok helyett 5. Tesztelje, hogy az üres és nem üres gyűjtemények következetesen viselkedjenek

Javasolt utasítás: 1. Határozza meg a törölhető opcionális attribútumokat, amelyek gyűjtemények lehetnek 2. Helyettesítse az egyetlen törölhető objektumokat üres gyűjteményekkel 3. Távolítsa el az ezekhez az opcionális attribútumokhoz kapcsolódó összes null-ellenőrzést 4. Frissítse a módszereket a gyűjteményekkel való munkavégzéshez az egyes objektumok helyett 5. Tesztelje, hogy az üres és nem üres gyűjtemények következetesen viselkedjenek

Without Proper Instructions

With Specific Instructions

ChatGPT

ChatGPT

Claude

Claude

Perplexity

Perplexity

Copilot

Copilot

Gemini

Gemini

DeepSeek

DeepSeek

Meta AI

Meta AI

Grok

Grok

Qwen

Qwen

Csehország

Csehország

Claire

Claire

félreértés

félreértés

gyermekpilóta

gyermekpilóta

Kettős

Kettős

mélység

mélység

A cél az

A cél az

Gróck

Gróck

Kövér

Kövér

Időjárás ️

  • Zéró

Szint

  • [x] Középtávú

Ezért

Hitelek

kép byEgyéb K.AzonA Pixabay


Ez a cikk a Refactoring sorozat része.


Trending Topics

blockchaincryptocurrencyhackernoon-top-storyprogrammingsoftware-developmenttechnologystartuphackernoon-booksBitcoinbooks