Praktikum 6. Refaktoreerimine. Maven.

Maven

Seni oleme kassasüsteemi projektiga seotud tegevusi (projekti ehitamine, pakendamine, käivitamine, testide käivitamine jne) teinud ehitussüsteemi Ant abil. Ant'i kõrval teine vähemalt sama populaarne ehitussüsteem on Maven, millega siinkohal ka natukene tutvume.

Ant on imperatiivset laadi ehitussüteem -- kõik käivitatavad tegevused (targetid) defineeritakse ühekaupa justkui pisikeste käskudest koosnevate meetoditena. Maven on seevastu pigem deklaratiivne ehitussüsteem ja seega juba põhimõtteliselt teistmoodi. Maven'is kirjeldab arendaja ära oma projekti üldise struktuuri ja sõltuvused, misjärel oskab Maven sisuliselt kõiki standardseid tegevusi teha "ise". Mida standardsema struktuuriga on projekt, seda vähem tuleb midagi üldse kirjeldada. Maven'i tegevusi nimetatakse goal-ideks (enam-vähem vastav Ant'i puhul target-itele). Mõned olulisemad Maveni sisse-ehitatud goal'id:

  • mvn package
  • mvn clean
  • mvn test
  • mvn exec:exec

Oluline on ka mõista, et Maven'i enda arhitektuur põhineb täielikult pluginitel. Maven'isse endasse ei ole standardseid käske jäigalt sisse ehitatud (nagu Ant'is on targetid <java>, <javac>, <jar> jne) vaid nad kõik paiknevad eraldi väikestes pluginites. Pluginid on küll tavaliselt ilma täiendava konfigureerimiseta koheselt kättesaadavad, kuid see teadmine teeb lihtsamaks erinevate Maveni tegevuste kohta info ja dokumentatsiooni otsimise. Ei maksa otsida ühtset API dokumentatsiooni nagu see oli olemas Ant'i puhul (Maveni puhul sellist asja ei eksisteeri!) -- tuleb leida vajaliku tegevuse jaoks sobiv Maveni plugin ning otsida üles selle konkreetse plugini dokumentatsioon.

Algselt oli Maveni üheks peamiseks trumbiks automaatne sõltuvuste-haldus (dependency management). Arendaja loetleb pom.xml-is üles oma projekti kõige otsesemad sõltuvused (jar-failid, mille vastu projekti kood on kirjutatud). Midagi muud tegema ei peagi: Maven oskab selle alusel kesksetest võrgu-repositooriumitest vajalikud sõltuvused alla tõmmata ja ära pakendada, hoolitsedes ka selle eest, et kõik versioonid oleksid õiged ja et lisatud saaksid ka omakorda sõltuvuste sõltuvused jne. Tänapäeval on ühel või teisel moel selline võimalus jõudnud kõikidesse ehitussüsteemidesse, k.a. Ant'i.

Esmalt on vajalik tõmmata ning installeerida Maven3 (äärmisel juhul Maven2, aga kindlasti mitte Maven 1.x):

  • Keskkonnamuutuja M2_HOME panna näitama kataloogi, kuhu Maveni lahti pakkisid
  • Lisada PATH keskkonnamuutujasse Maveni bin-kataloog.

Väga soovitatav on Eclipse'le lisada ka Maveni tuge pakkuv plugin m2e (vt viited).



ÜLESANDED KLASSIS

Ülesanne 1. Refaktoreerimine.

Selle ülesande juures kasutame antud näidisrakendust: refactoring-demoapp.zip. Rakenduses puudub ehitusskript -- importida see Eclipse'i ja käivitada läbi Eclipse'i.

Rakendus loeb juurkaustas olevatest .csv-formaadis failidest arstide ja patsientide andmed, loob andmete põhjal vastavad objektid ning prindib need konsooli välja. Rakenduse koodis on aga mitmeid nüansse, mis ei vasta hea koodi põhimõtetele, ennekõike koodi dublitseerimist. Refaktoreerige koodi nii, et see muutuks paremaks! (Vihje: saate kasutada nii ülemklassi loomist ja meetodite jagamist kui ka ühendamist).



Ülesanne 2. Maven näidisrakendus.

Aluseks võtta näidisrakendus: maven-demoapp.zip.

Ülesanded (muuta näidisrakenduse pom.xml-i):

  1. Muuta ehitatava jar-faili nimeks "demo-app.jar".
  2. Lisada ehitatava jar-faili manifesti viide main-meetodiga klassile.
  3. Lisada projektile sõltuvus JUnit.
  4. Tõsta java source ja target koodi versiooni 1.5-le.

Kui viimased kaks muudatust tehtud, peaks õnnestuma käivitada goale mvn package exec:exec ja mvn test.



ÜLESANDED KODUS

Ülesanne 1. Kassasüsteemi refaktoreerimine.

PurchaseInfoTableModel sisaldab List<SoldItem> (päritud klassist SalesSystemTableModel)ja Sale sisaldab Set<SoldItem>. Sellest dubleerimisest peaks lahti saama. Kõige mõistlikum on panna PurchaseInfoTableModel kasutama Sale objekti ridade saamiseks. Selleks eemaldada klassist SalesSystemTableModel väli List<T> rows ning muuta meetod public List<T> getTableRows abstraktseks, mille iga päriv klass ise implementeeriks.

Praegu toimub lao- kliendi- ja ajaloopaanide värskendamine andmete muutmise peale. Realiseerida loogika, kus neid andmeid värskendataks andmebaasist iga kord kui vastav paan aktiveeritakse.

Hea oleks kui objektmudeli kasutamine oleks uue ostu sooritamise korral umbes selline:

  • Kasutaja valib kliendi ja selle peale luuakse uus ost
    Client client = …
    Sale sale = new Sale(client);
  • Kasutaja valib toote, ja lisab selle ostule:
    StockItem stockItem = …
    // loob vajadusel sisemiselt SoldItem objekti ja lisab selle ostule või kasutab juba olemasolevat ja muudab lihtsalt kogust
    sale.addItem(stockItem);
  • Kasutaja sooritab ostu:
    sale.setSellingTime(new Date());
    Asendada senine meetod submitCurrentPurchase(List<SoldItem> goods, Client currentClient) uue meetodi vastu:
    salesDomainController.registerSale(sale);
    Kindlasti on vaja muuta ka StockItem’i kogust



Soovituslik tööde järjekord:

  • Unustada hetkeks kogu GUI ja teha korda vastavalt üleval olevale juhendile objektmudel.
  • Teha korda GUI. Alustada SaleSystemTableModel'ist, millest kaob väli rows. Seejärel muuta XxxTableModel'eid - PurchaseInfoTableModelist hakkab kasutama Sale objekti, StockTableModel peab oma ridu ise hoidma.
  • Lisada lao, kliendi ja ajaloo paanidele meetod refresh() sisu värskendamiseks. Tabeli read tuleb lugeda domeeni kontrolleriga andmebaasist ning kirjutada modelisse. Refresh meetod tuleb käivitada igal tabi aktiveerimisel.
  • Code cleanup. Tõenäoliselt jäävad kasutamat mitmed meetodid nii SalesDomainControllerImpl klassis kui ka mujal – kaotada need ära


Ülesanne 2. Kassasüsteemi üleviimine Ant ehitussüsteemilt Maven'ile.

Luua kassasüsteemi jaoks Maveni buildfail (pom.xml). Põhimõtteliselt peaks see astuma olemasoleva Ant'i build.xml faili asemele ja võimaldama teha nüüd Maven'i abil samu asju, mida eelnevalt tehti Ant'iga:

  • Peab saama kassasüsteemi kompileerida, pakendada (jar-i ehitada), testida ja käivitada.
  • Andmebaasi käivitamise võib jätta ant skripti. (Seetõttu antud juhul võib Ant'i build.xml alles jääda. Reaalses olukorras kasutatakse siiski enamasti korraga ainult ühte ehitussüsteemi (mitte mõlemat!))

Tõenäoliselt muudab teile ülesande lahendamise lihtsamaks, kui "annate Maven'ile järgi" ja re-organiseerite oma rakenduse kataloogistruktuuri vastavalt Maveni standard-struktuurile. Samas võite ka minna raskemat teed ja üritada pom.xml-is kirjeldada ära projekti praegune kataloogistruktuur.

Ilmselt saab üheks tõsisemaks küsimuseks Mavenile ülemineku juures olema lib-kaustast lahtisaamine. Maveni ideoloogia näeb ette, et jar-faile ei hoita koos projekti koodiga repositooriumis, vaid nad on lihtsalt ära kirjeldatud ja vajadusel tõmbab Maven nad ise ja pakib projekti pakendamisel projektiga kaasa. Samas, hetkel ei ole teie kassasüsteemi lib-kaustas kaugeltki mitte kõik jar-id teie enda projekti sõltuvused, vaid hoopis sõltuvuste sõltuvused või sõltuvuste sõltuvuste sõltuvused jne. Maveniga peaksite kirjeldama ainult teie enda projekti otsesed sõltuvused (nt Hibernate) ja kõik järgmiste astmete sõltuvused oskaks Maven seejärel ise tõmmata. Sõltuvustes orienteerumiseks on teile abiks Eclise'i Maven-plugini pom.xml editori vaade "Dependency graph" (vaate nähtavaks tegemiseks peate enne Eclipse'i seadistustes Maveni sätete alt sisse lülitama "advanced view"-de näitamise).

Projekti käivitamine peaks lõpuks toimuma kas mvn exec:exec või mvn exec:java käsuga (ükskõik kummaga mugavam tundub). Viidetes link vastavale dokumentatsioonile.

Jar-pakendusega projektide puhul on pisut keerulisem see, kuidas pakendada kokku lõplik jar koos kõigi sõltuvustega nii et seda oleks võimalik hiljem iseseisvalt käivitada (seda kuna jari sisse iseenesest teisi jare otseselt paigutada ei saa). Kasutada tuleb teil ilmselt Maven'i assembly pluginit ja seda natuke täiendavalt seadistada.



VIITED



Sidebar
Page edit