Marker-grensesnitt i Java

1. Introduksjon

I denne raske opplæringen lærer vi om markørgrensesnitt i Java.

2. Markørgrensesnitt

Et markørgrensesnitt er et grensesnitt som har ingen metoder eller konstanter inni seg. Det gir kjøretidstypeinformasjon om objekter, slik har kompilatoren og JVM det tilleggsinformasjon om objektet.

Et markørgrensesnitt kalles også et merkingsgrensesnitt.

Selv om markørgrensesnitt fortsatt er i bruk, peker de sannsynligvis på en kodelukt og bør brukes forsiktig. Hovedårsaken til dette er at de uskarpe linjene om hva et grensesnitt representerer siden markører ikke definerer noen oppførsel. Nyere utvikling favoriserer merknader for å løse noen av de samme problemene.

3. JDK Marker-grensesnitt

Java har mange innebygde markørgrensesnitt, for eksempel Serialiserbar, Klonbar, og Fjernkontroll.

La oss ta eksemplet på Klonbar grensesnitt. Hvis vi prøver å klone et objekt som ikke implementerer dette grensesnittet, kaster JVM en CloneNotSupportedException. Derav Klonbarmarkørgrensesnitt er en indikator for JVM som vi kan kalle Object.clone () metode.

På samme måte når du ringer ObjectOutputStream.writeObject () metode, JVM sjekker om objektet implementerer Serialiserbar markørgrensesnitt. Når det ikke er tilfelle, a NotSerializableException blir kastet. Derfor blir objektet ikke seriellisert til utgangsstrømmen.

4. Tilpasset markørgrensesnitt

La oss lage vårt eget markørgrensesnitt.

For eksempel kan vi lage en markør som indikerer om et objekt kan fjernes fra databasen:

offentlig grensesnitt slettbart {}

For å slette en enhet fra databasen, må objektet som representerer denne enheten implementere vår Slettbar markørgrensesnitt:

public class Entity implementes Deletable {// implementeringsdetaljer}

La oss si at vi har et DAO-objekt med en metode for å fjerne enheter fra databasen. Vi kan skrive vår slett () metode slik at bare objekter som implementerer markørgrensesnittet vårt kan slettes:

public class ShapeDao {// andre dao-metoder public boolean delete (Object object) {if (! (object instanceof Deletable)) {return false; } // slett implementeringsdetaljer returner sant; }}

Som vi kan se, vi gir en indikasjon til JVM, om kjøretidsoppførselen til objektene våre. Hvis objektet implementerer markørgrensesnittet vårt, kan det slettes fra databasen.

5. Markørgrensesnitt mot merknader

Ved å introdusere kommentarer, har Java gitt oss et alternativ for å oppnå de samme resultatene som markørgrensesnittene. Dessuten, som markørgrensesnitt, kan vi bruke merknader til hvilken som helst klasse, og vi kan bruke dem som indikatorer for å utføre visse handlinger.

Så hva er nøkkelforskjellen?

I motsetning til merknader tillater grensesnitt oss det dra nytte av polymorfisme. Som et resultat kan vi legge til ytterligere begrensninger i markørgrensesnittet.

La oss for eksempel legge til en begrensning som bare a Form type kan fjernes fra databasen:

offentlig grensesnitt Form {dobbel getArea (); dobbel getCircumference (); }

I dette tilfellet, markørgrensesnittet vårt, la oss kalle det Slettbar form, vil se slik ut:

offentlig grensesnitt DeletableShape utvider Shape {}

Da vil klassen vår implementere markørgrensesnittet:

public class Rectangle implementerer DeletableShape {// implementeringsdetaljer}

Derfor, alle Slettbar form implementeringer er også Form implementeringer. Åpenbart, vi kan ikke gjøre det ved å bruke merknader.

Imidlertid har hver designbeslutning avveininger og polymorfisme kan brukes som et motargument mot markørgrensesnitt. I vårt eksempel, hver klasse som strekker seg Rektangel implementeres automatisk Slettbar form.

6. Markørgrensesnitt mot typiske grensesnitt

I det forrige eksemplet kunne vi få de samme resultatene ved å endre DAO-ene våre slett () metode for å teste om objektet vårt er en Form eller ikke, i stedet for å teste om det er en Slettbar:

public class ShapeDao {// andre dao-metoder public boolean delete (Object object) {if (! (object instanceof Shape)) {return false; } // slett implementeringsdetaljer returner sant; }}

Så hvorfor lage et markørgrensesnitt når vi kan oppnå de samme resultatene ved hjelp av et typisk grensesnitt?

La oss forestille oss at, i tillegg til Form type, vil vi fjerne Person skriv også fra databasen. I dette tilfellet er det to alternativer for å oppnå det:

Det første alternativet er for å legge til en ekstra sjekk til vår forrige slett () metode for å verifisere om objektet som skal slettes er en forekomst av Person eller ikke.

public boolean delete (Object object) {if (! (object instanceof Shape || object instance of Person)) {return false; } // slett implementeringsdetaljer returner sant; }

Men hva om vi har flere typer som vi også vil fjerne fra databasen? Åpenbart vil dette ikke være et godt alternativ fordi vi har det for å endre vår metode for hver nye type.

Det andre alternativet er å lagede Person skriv implementere Form grensesnitt, som fungerer som et markørgrensesnitt. Men er en Person objekt virkelig en Form? Svaret er tydeligvis nei, og det gjør det andre alternativet verre enn det første.

Derfor, selv om vi kan oppnå de samme resultatene ved å bruke et typisk grensesnitt som en markør, vi vil ende opp med en dårlig design.

7. Konklusjon

I denne artikkelen diskuterte vi hva markørgrensesnitt er og hvordan de kan brukes. Så så vi på noen innebygde Java-eksempler på denne typen grensesnitt og hvordan de brukes av JDK.

Deretter opprettet vi vårt eget markørgrensesnitt og veide det opp mot bruk av en kommentar. Til slutt ender vi med å se hvorfor det er en god praksis å bruke et markørgrensesnitt i noen scenarier i stedet for et tradisjonelt grensesnitt.

Som alltid kan koden bli funnet på GitHub.


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