Pusty obiekt (wzorzec projektowy)

obiekt nie odnoszący się do żadnej wartości lub zachowujący się neutralnie

Pusty obiekt (ang. null object) – czynnościowy wzorzec projektowy (obiektowy), którego celem jest realizacja braku obiektu poprzez dostarczenie materialnej alternatywy, która oferuje domyślnie działanie puste, czyli niewykonujące żadnych operacji.

Wzorzec pusty obiekt umożliwia uniknięcie sprawdzenia, czy wartość jest różna od null przy zachowaniu zasad pełnej obiektowości (polimorfizm, abstrakcja, enkapsulacja).

Po raz pierwszy został opublikowany w książce Pattern Languages of Program Design. W książkach Martina Fowlera Refactoring i Joshua Kerievsky'ego Refactoring To Patterns[1] wzorzec ten uznawany jest jako Wzorzec refaktoryzacyjny[2][3].

Uzasadnienie użycia wzorca edytuj

W językach zorientowanych obiektowo, takich jak Java lub C#, zwykle dopuszczalne jest, by referencje miały wartość pustą. Wywołanie metody na referencji pustej z reguły prowadzi do błędu, dlatego przed wywołaniem jakichkolwiek metod na referencji należy sprawdzić, czy nie ma ona pustej wartości. Aby wyeliminować powtarzanie testów wartości pustej wykorzystuje się wzorzec pusty obiekt.

Zalety edytuj

  • upraszcza kod programu, eliminując zbędne i powtarzające się instrukcje warunkowe,
  • stosuje klasy polimorficzne,
  • hermetyzuje puste zachowanie, poprzez metodę o pustym ciele,
  • umożliwia wielokrotne wykorzystanie pustego zachowania.

Wady edytuj

  • sprawia, że puste zachowanie trudno rozpowszechnić wśród zachowań kilku obiektów współpracujących (silna hermetyzacja),
  • może powodować eksplozję (niepotrzebny rozrost) klasy,
  • może spowodować, że normalne wykonywanie programu potraktowane jest jako błąd.

Struktura edytuj

 
Diagram klas wzorca pusty obiekt

Głównymi elementami w tym wzorcu są:

  • Client – klient stosuje realizację klasy abstrakcyjnej. Z punktu widzenie klienta nie ma znaczenia, czy realizacja jest obiektem pustym, czy rzeczywistym, ponieważ oba są stosowane w ten sam sposób.
  • AbstractObject – klasa abstrakcyjna, która może być realizowana przez klasę rzeczywistą lub pustą.
  • RealObject – rzeczywista realizacja klasy AbstractObject wykonująca konkretne działanie.
  • NullObject – realizacja klasy AbstractObject, w której nic nie jest wykonywane, w celu zapewnienia dostarczenia niepustego obiektu do klienta.

Wzorce powiązane edytuj

  • Pusty obiekt jako singleton. Klasa NullObject jest często implementowana jako singleton[4]. Zwykle pusty obiekt nie ma żadnego stanu lub stanu nie można zmienić, więc w wielu przypadkach instancje są identyczne. Zamiast używania identycznych instancji w wielu przypadkach wystarczy, że system użyje jednej instancji wielokrotnie.
  • Pusty obiekt jako szczególny przypadek wzorca strategii[4]. Strategia określa kilka klas ConcreteStrategy jako różne podejścia do realizacji zadania. Jeśli jedno z tych podejść konsekwentnie nic nie wykonuje, to oznacza, że klasą ConcreteStrategy jest klasa NullObject.
  • Pusty obiekt jako szczególny przypadek wzorca stanu[4]. Jeśli konkretna klasa ConcreteState ze wzorca Stanu realizuje większość swoich metod jako puste (nic nie wykonują) lub przynajmniej zwracają pusty wynik, to wtedy taką klasę określamy jako pusty stan (ang. null state).
  • Pusty obiekt może być wykorzystany do umożliwienia wzorcowi odwiedzający (ang. visitor)[4] bezpiecznie odwiedzić hierarchię i obsłużyć puste sytuacje (obiekty).

Przypisy edytuj

  1. Joshua Kerievsky: Refactoring To Patterns. Addison-Wesley, 2004. ISBN 0-321-21335-1.
  2. Bobby Woolf: Pattern Languages of Program Design 3. Addison-Wesley, 1998.
  3. Martin Fowler: Refactoring. Improving the Design of Existing Code. Addison-Wesley, 1999. ISBN 0-201-48567-2.
  4. a b c d Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides: Design Patterns: Elements of Reusable Object-Oriented Software. Addison-Wesley, 1995.

Linki zewnętrzne edytuj