2

Kuigi Java põhitõdesid ja mitmeid OO patterned olen õppinud, jääb siiani alati "müstikaks", kuidas Swing kasutades võimalikult hästi eraldada GUI pool ja äriloogika - iga kord kui seda teen, on tunne et olen järjekordse paraja häkiga hakkama saanud.

Kõige lihtsam on ilmselt GUId luues anda talle minig Model kaasa ja iga nupu kliki korral teeb GUI vastavalt model.buttonClicked(). Mis aga siis teha, kui Model tahab GUId muuta - annan modelit luues talle GUI viite kaasa ja lisan GUI klassi vastavad meetodid?

Asjaga on ilmselt mingil määral seotud Observer või Command pattern? Kuskilt ei ole ka leidnud asjalikku seletust, kuna enamik tutoriale seletab et Swing ei ole MVC ja et on ka, kuid head ja ühest näidet on raske leida.

Ilmselt lihtne koodinäide seletaks asja kõige paremini...?

flag

4 Answers

6

Kahjuks, ei saa teps mitte nõustuda Egoni definitsiooniga.

MVC on muidugi üks segane värk ja veebist võib leida palju erinevaid definitsioone, aga minu meelest on kõige selle juures peamine vastutuse eraldamise printsiip, mis taandub sellele, et programmi sisemine loogika ning esitlusloogika peaksid olema üksteisest eraldatud.

MVC antinäide oleks klassikaline PHP segapudru, kus läbisegi andmebaasipäringutega pritsitakse välja HTML-i ja töödeldakse sisendparameetreid.

Heaks stiiliks oleks aga kõik need kolm loogikat lahus hoida. Just nimelt loogikad:

  • Mudel kannab endas rakenduse põhiloogikat (öeldakse ka "äriloogikat", aga see on eksitav termin, sest see ei pea olema sugugi seotud mingigi äriga). Näiteks kalkulaatori puhul on just Mudel see kes teab kuidas arvutusi teha. Ehk nagu nimigi ütleb - ta modelleerib selle domeeni loogikat, milles rakendus tegutseb (olgu selleks domeeniks siis matemaatikatehted või kasside kasvatamine).

  • Vaade kannab endas esitlusloogikat, ehk kuidas rakendus ekraanil välja näeb. Vaade võib olla lihtne HTML template, kus lihtsalt muutujad ära asendakse. Aga see võib sisaldada ka keerukaid algoritme joonistamaks ekraanile animeeritud 3D objekte.

  • Kontroller tegeleb aga kasutajalt saadud sisenditega: teksti sisestamine, hiire liikumine, serverisse saadetavad HTTP päringud. Kontroller interpreteerib saadud sisendeid ning käsutab nende põhjal mudelit. Näiteks kui kasutaja vajutab kalkulaatori "+" nuppu kutsub kontroller välja mudeli liitmise meetodi, mis teostab liitmise ja teavitab omakorda vaadet, et see näiteks saadud tulemust.

MVC ei pea aga olema midagi hiiglaslikku, mis hõlmab enda all kogu rakendust, nagu ehk ülalkirjeldatust võib välja lugeda. Ka rakenduse pisikised komponendid võivad endas sisaldada pisikesi MVC-sid. Näiteks see Egoni poolt välja toodud JTable.

Samuti ei tasu arvata, et MVC põhimõtete järgimiseks on oluline kõigi kolme osa range eraldamine. Näiteks mingi lihtsa käsurea programmi puhul võib kogu vaate moodustada paar printf-i - oleks tobe neid kuidagi ära abstraheerida. Samas kui programmi sisendparameetrite töötlus oleks hea eraldada muust loogikast. Lihtsate GUI-de puhul võib jällegi ära kaduda kontroller - lihtsam on siduda vaade otse mudeliga, näiteks sidudes vormi nupu mudeli mingi meetodiga.

Nagu ikka, peamine on mõtelda mida antud kontekstis kõige targem teha oleks.

link|flag
Leidsin MVC kalkulaatori leepoint.net/notes-java/GUI/structure/40mvc.html näiteks juurde... – egon Mar 5 at 9:01
See MVC kalkulaatori näide on suurepärane! Täpselt mida taga ajanud, JTable'i näide on ka hea aga võtab veidi kauem aega, et läbi närida. Tänud. – Indrek Mar 5 at 13:13
2

Kui jutt käib desktop rakendustest siis olenevalt olukorrast ma olen eelistanud Model-View-Presenter mustrit..Lihtsalt kogemusest et kui tuleb palju kasutajaliidese komponente versioniseerida, siis MVP päästab rohkem dubleerimisest kui MVC. Aga asi võib olla ka minus.

link|flag
1

Nagu Rene ja Tambet mainisid, ei ole see päris õige MVC seletus. See on rohkem segu midagi three-tierist ja MVC-st.


Kõige tähtsam siin juures aru saada, et kui palju sul eraldada on vaja, üks võimalus näiteks selleks:

  • Data ehk Andmed - tema ülesanne on tark olla ning öelda GUI-le kui ta on targemaks saanud.
  • View ehk GUI - tema ülesanne on Loogika eest ilus olla ning Loogikale edasi öelda, mida teha.
  • Model ehk Loogika - tema ülesanne on andmetega tööd teha.

Näiteks kalkulaator, kus on näha mitut viimast tulemust (mul ei ole mingit tahtmist javat kirjutada):

  • Model: elementaarne liitmine, korrutamine jne. samuti omab ühte model-t kus on kirjas viimased tulemused. Kui teeb mingi tehte, siis lisab selle model-sse.
  • Data: Lihtsalt istub. Kui midagi temas muutub siis ütleb GUI-le, et olen muutunud.
  • View: Laseb sisestada mingi numbri. Tehte vajutamisel ütleb Controllerile, et tee see tehe. Kui tuleb viga näitab viga. Kui model uueneb, uuendab enda pilti.

Muidu hea näide kuidas midagi sarnast toimib on JTable.

link|flag
Sarnaselt Rene'le paneksin ka mina tehted mudelisse, mitte kontrollerisse. – Tambet Matiisen Mar 4 at 22:02
1

Akadeemiliselt korrektne mudel on iseseisev tarkvara, mille kogu suhtlus on defineeritud läbi tema api ja liideste. Seega pole vahet, kas liidestad mudeli käsureaprogrammi, graafilise kasutajaliidese või mõne veebiteenusega. Lisaks võib api olla ka tööriistaks teistele arendajatele. Praktikas pole küll sellist tõupuhtust enamasti vaja. Kui mudel tahab omaalgatuslikult välismaailmale (nt. Swing GUI) sõnumeid saata, siis selleks võiks olle mudeli poolt defineeritud liides, millega kaudu mudel suhelda saab. Näiteks saab Swingi rakenduses luua klassi, mis antud liidest realiseerib ja siis selle klassi objekti mudelile saata. A'la "model.addListener(MyListener ls)", kus "MyListener" realiseerib mudelis defineeritud "ModelListener" liidest. Sellesse objekti on siis kirjutatud juba antud kasutajaliidese jaoks vajalik loogika, mida mudel teadma ei pea.

link|flag

Your Answer

Get an OpenID
or

Not the answer you're looking for? Browse other questions tagged or ask your own question.