Sastav, agregacija i udruživanje u Javi

1. Uvod

Objekti imaju veze između sebe, kako u stvarnom životu, tako i u programiranju. Ponekad je teško razumjeti ili implementirati te odnose.

U ovom uputstvu usredotočit ćemo se na Javinu primjenu na tri ponekad lako pomiješane vrste odnosa: sastav, agregacija i pridruživanje.

2. Sastav

Sastav je vrsta odnosa koji "pripada". To znači da je jedan od predmeta logično veća struktura, koja sadrži drugi objekt. Drugim riječima, to je dio ili član drugog objekta.

Alternativno, često ga nazivamo odnosom „ima-ima“ (za razliku od odnosa „je-a“, koji je nasljeđivanje).

Na primjer, soba pripada zgradi, ili drugim riječima zgrada ima sobu. U osnovi, jesmo li to nazvali "pripada" ili "ima-a", samo je pitanje gledišta.

Sastav je snažna vrsta odnosa "ima-ima" jer ga sadrži objekt koji ga sadrži. Stoga, životni ciklusi predmeta su vezani. To znači da ako uništimo objekt vlasnika, s njim će biti uništeni i njegovi članovi. Na primjer, soba je uništena sa zgradom u našem prethodnom primjeru.

Imajte na umu da to ne znači da objekt koji sadrži ne može postojati bez ijednog od njegovih dijelova. Na primjer, možemo srušiti sve zidove unutar zgrade, a time uništiti sobe. Ali zgrada će i dalje postojati.

Što se tiče kardinalnosti, objekt koji sadrži može imati onoliko dijelova koliko želimo. Međutim, svi dijelovi moraju imati točno jedan spremnik.

2.1. UML

U UML-u označavamo sastav sljedećim simbolom:

Imajte na umu da je dijamant na predmetu koji sadrži i da je osnova crte, a ne strelica. Radi jasnoće, često crtamo i strelicu:

Dakle, ovaj UML konstrukt možemo koristiti za primjer zgrade u sobi:

2.2. Izvorni kod

U Javi to možemo modelirati s ne-statičnom unutarnjom klasom:

razred zgrada {class room {}}

Alternativno, tu klasu možemo deklarirati i u tijelu metode. Nije važno je li to imenovani razred, anonimni razred ili lambda:

razred zgrada {Room createAnonymousRoom () {return new Room () {@Override void doInRoom () {}}; } Soba createInlineRoom () {klasa InlineRoom implementira Room {@Override void doInRoom () {}} return new InlineRoom (); } Soba createLambdaRoom () {return () -> {}; } soba sučelja {void doInRoom (); }}

Imajte na umu da je bitno da naša unutarnja klasa ne bude statična jer veže sve svoje instance na klasu koja sadrži.

Obično sadržavajući objekt želi pristupiti svojim članovima. Stoga bismo trebali pohraniti njihove reference:

razred zgrada {Popis soba; predavaonica {}}

Imajte na umu da svi objekti unutarnje klase pohranjuju implicitnu referencu na svoj objekt koji sadrži. Kao rezultat toga, ne trebamo ga pohranjivati ​​ručno da bismo mu pristupili:

razred zgrada {Adresa niza; klasa Soba {String getBuildingAddress () {return Building.this.address; }}}

3. Zbrajanje

Agregacija je također odnos „ima-ima“. Ono što ga razlikuje od sastava, to što ne uključuje posjedovanje. Kao rezultat toga, životni ciklusi predmeta nisu povezani: svaki od njih može postojati neovisno jedan o drugome.

Na primjer, automobil i njegovi kotači. Možemo skinuti kotače, a oni će i dalje postojati. Možemo montirati druge (već postojeće) kotače ili ih instalirati na drugi automobil i sve će raditi sasvim u redu.

Naravno, automobil bez kotača ili odvojeni kotač neće biti toliko koristan kao automobil s uključenim kotačima. Ali zato je taj odnos uopće postojao: do sastaviti dijelove na veću konstrukciju koja je sposobna za više stvari od svojih dijelova.

Budući da agregiranje ne uključuje posjedovanje, član ne mora biti vezan samo za jedan spremnik. Na primjer, trokut je napravljen od segmenata. Ali trokuti mogu dijeliti segmente kao svoje stranice.

3.1. UML

Agregacija je vrlo slična sastavu. Jedina logična razlika je agregacija slabiji odnos.

Stoga su i UML prikazi vrlo slični. Jedina razlika je u tome što je dijamant prazan:

Za automobile i kotače tada bismo učinili:

3.2. Izvorni kod

U Javi možemo modelirati agregaciju s običnom starom referencom:

klasa Kotač {} klasa Automobil {Popis kotača; }

Član može biti bilo koje vrste klase, osim nestatične unutarnje klase.

U isječku koda iznad obje klase imaju zasebnu izvornu datoteku. Međutim, možemo koristiti i statičku unutarnju klasu:

razred automobila {Popis kotača; kotačić statičke klase {}}

Imajte na umu da će Java stvoriti implicitnu referencu samo u ne-statičkim unutarnjim klasama. Zbog toga moramo odnos održavati ručno tamo gdje nam je potreban:

klasa Kotač {Automobil; } klasa Automobil {Popis kotača; }

4. Udruženje

Udruženje je najslabija veza između njih trojice. To nije odnos "ima-a", niti jedan od predmeta nije dio niti član drugog.

Udruživanje samo znači da se predmeti "poznaju". Na primjer, majka i njezino dijete.

4.1. UML

U UML-u vezu možemo označiti strelicom:

Ako je asocijacija dvosmjerna, možemo koristiti dvije strelice, strelicu s vrhom strelice na oba kraja ili crtu bez vrhova strelica:

U UML-u možemo predstavljati majku i njezino dijete, a zatim:

4.2. Izvorni kod

U Javi možemo modelirati udruživanje na isti način kao i agregacija:

razred Dijete {} razred Majka {Popis djece; }

Ali čekaj, kako možemo znati znači li referenca agregaciju ili udruživanje?

Pa ne možemo. Razlika je jedino logična: je li jedan od predmeta dio drugog ili nije.

Također, reference moramo ručno održavati na oba kraja kao što smo to učinili s agregiranjem:

razred Dijete {Majka majka; } razred Majka {Popis djece; }

5. UML Sidenote

Radi jasnoće, ponekad želimo definirati kardinalnost odnosa na UML dijagramu. To možemo učiniti tako da napišemo na krajeve strelice:

Imajte na umu da nema smisla zapisivati ​​nulu kao kardinalnost, jer to znači da nema veze. Jedina je iznimka kada želimo koristiti raspon da naznačimo neobavezni odnos:

Također imajte na umu da, budući da u sastavu postoji točno jedan vlasnik, to ne označavamo na dijagramima.

6. Složeni primjer

Pogledajmo (malo) složeniji primjer!

Modelirat ćemo sveučilište koje ima svoje odjele. Na svakom odjelu rade profesori, koji također imaju prijatelje među sobom.

Hoće li odjeli postojati nakon što zatvorimo sveučilište? Naravno da nije, dakle riječ je o kompoziciji.

Ali profesori će i dalje postojati (nadamo se). Moramo odlučiti što je logičnije: smatramo li profesore dijelovima odsjeka ili ne. Alternativno: jesu li članovi odjela ili nisu? Da, jesu. Stoga je to agregacija. Povrh toga, profesor može raditi na više odsjeka.

Odnos između profesora je udruživanje, jer nema smisla reći da je profesor dio drugog.

Kao rezultat, ovaj primjer možemo modelirati sa sljedećim UML dijagramom:

A Java kod izgleda ovako:

razred Sveučilište {Odjel za popis; } razredni odjel {Popis profesora; } razred profesor {Odjel za popis; Popis prijatelja; }

Imajte na umu, da ako mi oslanjati se na izraze „ima-a“, „pripada-pripada“, „član“, „dio“, i tako dalje, možemo lakše prepoznati odnose između naših predmeta.

7. Zaključak

U ovom smo članku vidjeli svojstva i zastupljenost sastava, agregacije i povezivanja. Također smo vidjeli kako modelirati te odnose u UML-u i Javi.

Kao i obično, primjeri su dostupni na GitHubu.