Null-Objekt-Muster

Im Null-Objekt-Muster ersetzt ein Null-Objekt die Prüfung auf NULL-Objektinstanzen. Statt auf Nullwerte zu prüfen, antwortet das Null-Objekt mit einer Beziehung, die nichts bewirkt. Ein solches Null-Objekt kann auch ein Standardverhalten bereitstellen, wenn keine Daten verfügbar sind.

Im Null-Objekt-Muster erstellen wir eine abstrakte Klasse, die verschiedene auszuführende Operationen vorgibt, und Entitätsklassen, die diese Klasse erweitern, und erstellen außerdem eine Null-Objekt-Klasse, die nichts für die Klasse implementiert. Diese Null-Objekt-Klasse wird nahtlos an Stellen verwendet, an denen Null-Prüfungen erforderlich sind.


summary

Absicht

Verwenden Sie ein Null-Objekt anstelle eines Nullwerts. Das Null-Objekt implementiert dieselbe Schnittstelle, führt jedoch keine Operationen aus oder stellt Standardoperationen für Anfragen bereit.

Wesentliche gelöste Probleme

  • Das Null-Objekt-Muster löst Probleme, die durch die Verwendung von Nullwerten in einem System entstehen können, wie z. B. NullPointerException-Ausnahmen.
  • Es ermöglicht dem System, mit einem "sicheren" Null-Objekt weiterzulaufen, wenn kein geeignetes Objekt verfügbar ist, anstatt fehlzuschlagen.

Anwendungsfall

  • Wenn das System Null-Objekte verarbeiten muss, aber auch Null-Prüfungen oder die Behandlung von Nullwerten vermeiden möchte.

Implementierungsansatz

  • Protokoll definieren:Definieren Sie ein Protokoll oder eine Schnittstelle, die die zu implementierenden Verhaltensweisen spezifiziert.
  • Konkrete Objekte erstellen:Konkrete Objekte, die das Protokoll implementieren und tatsächliches Verhalten bereitstellen.
  • Null-Objekt erstellen:Implementieren Sie außerdem dasselbe Protokoll, bieten Sie jedoch eine "leere" Implementierung, d. h., es werden keine sinnvollen Operationen ausgeführt.

Schlüsselcode

  • Protokoll oder Schnittstelle:Gibt die Methoden an, die das Objekt implementieren muss.
  • Konkretes Objekt:Implementiert das Protokoll und enthält die tatsächliche Geschäftslogik.
  • Null-Objekt:Implementiert das Protokoll, aber die Methodenimplementierungen sind leer oder Standardverhalten.

Anwendungsbeispiel

  • Protokollierungssystem:In einem Protokollierungssystem kann ein Null-Objekt einen Logger darstellen, der keine Operationen ausführt.
  • Standardbenutzer: In einem System kann, wenn derzeit kein Benutzer vorhanden ist, anstelle von null ein leeres Benutzerobjekt verwendet werden.

Vorteile

  1. Vermeidung von Null-Prüfungen: Beseitigt Null-Prüfungen im Code.
  2. Vereinfachung des Client-Codes: Clients können Methoden direkt aufrufen, unabhängig davon, ob das Objekt null ist.
  3. Erweiterbarkeit: Das Hinzufügen neuer konkreter Objekte ist für Clients transparent und erfordert keine Änderung des vorhandenen Codes.

Nachteile

  • Kann Fehler verbergen: Die Verwendung von Null-Objekten kann Fehler oder Ausnahmebedingungen verbergen und das Debugging erschweren.
  • Erhöht die Designkomplexität: Ein Null-Objekt muss für jede Schnittstelle implementiert werden, die null zurückgeben kann.

Verwendungshinweise

  • Wenn das System Nullwerte verarbeiten muss, aber auch die Fehlerbehandlung vereinfachen und Null-Prüfungen vermeiden möchte, sollte die Verwendung des Null-Objekt-Musters in Betracht gezogen werden.

Hinweise

  • Das Null-Objekt-Muster sollte mit Vorsicht verwendet werden, um sicherzustellen, dass es keine Fehler verbirgt oder den wahren Zustand des Systems verschleiert.
  • Ein Null-Objekt sollte dieselbe Schnittstelle wie konkrete Objekte bereitstellen, damit Client-Code es ohne Änderungen verwenden kann.

Struktur

Das Null-Objekt-Muster umfasst die folgenden Hauptrollen:

  • AbstractionObject(Abstract Object): Definiert die vom Client erwartete Schnittstelle. Diese Schnittstelle kann eine abstrakte Klasse oder ein Interface sein.

  • Concrete Object(Concrete Object): Konkrete Klassen, die die Schnittstelle des abstrakten Objekts implementieren. Diese Klassen bieten echtes Verhalten.

  • Null Object:Eine Null-Objekt-Klasse, die die abstrakte Objektschnittstelle implementiert. Diese Klasse bietet standardmäßiges No-Op-Verhalten, das verwendet werden kann, wenn das Objekt nicht verfügbar oder nicht anwendbar ist. Sie kann als Ersatz für konkrete Objekte dienen und Null-Prüfungen im Client-Code ersetzen.

Implementierung

Wir werden eine erstellen, die Operationen definiert (hier den Namen des Kunden) ...AbstractCustomerAbstrakte Klasse, und vonAbstractCustomerabgeleitete Entitätsklassen. Factory-KlasseCustomerFactoryBasierend auf dem vom Kunden übergebenen Namen, geben SieRealCustomeroderNullCustomer-Objekt zurück.

NullPatternDemo, unsere Demo-Klasse verwendetCustomerFactory, um die Verwendung des Null-Objekt-Musters zu demonstrieren.

空对象模式的 UML 图

Schritt 1

Erstellen Sie eine abstrakte Klasse.

AbstractCustomer.java

public abstract class AbstractCustomer { protected String name; public abstract boolean isNil(); public abstract String getName(); }

Schritt 2

Erstellen Sie Entitätsklassen, die die obige Klasse erweitern.

RealCustomer.java

public class RealCustomer extends AbstractCustomer { public RealCustomer(String name) { this.name = name; } @Override public String getName() { return name; } @Override public boolean isNil() { return false; } }

NullCustomer.java

public class NullCustomer extends AbstractCustomer { @Override public String getName() { return "Nicht in der Kundendatenbank verfügbar"; } @Override public boolean isNil() { return wahr; } }

Schritt 3

ErstellenCustomerFactory-Klasse.

CustomerFactory.java

public class CustomerFactory { public static final String[] names = {"Rob", "Joe", "Julie"}; public static AbstractCustomer getCustomer(String name){ for (int i = 0; i < names.length; i++) { if (names[i].equalsIgnoreCase(name)){ return new RealCustomer(name); } } return new NullCustomer(); } }

Schritt 4

VerwendungCustomerFactory, basierend auf dem vom Kunden übergebenen Namen, umRealCustomeroderNullCustomer zu erhaltenObjekt.

NullPatternDemo.java

public class NullPatternDemo { public static void main(String[] args) { AbstractCustomer customer1 = CustomerFactory.getCustomer("Rob"); AbstractCustomer customer2 = CustomerFactory.getCustomer("Bob"); AbstractCustomer customer3 = CustomerFactory.getCustomer("Julie"); AbstractCustomer customer4 = CustomerFactory.getCustomer("Laura"); System.out.println("Kunden"); System.out.println(customer1.getName()); System.out.println(customer2.getName()); System.out.println(customer3.getName()); System.out.println(customer4.getName()); } }

Schritt 5

Programm ausführen, Ergebnis ausgeben:

Customers
Rob
Not Available in Customer Database
Julie
Not Available in Customer Database
Weitere Erweiterungen