Introduksjon til Null Object Pattern

1. Oversikt

I denne raske opplæringen tar vi en titt på Null Object Pattern, et spesielt tilfelle av strategimønsteret. Vi beskriver formålet og når vi faktisk bør vurdere å bruke det.

Som vanlig vil vi også gi et enkelt kodeeksempel.

2. Null Object Pattern

I de fleste objektorienterte programmeringsspråk har vi ikke lov til å bruke a null henvisning. Derfor blir vi ofte tvunget til å skrive null sjekker:

Kommando cmd = getCommand (); hvis (cmd! = null) {cmd.execute (); }

Noen ganger, hvis antall slike hvis utsagn blir høye, kan koden bli stygg, vanskelig å lese og feilutsatt. Dette er når Null Object Pattern kan være nyttig.

Hensikten med Null Object Pattern er å minimere den slags null Sjekk. I stedet kan vi identifisere null-oppførselen og kapsle den inn i typen som forventes av klientkoden. Oftere enn ikke, slik nøytral logikk er veldig enkel - gjør ingenting. På denne måten trenger vi ikke lenger håndtere spesiell håndtering av null referanser.

Vi kan ganske enkelt behandle nullobjekter på samme måte som vi behandler andre forekomster av en gitt type som faktisk inneholder noe mer sofistikert forretningslogikk. Følgelig forblir klientkoden renere.

Ettersom null-objekter ikke skal ha noen tilstand, er det ikke nødvendig å opprette identiske forekomster flere ganger. Dermed vil vi ofte implementere null objekter som singler.

3. UML Diagram for Null Object Pattern

La oss se på mønsteret visuelt:

Som vi kan se, kan vi identifisere følgende deltakere:

  • Klient krever en forekomst av Abstrakt Objekt
  • Abstrakt Objekt definerer kontrakten Klient forventer - det kan også inneholde delt logikk for implementeringsklassene
  • RealObject redskaper Abstrakt Objekt og gir ekte oppførsel
  • NullObject redskaper Abstrakt Objekt og gir nøytral oppførsel

4. Gjennomføring

Nå som vi har en klar ide om teorien, la oss se på et eksempel.

Tenk deg at vi har et meldingsruterapplikasjon. Hver melding skal ha en gyldig prioritet. Systemet vårt skal føre rute med høy prioritet til en SMS-gateway, mens meldinger med middels prioritet skal sendes til en JMS-kø.

Fra tid til annen, imidlertid kan meldinger med “udefinert” eller tom prioritet komme til søknaden vår. Slike meldinger bør kastes fra videre behandling.

Først skal vi lage Ruter grensesnitt:

offentlig grensesnitt Router {void route (Message msg); }

Deretter la oss lage to implementeringer av grensesnittet ovenfor - den som er ansvarlig for ruting til en SMS-gateway og den som vil dirigere meldingene til JMS-køen:

offentlig klasse SmsRouter implementerer Router {@Override public void route (Message msg) {// implementeringsdetaljer}}
offentlig klasse JmsRouter implementerer Router {@Override public void route (Message msg) {// implementeringsdetaljer}}

Endelig, la oss implementere vårt null-objekt:

offentlig klasse NullRouter implementerer Router {@Override public void route (Message msg) {// gjør ingenting}}

Vi er nå klare til å sette sammen alle delene. La oss se hvordan eksempelklientkoden kan se ut:

public class RoutingHandler {public void handle (Iterable messages) {for (Message msg: messages) {Router router = RouterFactory.getRouterForMessage (msg); router.route (msg); }}}

Som vi kan se, vi behandler alle Ruter objekt på samme måte, uansett hvilken implementering som returneres av RouterFactory. Dette gjør at vi kan holde koden ren og lesbar.

5. Når skal du bruke Null Object Pattern

Vi bør bruke Null Object Pattern når en Klient ellers ville sjekket for null bare for å hoppe over utførelse eller utføre en standardhandling. I slike tilfeller kan vi kapsle inn den nøytrale logikken i et nullobjekt og returnere den til klienten i stedet for null verdi. Denne måten klientens kode ikke lenger trenger å være klar over om en gitt forekomst er null eller ikke.

En slik tilnærming følger generelle objektorienterte prinsipper, som Tell-Don't-Ask.

For å bedre forstå når vi skal bruke Null Object Pattern, la oss forestille oss at vi må implementere CustomerDao grensesnitt definert som følger:

offentlig grensesnitt CustomerDao {Collection findByNameAndLastname (strengnavn, strengnavn); Kunde getById (lang id); }

De fleste av utviklerne ville komme tilbake Collections.emptyList () fra findByNameAndLastname () i tilfelle ingen av kundene stemmer overens de angitte søkekriteriene. Dette er et veldig godt eksempel på å følge Null Object Pattern.

I kontrast, den ById () skal returnere kunden med gitt ID. Noen som kaller denne metoden forventer å få den spesifikke kundenheten. I tilfelle ingen slik kunde eksisterer, bør vi eksplisitt returnere null for å signalisere at det er noe galt med den medfølgende ID-en.

Som med alle andre mønstre, vi må vurdere vår spesifikke brukssak før vi blindt implementerer Null Object Pattern. Ellers kan vi utilsiktet introdusere noen feil i koden vår som det vil være vanskelig å finne.

6. Konklusjon

I denne artikkelen lærte vi hva Null Object Pattern er og når vi kan bruke det. Vi implementerte også et enkelt eksempel på designmønsteret.

Som vanlig er alle kodeeksemplene tilgjengelig på GitHub.


$config[zx-auto] not found$config[zx-overlay] not found