Programmering

Observer and Observable

Her er problemet: Du designer et program som skal gjengi data som beskriver en tredimensjonal scene i to dimensjoner. Programmet må være modulært og må tillate flere, samtidige visninger av samme scene. Hver visning må kunne vise scenen fra et annet utsiktspunkt, under forskjellige lysforhold. Enda viktigere, hvis noen deler av den underliggende scenen endres, må visningene oppdateres.

Ingen av disse kravene gir en uoverstigelig utfordring i programmeringen. Hvis koden som håndterer hvert krav måtte skrives de novoimidlertid vil det legge betydelig arbeid til den totale innsatsen. Heldigvis er støtte for disse oppgavene allerede levert av Java-klassebiblioteket i form av grensesnitt Observatør og klasse Observerbar- både inspirert av kravene til MVC-arkitekturen.

Model / View / Controller (MVC) -arkitekturen

Model / View / Controller-arkitekturen ble introdusert som en del av Smalltalk, et populært objektorientert programmeringsspråk oppfunnet av Alan Kay. MVC ble designet for å redusere programmeringsinnsatsen som kreves for å bygge systemer som bruker flere, synkroniserte presentasjoner av de samme dataene. Dens sentrale egenskaper er at modellen, kontrollerne og visningene blir behandlet som separate enheter, og at endringer som er gjort i modellen, skal reflekteres automatisk i hver av visningene.

I tillegg til programeksemplet som er beskrevet i innledende avsnitt ovenfor, kan modell / visning / kontrollerarkitekturen brukes til prosjekter som følgende:

  • En grafpakke som inneholder samtidige søylediagram-, linjediagram- og sektordiagramvisninger av de samme dataene.
  • Et CAD-system, der deler av designet kan sees i forskjellige forstørrelser, i forskjellige vinduer og i forskjellige skalaer.

Figur 1 illustrerer MVC-arkitekturen i sin mest generelle form. Det er en modell. Flere kontrollere manipulerer modellen; flere visninger viser dataene i modellen, og endres når tilstanden til modellen endres.

Figur 1. Model / View / Controller-arkitekturen

Fordeler med MVC

Model / View / Controller-arkitekturen har flere fordeler:

  • Det er en tydelig definert skille mellom komponenter i et program - problemer i hvert domene kan løses uavhengig.
  • Det er en veldefinert API - alt som bruker APIen riktig kan erstatte enten modellen, visningen eller kontrolleren.
  • Bindingen mellom modellen og visningen er dynamisk - den skjer på kjøretid, i stedet for på kompileringstid.

Ved å innlemme MVC-arkitekturen i et design, kan deler av et program utformes separat (og utformes for å gjøre jobben sin bra) og deretter bundet sammen på kjøretid. Hvis en komponent senere anses å være uegnet, kan den byttes ut uten å påvirke de andre delene. Kontrast dette scenariet med den monolitiske tilnærmingen som er typisk for mange raske og skitne Java-programmer. Ofte inneholder en ramme hele staten, håndterer alle hendelser, gjør alle beregningene og viser resultatet. I alle, men de enkleste av slike systemer, er det ikke trivielt å gjøre endringer etter hvert.

Definere delene

Modellen er objektet som representerer dataene i programmet. Den administrerer dataene og gjennomfører alle transformasjoner av disse dataene. Modellen har ingen spesifikk kunnskap om verken kontrollere eller synspunkter - den inneholder ingen interne referanser til noen av dem. Snarere systemet påtar seg ansvaret for å opprettholde koblinger mellom modellen og dens synspunkter og varsle synspunktene når modellen endres.

Utsikten er objektet som styrer den visuelle visningen av dataene representert av modellen. Den produserer den visuelle representasjonen av modellobjektet og viser dataene til brukeren. Den samhandler med modellen via en referanse til selve modellobjektet.

Kontrolleren er objektet som gir midler for brukerinteraksjon med dataene representert av modellen. Den gir de måtene endringene gjøres på, enten i informasjonen i modellen eller i utseendet til visningen. Den samhandler med modellen via en referanse til selve modellobjektet.

På dette punktet kan et konkret eksempel være nyttig. Tenk som et eksempel på systemet som er beskrevet i innledningen.

Figur 2. Tredimensjonalt visualiseringssystem

Den sentrale delen av systemet er modellen for den tredimensjonale scenen. Modellen er en matematisk beskrivelse av toppunktene og ansiktene som utgjør scenen. Dataene som beskriver hvert toppunkt eller ansikt kan modifiseres (kanskje som et resultat av brukerinngang eller en scene forvrengning eller morphing algoritme). Imidlertid er det ingen forestilling om synspunkt, visningsmetode (trådramme eller solid), perspektiv eller lyskilde. Modellen er en ren representasjon av elementene som utgjør scenen.

Den delen av programmet som forvandler dataene i modellen til et grafisk display, er visningen. Visningen legemliggjør den faktiske visningen av scenen. Det er den grafiske fremstillingen av scenen fra et bestemt synspunkt, under spesielle lysforhold.

Kontrolleren vet hva som kan gjøres med modellen, og implementerer brukergrensesnittet som gjør det mulig å iverksette denne handlingen. I dette eksemplet kan et kontrollpanel for datainnføring tillate brukeren å legge til, endre eller slette hjørner og ansikter.

Observer and Observable

Java-språket støtter MVC-arkitekturen med to klasser:

  • Observatør: Ethvert objekt som ønsker å bli varslet når tilstanden til et annet objekt endres.
  • Observerbar: Ethvert objekt hvis tilstand kan være av interesse, og som et annet objekt kan registrere en interesse for.

Disse to klassene kan brukes til å implementere mye mer enn bare MVC-arkitekturen. De er egnet for ethvert system der objekter må varsles automatisk om endringer som forekommer i andre objekter.

Vanligvis er modellen en undertype av Observerbar og utsikten er en undertype av Observatør. Disse to klassene håndterer MVCs automatiske varslingsfunksjon. De gir mekanismen der visningene automatisk kan varsles om endringer i modellen. Objektreferanser til modellen i både kontrolleren og visningen gir tilgang til data i modellen.

Observer og Observable-funksjoner

Følgende er kodelister for observatøren og observerbare funksjoner:

Observatør

  • offentlig ugyldig oppdatering (Observable obs, Object obj)

    Kalt når det har skjedd en endring i den observerbare tilstanden.

Observerbar

  • public void addObserver (Observer obs)

    Legger til en observatør på den interne listen over observatører.

  • public void deleteObserver (Observer obs)

    Sletter en observatør fra den interne listen over observatører.

  • offentlig ugyldig deleteObservers ()

    Sletter alle observatører fra den interne listen over observatører.

  • public int countObservers ()

    Returnerer antall observatører i den interne listen over observatører.

  • beskyttet tomrom settChanged ()

    Angir det interne flagget som indikerer at denne observerbare har endret tilstand.

  • beskyttet tomrom clearChanged ()

    Tømmer det indre flagget som indikerer at dette observerbare har endret tilstand.

  • offentlig boolsk hasChanged ()

    Returnerer den boolske verdien true hvis denne observerbare har endret tilstand.

  • offentlig ugyldig notifyObservers ()

    Kontrollerer det interne flagget for å se om det observerbare har endret tilstand og varsler alle observatører.

  • public void notifyObservers (Object obj)

    Kontrollerer det interne flagget for å se om det observerbare har endret tilstand og varsler alle observatører. Passer objektet som er spesifisert i parameterlisten til gi beskjed() metoden til observatøren.

Deretter tar vi en titt på hvordan du lager en ny Observerbar og Observatør klasse, og hvordan man knytter de to sammen.

Utvid en observerbar

En ny klasse med observerbare objekter opprettes ved å utvide klassen Observerbar. Fordi klasse Observerbar allerede implementerer alle metodene som er nødvendige for å gi ønsket oppførsel, trenger den avledede klassen bare å gi noen mekanisme for å justere og få tilgang til den interne tilstanden til det observerbare objektet.

I ObservableValue nedenfor, blir den interne tilstanden til modellen fanget av heltallet n. Denne verdien er kun tilgjengelig (og, enda viktigere, modifisert) gjennom offentlige tilgangere. Hvis verdien endres, påkaller det observerbare objektet sin egen setChanged () metode for å indikere at tilstanden til modellen har endret seg. Den påkaller seg deretter sin egen notifyObservers () metode for å oppdatere alle registrerte observatører.

Oppføring 1. ObservableValue

 importere java.util.Observable; offentlig klasse ObservableValue strekker Observable {private int n = 0; public ObservableValue (int n) {this.n = n; } public void setValue (int n) {this.n = n; setChanged (); notifyObservers (); } public int getValue () {return n; }} 

Implementere en observatør

En ny klasse av objekter som observerer endringene i tilstanden til et annet objekt, opprettes ved å implementere Observatør grensesnitt. De Observatør grensesnitt krever at en Oppdater() metode blir gitt i den nye klassen. De Oppdater() metoden kalles når den observerbare endrer tilstand og kunngjør dette ved å kalle sin notifyObservers () metode. Observatøren bør deretter forhøre det observerbare objektet for å bestemme dets nye tilstand, og i tilfelle MVC-arkitekturen, justere synet riktig.

I følgende TextObserver oppføring, den gi beskjed() metoden sjekker først for å sikre at den observerbare som har kunngjort en oppdatering er den observerbare som denne observatøren observerer. Hvis den er, leser den den observerbare tilstanden og skriver ut den nye verdien.

Oppføring 2. TextObserver

 importere java.util.Observer; importere java.util.Observable; offentlig klasse TextObserver implementerer Observer {private ObservableValue ov = null; offentlig TextObserver (ObservableValue ov) {this.ov = ov; } offentlig ugyldig oppdatering (Observable obs, Object obj) {if (obs == ov) {System.out.println (ov.getValue ()); }}} 

Knyt de to sammen

Et program varsler et observerbart objekt som en observatør ønsker å bli varslet om endringer i dets tilstand ved å ringe det observerbare objektet addObserver () metode. De addObserver () metoden legger observatøren til den interne listen over observatører som bør varsles hvis tilstanden til det observerbare endres.

Eksemplet nedenfor viser klasse Main og demonstrerer hvordan du bruker addObserver () metoden for å legge til en forekomst av TextObserver klasse (oppføring 2) til den observerbare listen som vedlikeholdes av ObservableValue klasse (oppføring 1).

Oppføring 3. addObserver ()

 public class Main {public Main () {ObservableValue ov = new ObservableValue (0); TextObserver til = ny TextObserver (ov); ov.addObserver (til); } public static void main (String [] args) {Main m = new Main (); }} 

Hvordan det hele fungerer sammen

Den følgende hendelsesforløpet beskriver hvordan samspillet mellom en observerbar og en observatør vanligvis forekommer i et program.

  1. Først manipulerer brukeren en brukergrensesnittkomponent som representerer en kontroller. Kontrolleren gjør en endring av modellen via en offentlig tilgangsmetode - som er setValue () i eksemplet ovenfor.
  2. Den offentlige tilgangsmetoden endrer private data, justerer modellens interne tilstand og kaller den setChanged () metode for å indikere at tilstanden har endret seg. Det kaller da notifyObservers () å varsle observatørene om at det har endret seg. Oppfordringen til notifyObservers () kan også utføres andre steder, for eksempel i en oppdateringsløkke som kjører i en annen tråd.
  3. De Oppdater() metoder på hver av observatørene kalles, noe som indikerer at en endring i tilstanden har skjedd. Observatørene får tilgang til modellens data via modellens offentlige tilgangsmetoder og oppdaterer deres respektive synspunkter.

Observer / Observable in a MVC architecture

La oss nå vurdere et eksempel som viser hvordan observerbare og observatører vanligvis fungerer sammen i en MVC-arkitektur. Som modellen i ObservableValue (Oppføring 1) modellen i dette eksemplet er veldig enkel. Den interne tilstanden består av et enkelt heltall. Staten manipuleres utelukkende via tilgangsmetoder som de i ObservableValue. Koden for modellen finnes her.

Opprinnelig ble det skrevet en enkel tekstvisning / kontrollerklasse. Klassen kombinerer funksjonene i både en visning (den viser verdien av modellens nåværende tilstand) og en kontroller (den lar brukeren angi en ny verdi for tilstanden til modellen). Koden finnes her.

Ved å designe systemet ved hjelp av MVC-arkitekturen (i stedet for å legge inn koden for modellen, visningen og tekstkontrolleren i en monolitisk klasse), blir systemet enkelt redesignet for å håndtere en annen visning og en annen kontroller. I dette tilfellet ble det skrevet en skyvevisning / kontrollerklasse. Posisjonen til glidebryteren representerer verdien av modellens nåværende tilstand og kan justeres av brukeren for å angi en ny verdi for tilstanden til modellen. Koden finnes her.

Om forfatteren

Todd Sundsted har skrevet programmer siden datamaskiner ble tilgjengelige i stasjonære modeller. Selv om han opprinnelig var interessert i å bygge distribuerte objektapplikasjoner i C ++, flyttet Todd til Java-programmeringsspråket da Java ble det åpenbare valget for den slags ting.

Denne historien, "Observer and Observable" ble opprinnelig utgitt av JavaWorld.

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