161 čtení

Refactoring 029 - Jak nahradit NULL s kolekcí

podle Maximiliano Contieri6m2025/06/02
Read on Terminal Reader

Příliš dlouho; Číst

Nahraďte nullovatelné volitelné atributy prázdnými sbírkami, abyste odstranili null kontroly a využili polymorfismus.
featured image - Refactoring 029 - Jak nahradit NULL s kolekcí
Maximiliano Contieri HackerNoon profile picture

Přeměňte volitelné atributy na prázdné sbírky pro čistší, bezpečnější a polymorfický kód, čímž vyloučíte miliardovou chybu

TL;DR: Nahraďte nullovatelné volitelné atributy prázdnými sbírkami, abyste odstranili null kontroly a využili polymorfismus.

TL;DR: Nahraďte nullovatelné volitelné atributy prázdnými sbírkami, abyste odstranili null kontroly a využili polymorfismus.

Problémy řešené

  • Nulové referenční výjimky
  • Nadměrná podmíněná logika a IF
  • Křehká chyba při manipulaci
  • Volitelné atributy
  • Komplexní ověřovací kód
  • Porušení polymorfismu

kroky

  1. Identifikace zrušených volitelných atributů, které mohou být sbírkami
  2. Vyměňte jednotlivé nullovatelné objekty za prázdné sbírky
  3. Odstranění všech null kontrol souvisejících s těmito volitelnými atributy
  4. Aktualizace metod pro práci se sbírkami namísto jednotlivých objektů

Vzorový kód

Před

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

Po tomto 🙂

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

Typ

  • [x] poloautomatické

Bezpečnost ️

Toto refaktorování je obecně bezpečné, pokud ovládáte všechny přístupové body k atributům sbírky.


Musíte se ujistit, že žádný externí kód neočekává nulové hodnoty a zabývá se vnitřními API.


Refaktoring udržuje stejné vnější chování a zároveň zjednodušuje vnitřní logiku.


Měli byste ověřit, že všichni konstruktéři a tovární metody správně iniciují sbírky.

Proč je kód lepší?

Změněný kód eliminujeNulové výjimkySnižuje podmíněnou složitost.


Prázdné sbírky a ne-prázdné sbírky se chovají polymorfně, což vám umožní zacházet s nimi rovnoměrně.


Kód se stává předvídatelnější, protože sbírky vždy existují (alespoň prázdné) a reagují na stejné operace.


Implementace metod se stávají kratšími a více se zaměřují na obchodní logiku namísto null manipulace.


Tento přístup je v souladu se zásadou, že nelegální státy jsou ve vašem doménovém modelu nereprezentovatelné, což vede k robustnějšímu a udržitelnějšímu kódu.


Prázdné sbírky a ne-prázdné sbírkypolymorphic.

Jak se vypořádat s tímto problémem? ️

V reálném světě existují kontejnery, i když jsou prázdné.


Zobrazováním volitelných sbírek jako prázdných sbírek namísto null vytvoříte přesnější model reality.


Nul neexistuje v reálném světě a vždy porušujeBičování.


Tím se udržuje vzájemná korelace mezi reálnými koncepty a vašim výpočetním modelem, čímž se vytváří dobrýMapy.


Když vrátíte sbírku namísto nullů, snížíte takéSpojení.

Omezení ️

Toto refaktorování nemusí být vhodné, pokud null má jiný sémantický význam než „prázdný“.Některé tradiční rozhraní API mohou očekávat hodnoty null, které vyžadují adaptační vrstvy.


Musíte zajistit, aby všechny cesty kódu inicializovaly sbírky důsledně, aby se zabránilo smíšeným nulovým a prázdným stavům.

Reaktor s AI

Navržená nabídka: 1. identifikujte nullovatelné volitelné atributy, které by mohly být sbírkami 2. nahraďte jednotlivé nullovatelné objekty prázdnými sbírkami 3. odstraňte všechny null kontroly související s těmito volitelnými atributy 4. aktualizujte metody pro práci se sbírkami namísto s jednotlivými objekty 5. otestujte, zda se prázdné a ne-prázdné sbírky chovají konzistentně

Navržená nabídka: 1. identifikujte nullovatelné volitelné atributy, které by mohly být sbírkami 2. nahraďte jednotlivé nullovatelné objekty prázdnými sbírkami 3. odstraňte všechny null kontroly související s těmito volitelnými atributy 4. aktualizujte metody pro práci se sbírkami namísto s jednotlivými objekty 5. otestujte, zda se prázdné a ne-prázdné sbírky chovají konzistentně

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

Chatky

Chatky

Claude

Claude

Zmatenost

Zmatenost

Copilot

Copilot

Dvojčata

Dvojčata

hluboký

hluboký

Cílem AI

Cílem AI

Grochová

Grochová

Květen

Květen

Týden ️

  • Nulová

Úroveň

  • [x] Zprostředkování

Tohle je

Půjčky

Obrázek odAž do K.jePixabay


Tento článek je součástí série Refactoring.


L O A D I N G
. . . comments & more!

About Author

Maximiliano Contieri HackerNoon profile picture
Maximiliano Contieri@mcsee
I’m a sr software engineer specialized in Clean Code, Design and TDD Book "Clean Code Cookbook" 500+ articles written

ZAVĚŠIT ZNAČKY

TENTO ČLÁNEK BYL PŘEDSTAVEN V...

Trending Topics

blockchaincryptocurrencyhackernoon-top-storyprogrammingsoftware-developmenttechnologystartuphackernoon-booksBitcoinbooks