Programavimas

Stebėtojas ir stebimas

Štai problema: jūs kuriate programą, kuri perteiks duomenis, apibūdinančius trimatę sceną dviem aspektais. Programa turi būti modulinė ir leisti leisti vienu metu žiūrėti tą pačią sceną. Kiekvienas vaizdas turi turėti galimybę parodyti sceną iš kito apžvalgos taško, esant skirtingoms apšvietimo sąlygoms. Dar svarbiau, jei pasikeičia kuri nors pagrindinės scenos dalis, rodiniai turi būti atnaujinti patys.

Nė vienas iš šių reikalavimų nekelia neįveikiamo programavimo iššūkio. Jei reikėjo parašyti kodą, kuris tvarko kiekvieną reikalavimą de novotačiau tai pridėtų daug darbo prie visų pastangų. Laimei, palaikymą šioms užduotims jau teikia „Java“ klasės biblioteka sąsajos forma Stebėtojas ir klasė Stebimas- tiek iš dalies įkvėpė MVC architektūros reikalavimai.

Model / View / Controller (MVC) architektūra

Model / View / Controller architektūra buvo pristatyta kaip „Smalltalk“, populiarios į objektus orientuotos programavimo kalbos, kurią išrado Alanas Kay, dalis. MVC buvo sukurtas siekiant sumažinti programavimo pastangas, reikalingas kuriant sistemas, naudojant kelis, sinchronizuotus tų pačių duomenų pateikimus. Pagrindinės jo ypatybės yra tai, kad modelis, valdikliai ir peržiūros yra traktuojami kaip atskiri subjektai ir kad modelio pakeitimai turėtų automatiškai atsispindėti kiekvienoje nuomonėje.

Be programos pavyzdžio, aprašyto ankstesnėje pastraipoje, „Model / View / Controller“ architektūra gali būti naudojama tokiems projektams kaip:

  • Grafikų paketas, kuriame yra tų pačių duomenų juostos diagramos, linijinės diagramos ir skritulinės diagramos rodiniai vienu metu.
  • CAD sistema, kurioje dizaino dalys gali būti matomos skirtingais didinimais, skirtinguose languose ir skirtingais masteliais.

1 paveiksle pavaizduota MVC architektūra jos bendra forma. Yra vienas modelis. Keli valdikliai manipuliuoja modeliu; keli rodiniai rodo modelio duomenis ir keičiasi keičiantis modelio būsenai.

1 paveikslas. Model / View / Controller architektūra

MVC nauda

Model / View / Controller architektūra turi keletą privalumų:

  • Programos komponentai yra aiškiai apibrėžti - kiekvienos srities problemos gali būti sprendžiamos savarankiškai.
  • Yra gerai apibrėžta API - viskas, kas tinkamai naudoja API, gali pakeisti modelį, vaizdą arba valdiklį.
  • Ryšys tarp modelio ir vaizdo yra dinamiškas - jis vyksta veikimo metu, o ne kompiliavimo metu.

Įtraukiant MVC architektūrą į dizainą, programos dalys gali būti suprojektuotos atskirai (ir suprojektuotos taip, kad gerai atliktų savo darbą) ir tada būtų sujungtos vykdymo metu. Jei vėliau komponentas laikomas netinkamu, jį galima pakeisti nepažeidžiant kitų dalių. Palyginkite šį scenarijų su monolitiniu požiūriu, būdingu daugeliui greitai ir nešvariai dirbančių „Java“ programų. Dažnai rėmelyje yra visa būsena, tvarkomi visi įvykiai, atliekami visi skaičiavimai ir rodomas rezultatas. Taigi visose, išskyrus paprasčiausią, tokiose sistemose pakeitimų atlikimas nėra faktas.

Dalių apibrėžimas

Modelis yra objektas, kuris rodo programos duomenis. Jis tvarko duomenis ir vykdo visas tų duomenų transformacijas. Modelis neturi jokių specialių žinių nei apie valdytojus, nei apie savo požiūrį - jame nėra jokių vidinių nuorodų į abu. Atvirkščiai, pati sistema prisiima atsakomybę palaikyti ryšius tarp modelio ir jo nuomonių ir pranešti apie nuomonę pasikeitus modeliui.

Vaizdas yra objektas, kuris valdo modelio vaizduojamų duomenų vaizdinį vaizdą. Tai sukuria vizualų modelio objekto vaizdą ir rodo duomenis vartotojui. Jis sąveikauja su modeliu per nuorodą į patį modelio objektą.

Valdiklis yra objektas, suteikiantis vartotojo sąveikos su modelio atstovais duomenis. Jame pateikiamos priemonės, kuriomis atliekami modelyje esančios informacijos ar vaizdo išvaizdos pakeitimai. Jis sąveikauja su modeliu, pateikdamas nuorodą į patį modelio objektą.

Šiuo metu gali būti naudingas konkretus pavyzdys. Panagrinėkime pavyzdį įvade aprašytą sistemą.

2 paveikslas. Trimatė vizualizavimo sistema

Centrinė sistemos dalis yra erdvinės scenos modelis. Modelis yra matematinis viršūnių ir veidų, sudarančių sceną, aprašymas. Duomenys, apibūdinantys kiekvieną viršūnę ar veidą, gali būti modifikuojami (galbūt dėl ​​vartotojo įvesties, scenos iškraipymo ar morfijos algoritmo). Tačiau nėra požiūrio, vaizdavimo metodo (vielinio rėmo ar vientiso), perspektyvos ar šviesos šaltinio sąvokos. Modelis yra grynas scenos elementų vaizdavimas.

Programos dalis, transformuojanti modelio duomenis į grafinį vaizdą, yra rodinys. Vaizdas įkūnija tikrąjį scenos vaizdą. Tai grafinis scenos vaizdas tam tikru požiūriu, esant tam tikroms apšvietimo sąlygoms.

Valdiklis žino, ką galima padaryti modeliui, ir įdiegia vartotojo sąsają, leidžiančią pradėti tą veiksmą. Šiame pavyzdyje duomenų įvedimo valdymo skydelis gali leisti vartotojui pridėti, modifikuoti ar ištrinti viršūnes ir veidus.

Stebėtojas ir stebimas

„Java“ kalba palaiko MVC architektūrą dviem klasėmis:

  • Stebėtojas: Bet koks objektas, apie kurį norima pranešti pasikeitus kito objekto būsenai.
  • Stebimas: Bet koks objektas, kurio būsena gali būti įdomi ir kurį kitas objektas gali registruoti.

Šios dvi klasės gali būti naudojamos kur kas daugiau nei tik MVC architektūrai įgyvendinti. Jie tinka bet kuriai sistemai, kurioje objektams reikia automatiškai pranešti apie kitų objektų pokyčius.

Paprastai modelis yra Stebimas vaizdas yra potipis Stebėtojas. Šios dvi klasės valdo MVC automatinio pranešimo funkciją. Jie suteikia mechanizmą, pagal kurį nuomonėms galima automatiškai pranešti apie modelio pokyčius. Objekto nuorodos į modelį tiek valdiklyje, tiek rodinyje leidžia pasiekti modelio duomenis.

Stebėtojo ir stebimos funkcijos

Toliau pateikiami stebėtojo kodai ir stebimos funkcijos:

Stebėtojas

  • viešas niekinis atnaujinimas (Stebimas obs, Object obj)

    Skambinama, kai įvyko stebimos būklės pasikeitimas.

Stebimas

  • public void addObserver (Observer obs)

    Stebėtojas įtraukiamas į vidinį stebėtojų sąrašą.

  • public void deleteObserver (Observer obs)

    Ištrina stebėtoją iš vidinio stebėtojų sąrašo.

  • viešas negaliojantis ištrinti stebėtojai ()

    Ištrina visus stebėtojus iš vidinio stebėtojų sąrašo.

  • Visuomenės vid. stebėtojai ()

    Pateikia stebėtojų skaičių vidiniame stebėtojų sąraše.

  • apsaugotas negaliojantis setChanged ()

    Nustato vidinę vėliavą, rodančią, kad ši stebima būsena pasikeitė.

  • apsaugotas negaliojantis clearChanged ()

    Išvalo vidinę vėliavą, kuri rodo, kad ši stebima padėtis pasikeitė.

  • viešoji loginė reikšmė hasChanged ()

    Grąžina loginę reikšmę, jei ši stebima būsena pasikeitė.

  • viešas niekinis pranešimas Stebėtojai ()

    Patikrina vidinę vėliavą, ar stebima, ar pasikeitė būsena, ir praneša apie tai visiems stebėtojams.

  • viešas niekinis pranešimas Stebėtojai (objekto objektas)

    Patikrina vidinę vėliavą, ar stebima, ar pasikeitė būsena, ir praneša apie tai visiems stebėtojams. Perduoda parametrų sąraše nurodytą objektą pranešti () stebėtojo metodas.

Toliau mes apžvelgsime, kaip sukurti naują Stebimas ir Stebėtojas klasę ir kaip susieti abu.

Išplėskite stebimą

Pratęsus klasę, sukuriama nauja stebimų objektų klasė Stebimas. Nes klasė Stebimas jau įgyvendina visus metodus, būtinus norimam elgesiui užtikrinti, išvestinė klasė turi pateikti tik tam tikrą mechanizmą, skirtą stebėti ir pasiekti stebimo objekto vidinę būseną.

Viduje konors ObservableValue Žemiau pateikiant modelio vidinę būseną, užfiksuojamas sveikasis skaičius n. Prie šios vertės galima patekti (ir, dar svarbiau, modifikuoti), tik per viešus prieigą. Jei vertė yra pakeista, stebimas objektas iškviečia savo setChanged () metodas, nurodantis, kad pasikeitė modelio būsena. Tada jis remiasi savaisiais pranešti stebėtojams () metodas, siekiant atnaujinti visus registruotus stebėtojus.

Sąrašas 1. ObservableValue

 importuoti java.util.Pastebima; viešoji klasė „ObservableValue“ tęsiasi Stebima {private int n = 0; public ObservableValue (int n) {this.n = n; } public void setValue (int n) {this.n = n; setChanged (); pranešti Stebėtojai (); } public int getValue () {return n; }} 

Įdiegti stebėtoją

Įdiegus programą sukuriama nauja objektų klasė, stebinti kito objekto būsenos pokyčius Stebėtojas sąsaja. Stebėtojas sąsaja reikalauja, kad atnaujinti () metodas bus pateiktas naujoje klasėje. atnaujinti () metodas yra iškviečiamas, kai pastebimi pokyčiai, ir paskelbia šį faktą paskambindamas pranešti stebėtojams () metodas. Tada stebėtojas turėtų apklausti stebimą objektą, kad nustatytų jo naują būseną, o MVC architektūros atveju - tinkamai pakoreguoti savo vaizdą.

Toliau „TextObserver“ sąrašas pranešti () metodas pirmiausia patikrina, ar stebėtojas, paskelbęs atnaujinimą, yra stebimas, kurį stebi šis stebėtojas. Jei taip, jis nuskaito stebimo būseną ir išspausdina naują vertę.

Sąrašas 2. „TextObserver“

 importuoti java.util.Observer; importuoti java.util.Pastebima; viešoji klasė „TextObserver“ įgyvendina stebėtoją {privatų stebimą vertę ov = null; public TextObserver (ObservableValue ov) {this.ov = ov; } public void update (Stebimas obs, Object obj) {if (obs == ov) {System.out.println (ov.getValue ()); }}} 

Suri abu

Programa praneša stebimam objektui, kad stebėtojas nori būti informuotas apie savo būsenos pasikeitimus, paskambindamas stebimam objektui addObserver () metodas. addObserver () metodas įtraukia stebėtoją į vidinį stebėtojų sąrašą, apie kurį turėtų būti pranešta, jei stebimos būklės pokyčiai.

Toliau pateiktame pavyzdyje, kuriame rodoma „Main“ klasė, parodoma, kaip naudotis addObserver () metodas pridėti „TextObserver“ klasė (2 sąrašas) į stebimą sąrašą, kurį tvarko ObservableValue klasė (1 sąrašas).

3. sąrašas „addObserver“ ()

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

Kaip visa tai veikia kartu

Ši įvykių seka apibūdina, kaip paprastai stebima ir stebima sąveika programoje.

  1. Pirmiausia vartotojas valdo vartotojo sąsajos komponentą, vaizduojantį valdiklį. Valdiklis keičia modelį naudodamas viešojo prieigos metodą, kuris yra setValue () aukščiau pateiktame pavyzdyje.
  2. Viešojo prieigos metodas modifikuoja privačius duomenis, koreguoja vidinę modelio būseną ir iškviečia juos setChanged () metodas, rodantis, kad pasikeitė jo būsena. Tada paskambina pranešti stebėtojams () pranešti stebėtojams, kad tai pasikeitė. Kvietimas pranešti stebėtojams () taip pat galėtų būti atliekama kitur, pavyzdžiui, atnaujinimo cikle, einančiame kitoje gijoje.
  3. atnaujinti () kviečiami kiekvieno stebėtojo metodai, rodantys, kad pasikeitė būklė. Stebėtojai prieina modelio duomenis naudodamiesi viešojo modelio metodais ir atnaujina savo nuomonę.

Stebėtojas / stebimas MVC architektūroje

Dabar apsvarstykime pavyzdį, parodantį, kaip stebimieji ir stebėtojai paprastai dirba kartu MVC architektūroje. Kaip modelis ObservableValue (1 sąrašas) šio pavyzdžio modelis yra labai paprastas. Jo vidinę būseną sudaro viena sveikojo skaičiaus reikšmė. Valstybė yra manipuliuojama išimtinai per prieigos metodus, tokius kaip ObservableValue. Modelio kodą rasite čia.

Iš pradžių buvo parašyta paprasta teksto peržiūra / valdiklio klasė. Klasė sujungia tiek rodinio (tekstiniu būdu parodo esamos modelio būsenos vertę), tiek valdiklio (jis leidžia vartotojui įvesti naują modelio būsenos vertę) ypatybes. Kodas yra čia.

Projektuojant sistemą naudojant MVC architektūrą (o ne įterpiant modelio, rodinio ir teksto valdiklio kodą į vieną monolitinę klasę), sistema lengvai pertvarkoma, kad būtų galima tvarkyti kitą vaizdą ir kitą valdiklį. Šiuo atveju buvo parašyta slankiklio rodinio / valdiklio klasė. Slankiklio padėtis atspindi dabartinės modelio būsenos vertę, ir vartotojas gali ją koreguoti, kad nustatytų naują modelio būsenos vertę. Kodas yra čia.

Apie autorių

Toddas Sundstedas rašė programas nuo tada, kai kompiuteriai tapo prieinami darbalaukio modeliuose. Nors Toddas iš pradžių domėjosi paskirstytų objektų programų kūrimu C ++, Toddas persikėlė į „Java“ programavimo kalbą, kai „Java“ tapo akivaizdžiu pasirinkimu tokiems dalykams.

Šią istoriją „Stebėtojas ir stebimas“ iš pradžių išleido „JavaWorld“.