Programovanie

Pozorovateľ a pozorovateľ

Tu je problém: Navrhujete program, ktorý vykreslí údaje popisujúce trojrozmernú scénu v dvoch dimenziách. Program musí byť modulárny a musí umožňovať viacnásobné súčasné zobrazenie tej istej scény. Každý pohľad musí byť schopný zobraziť scénu z iného výhodného bodu za rôznych svetelných podmienok. Dôležitejšie je, že ak sa zmení ktorákoľvek časť základnej scény, zobrazenia sa musia aktualizovať samy.

Žiadna z týchto požiadaviek nepredstavuje neprekonateľnú programátorskú výzvu. Ak musel byť napísaný kód, ktorý vybavuje každú požiadavku de novo, avšak celkovému úsiliu by to pridalo značnú prácu. Podporu pre tieto úlohy našťastie už poskytuje knižnica tried Java v podobe rozhrania Pozorovateľ a triedy Pozorovateľné- obidve sú čiastočne inšpirované požiadavkami architektúry MVC.

Architektúra Model / View / Controller (MVC)

Architektúra Model / View / Controller bola predstavená ako súčasť Smalltalk, populárneho objektovo orientovaného programovacieho jazyka, ktorý vymyslel Alan Kay. Program MVC bol navrhnutý tak, aby znížil programovacie úsilie potrebné na vytvorenie systémov, ktoré využívajú viac synchronizovaných prezentácií rovnakých údajov. Jeho ústrednou charakteristikou je, že s modelom, radičmi a pohľadmi sa zaobchádza ako so samostatnými entitami a že zmeny vykonané v modeli by sa mali automaticky prejaviť v každom z pohľadov.

Okrem príkladu programu popísaného v úvodnom odseku vyššie sa môže architektúra Model / View / Controller použiť pre projekty, ako napríklad:

  • Balík grafov, ktorý obsahuje súčasné zobrazenie stĺpcových, čiarových a koláčových grafov na rovnaké údaje.
  • CAD systém, v ktorom je možné zobraziť časti vzoru pri rôznych zväčšeniach, v rôznych oknách a v rôznych mierkach.

Obrázok 1 zobrazuje architektúru MVC v jej najobecnejšej podobe. Existuje jeden model. S modelom manipuluje viac radičov; viacnásobné zobrazenia zobrazujú údaje v modeli a menia sa podľa zmeny stavu modelu.

Obrázok 1. Architektúra Model / View / Controller

Výhody MVC

Architektúra Model / View / Controller má niekoľko výhod:

  • Medzi komponentmi programu existuje jasne definované oddelenie - problémy v každej doméne je možné vyriešiť nezávisle.
  • Existuje dobre definované API - čokoľvek, čo správne používa API, môže nahradiť buď model, pohľad, alebo radič.
  • Väzba medzi modelom a pohľadom je dynamická - vyskytuje sa skôr za behu, ako za kompilácie.

Začlenením architektúry MVC do dizajnu možno časti programu navrhnúť osobitne (a navrhnúť ich tak, aby vykonávali svoju prácu dobre) a potom sa za behu spojiť. Ak sa komponent neskôr považuje za nevhodný, je možné ho vymeniť bez ovplyvnenia ostatných častí. Porovnajte tento scenár s monolitickým prístupom typickým pre mnoho rýchlych a špinavých programov Java. Rámec často obsahuje celý stav, spracováva všetky udalosti, robí všetky výpočty a zobrazuje výsledok. Takže vo všetkých takýchto systémoch okrem tých najjednoduchších nie je uskutočňovanie zmien potom triviálne.

Definovanie častí

Model je objekt, ktorý predstavuje údaje v programe. Spravuje údaje a vykonáva všetky transformácie týchto údajov. Model nemá konkrétne znalosti ani o svojich radičoch, ani o svojich názoroch - neobsahuje ani interné odkazy. Systém skôr preberá zodpovednosť za udržiavanie väzieb medzi modelom a jeho názormi a upozorňovanie pohľadov pri zmene modelu.

Výhľad je objekt, ktorý spravuje vizuálne zobrazenie údajov predstavovaných modelom. Produkuje vizuálne znázornenie modelového objektu a zobrazuje údaje používateľovi. Interaguje s modelom prostredníctvom odkazu na samotný objekt modelu.

Kontrolór je objekt, ktorý poskytuje prostriedky na interakciu používateľa s údajmi predstavovanými modelom. Poskytuje prostriedky, pomocou ktorých sa vykonávajú zmeny buď v informáciách v modeli, alebo vo vzhľade pohľadu. Interaguje s modelom prostredníctvom odkazu na samotný objekt modelu.

V tomto okamihu môže byť užitočný konkrétny príklad. Zoberme si ako príklad systém opísaný v úvode.

Obrázok 2. Trojrozmerný vizualizačný systém

Ústredným prvkom systému je model trojrozmernej scény. Model predstavuje matematický popis vrcholov a tvárí, ktoré tvoria scénu. Dáta popisujúce každý vrchol alebo tvár je možné upravovať (možno v dôsledku vstupu používateľa alebo algoritmu skreslenia alebo morfovania scény). Neexistuje však žiadna predstava o uhle pohľadu, metóde zobrazenia (drôtový alebo pevný), perspektíve alebo svetelnom zdroji. Model je čistým znázornením prvkov, ktoré tvoria scénu.

Časť programu, ktorá transformuje údaje v modeli na grafické zobrazenie, je pohľad. Pohľad stelesňuje skutočné zobrazenie scény. Je to grafické znázornenie scény z určitého pohľadu, za konkrétnych svetelných podmienok.

Kontrolór vie, čo sa dá s modelom urobiť, a implementuje užívateľské rozhranie, ktoré umožňuje iniciovať túto akciu. V tomto príklade môže ovládací panel na zadávanie údajov umožniť používateľovi pridávať, upravovať alebo odstraňovať vrcholy a tváre.

Pozorovateľ a pozorovateľ

Jazyk Java podporuje architektúru MVC dvoma triedami:

  • Pozorovateľ: Akýkoľvek objekt, ktorý si želá byť upozornený, keď sa zmení stav iného objektu.
  • Pozorovateľné: Akýkoľvek objekt, o ktorého stav môže byť záujem, a u ktorého môže zaregistrovať záujem iný objekt.

Tieto dve triedy možno použiť na implementáciu oveľa viac než len architektúry MVC. Sú vhodné pre akýkoľvek systém, kde je potrebné objekty automaticky upozorňovať na zmeny, ktoré sa vyskytujú v iných objektoch.

Typicky je model podtypom Pozorovateľné a pohľad je podtypom Pozorovateľ. Tieto dve triedy pracujú s funkciou automatického oznamovania MVC. Poskytujú mechanizmus, pomocou ktorého môžu byť pohľady automaticky informované o zmenách v modeli. Odkazy na objekt v modeli v radiči aj v pohľade umožňujú prístup k údajom v modeli.

Pozorovateľské a pozorovateľné funkcie

Nasleduje zoznam kódov pre pozorovateľa a pozorovateľné funkcie:

Pozorovateľ

  • aktualizácia verejnej neplatnosti (pozorovateľné obs, objekt obj)

    Volá sa, keď došlo k zmene stavu pozorovateľného.

Pozorovateľné

  • public void addObserver (Observer obs)

    Pridá pozorovateľa do interného zoznamu pozorovateľov.

  • public void deleteObserver (Observer obs)

    Vymaže pozorovateľa z interného zoznamu pozorovateľov.

  • public void deleteObservers ()

    Vymaže všetkých pozorovateľov z interného zoznamu pozorovateľov.

  • public int countObservers ()

    Vráti počet pozorovateľov z interného zoznamu pozorovateľov.

  • protected void setChanged ()

    Nastaví interný príznak, ktorý indikuje, že táto zmena bola viditeľná.

  • protected void clearChanged ()

    Vymaže vnútorný príznak, ktorý naznačuje, že je možné pozorovať, že sa zmenil stav.

  • public boolean hasChanged ()

    Vráti boolovskú hodnotu true, ak táto pozorovateľná zmenila stav.

  • public void notifyObservers ()

    Skontroluje vnútorný príznak, či bol pozorovateľný zmenený stav, a upozorní všetkých pozorovateľov.

  • public void notifyObservers (objekt obj)

    Skontroluje vnútorný príznak, či bol pozorovateľný zmenený stav, a upozorní všetkých pozorovateľov. Predá objekt uvedený v zozname parametrov upozorniť () metóda pozorovateľa.

Ďalej sa pozrieme na to, ako vytvoriť nový Pozorovateľné a Pozorovateľ triedy a ako ich spojiť.

Rozšírte pozorovateľné

Rozšírením triedy sa vytvorí nová trieda pozorovateľných objektov Pozorovateľné. Pretože trieda Pozorovateľné už implementuje všetky metódy potrebné na zabezpečenie požadovaného správania, odvodená trieda musí poskytnúť iba určitý mechanizmus na prispôsobenie a prístup k vnútornému stavu pozorovateľného objektu.

V ObservableValue zoznam uvedený nižšie, vnútorný stav modelu je zachytený celým číslom n. Táto hodnota je prístupná (a čo je dôležitejšie, modifikovaná) iba prostredníctvom verejných prístupových práv. Ak sa hodnota zmení, vyvolaný objekt si vyvolá svoju vlastnú setChanged () metóda označujúca, že sa zmenil stav modelu. Potom vyvolá svoje vlastné notifyObservers () aktualizovať všetkých registrovaných pozorovateľov.

Zoznam 1. ObservableValue

 import java.util.Observable; public class ObservableValue extends 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; }} 

Implementujte pozorovateľa

Nová trieda objektov, ktorá sleduje zmeny stavu iného objektu, sa vytvorí implementáciou Pozorovateľ rozhranie. The Pozorovateľ rozhranie vyžaduje, aby aktualizácia () v novej triede. The aktualizácia () metóda sa volá vždy, keď pozorovateľná zmení stav a oznámi túto skutočnosť volaním svojho notifyObservers () metóda. Pozorovateľ by mal potom vypočuť pozorovateľný objekt, aby určil jeho nový stav, a v prípade architektúry MVC primerane upraviť svoj pohľad.

V nasledujúcom TextovýObserver zoznam, upozorniť () metóda najskôr skontroluje, či pozorovateľ, ktorý ohlásil aktualizáciu, je pozorovateľný, ktorý tento pozorovateľ pozoruje. Ak je, potom načíta stav pozorovateľného a vytlačí novú hodnotu.

Výpis 2. TextObserver

 import java.util.Observer; import java.util.Observable; verejná trieda TextObserver implementuje Observer {private ObservableValue ov = null; public TextObserver (ObservableValue ov) {this.ov = ov; } public void update (Observable obs, Object obj) {if (obs == ov) {System.out.println (ov.getValue ()); }}} 

Zviažte ich k sebe

Program upozorní pozorovateľný objekt tým, že si želá byť informovaný o zmenách v jeho stave, tým, že zavolá pozorovateľný objekt addObserver () metóda. The addObserver () metóda pridáva pozorovateľa na interný zoznam pozorovateľov, ktorí by mali byť upozornení, ak sa stav pozorovateľných zmien zmení.

Nasledujúci príklad, ktorý ukazuje triedu Main, ukazuje, ako sa používa addObserver () metóda na pridanie inštancie súboru TextovýObserver triedy (zoznam 2) na pozorovateľný zoznam udržiavaný ObservableValue triedy (zoznam 1).

Zoznam 3. addObserver ()

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

Ako to všetko spolu funguje

Nasledujúca postupnosť udalostí popisuje, ako obvykle v rámci programu dochádza k interakcii medzi pozorovateľom a pozorovateľom.

  1. Najprv užívateľ manipuluje s komponentom užívateľského rozhrania predstavujúcim radič. Ovládač vykoná zmenu modelu pomocou verejnej metódy prístupu - čo je setValue () vo vyššie uvedenom príklade.
  2. Metóda verejného prístupu upravuje súkromné ​​údaje, upravuje interný stav modelu a volá ich setChanged () metóda naznačujúca, že sa jeho stav zmenil. Potom zavolá notifyObservers () oznámiť pozorovateľom, že sa zmenila. Výzva na notifyObservers () sa dajú vykonať aj inde, napríklad v aktualizačnej slučke bežiacej v inom vlákne.
  3. The aktualizácia () volajú sa metódy každého z pozorovateľov, čo naznačuje, že došlo k zmene stavu. Pozorovatelia pristupujú k údajom modelu pomocou metód verejného prístupu modelu a aktualizujú svoje príslušné zobrazenia.

Pozorovateľ / pozorovateľ v architektúre MVC

Teraz zvážme príklad demonštrujúci, ako pozorovateľní a pozorovatelia zvyčajne pracujú spoločne v architektúre MVC. Rovnako ako model v ObservableValue (Zoznam 1), model v tomto príklade je veľmi jednoduchý. Jeho vnútorný stav pozostáva z jednej celočíselnej hodnoty. So štátom sa manipuluje výlučne pomocou prístupových metód, ako sú tie v ObservableValue. Kód modelu sa nachádza tu.

Spočiatku bola napísaná jednoduchá trieda textového zobrazenia / radiča. Trieda kombinuje vlastnosti zobrazenia (textovo zobrazuje hodnotu aktuálneho stavu modelu) aj ovládača (umožňuje používateľovi zadať novú hodnotu pre stav modelu). Kód sa nachádza tu.

Navrhnutím systému pomocou architektúry MVC (namiesto vloženia kódu pre model, zobrazenie a textový radič do jednej monolitickej triedy) je možné systém ľahko prepracovať tak, aby spracovával iný pohľad a iný radič. V tomto prípade bola napísaná trieda posuvného zobrazenia / radiča. Poloha posúvača predstavuje hodnotu aktuálneho stavu modelu a môže ju používateľ upraviť tak, aby nastavovala novú hodnotu pre stav modelu. Kód sa nachádza tu.

O autorovi

Todd Sundsted píše programy od chvíle, keď boli počítače k ​​dispozícii v stolných modeloch. Aj keď sa Todd pôvodne zaujímal o budovanie aplikácií distribuovaných objektov v C ++, prešiel na programovací jazyk Java, keď sa Java stala jasnou voľbou pre tento druh vecí.

Tento príbeh „Pozorovateľ a pozorovateľ“ pôvodne publikoval server JavaWorld.

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