Objektum-összetétel
Ez a szócikk nem tünteti fel a független forrásokat, amelyeket felhasználtak a készítése során. Emiatt nem tudjuk közvetlenül ellenőrizni, hogy a szócikkben szereplő állítások helytállóak-e. Segíts megbízható forrásokat találni az állításokhoz! Lásd még: A Wikipédia nem az első közlés helye. |
A számítástudományban az objektum-összetétel és az objektumegyesítés szorosan egymáshoz köthető műveletek arra irányulóan, hogy objektumokat vagy adattípusokat komplexebb formává alakítsunk át. A gyakorlatban az összetétel és az egyesítés közti különbségeket gyakran elhanyagolják, nem veszik figyelembe. Az összetétel gyakori példái olyan objektumok, amik objektumorientált programozásban, változókban, sorozatokban, vagy különféle gráf struktúrákban vannak felhasználva. Az objektum-összetétel továbbá szoros összefüggésben áll az adat struktúrákkal is, de nem azonos azokkal.
Az objektum-összetétel az információ logikai, fogalmi felépítésére utal, nem pedig az adatstruktúrák fizikai implementálására. Például, a sorozatok különböznek a „set” adattípustól, mivel többek között az összeállított elemek sorrendje egy fontos feltétel az előbbinek, de az utóbbinak nem. Olyan adatstruktúrák, mint például a sor, a láncolt lista, a hash tábla, használhatók arra, hogy valamelyiküket implementáljuk. Talán zavaró, de előfordul, hogy ugyanazt a fogalmat használják mind az adatstruktúrákra, mind az összetételre. Például, a bináris fa mindkettőre utalhat: adatstruktúraként az elemek lineáris sorozatban való hozzáférését jelenti, ahol az elemek tényleges pozíciója lényegtelen, mivel a fa átrendezhető anélkül, hogy elveszítse funkcióját. Ennek ellenére, mint objektum-összetétel, a bináris fában az elemek pozíciója releváns, hiszen megváltoztatva azokat, a fa funkciója is elvész (ez történik például a kladogramokban is).
Programozási technikák
[szerkesztés]Az objektumorientált programozás az objektumok egységbezárásán alapul, két fő technikát használ erre: az altípusokat és az objektum-összetételt.[1] Objektum-összetétel esetén már meglévő, összetett objektumon belül kombinálunk kisebb objektumokat egy komplexebbé, illetve, ezzel egy időben biztosítjuk minden elem egységbezárását egy jól definiált interface segítségével anélkül, hogy az objektumok belseje láthatóvá válna. Ebből is látható, hogy az objektum-összetétel mennyire különbözik az adatstruktúráktól, mivel azoknál nem szükséges az egységbezárás használata.
Osztály-alapú és típusos programozási nyelvekben a típusok elkülöníthetők összetett és nem összetett típusokra, az összetétel pedig tekinthető a típusok közti kapcsolatnak is: az összetett típus egy objektumának (pl. „autó”) van objektuma egy másik típusból (pl. „kerék”). Mikor egy összetett objektum több al-objektumot is tartalmaz azonos típusból, olyankor szerepekhez is hozzárendelhetők. Például, a „Point” objektum három számot tartalmazhat, mindegyik szám az adott pont különböző tengelyektől (x, y, z) mért távolságát reprezentálja.
Az összetételt muszáj elkülöníteni az altípusosságtól, mivel az utóbbi egy már létező, általános típusokhoz ad részleteket, így egy specifikusabb adat típust hoz létre. Például, az „autó” egy specifikusabb típusa a járműnek: „Az autó jármű.” (Is-a kapcsolat). Az altípusosság nem mondja ki a kapcsolatot két különböző objektum közt, hanem azt mondja, hogy egy bizonyos típus objektumai egyidejűleg objektumai egy másik típusnak is.
A prototípus-alapú programozási nyelvekben, mint amilyen a JavaScript is, az objektumok dinamikusan öröklik a tulajdonságaikat egy prototípus objektumtól, már a példányosításuk pillanatában. Az összetétel megkülönböztetendő a prototípusoktól: az újonnan példányosított objektum örökli a prototípusának összetételét, de akár saját magát is kompozicionálhatja.
UML modellezési technika
[szerkesztés]UML modellezésben az objektumok létrehozhatók koncepcionálisan, anélkül, hogy programozási nyelv segítségével lennének implementálva. Négyféle lehetőség van arra, hogy UML-ben objektumokat állítsunk össze: property, egyesítés, aggregáció és összetétel[2]:
- A property az osztályának egy attribútumát reprezentálja.
- Az egyesítés az egyesített osztályok közti szemantikai kapcsolatot reprezentálja.Az egyesület tagvége a társított osztály egy tulajdonságának felel meg.
- Az aggregáció egyfajta egyesítés, ami a rész/egész kapcsolatot modellezi az egész és a hozzá köthető komponensek közt.
- Az összetétel az aggregáció egy fajtája, ami a rész/egész kapcsolatot modellezi az egész és a kizárólagosan tulajdonlott részek közt.
Az aggregált egész és annak komponensei közt egy gyenge „has-a” kapcsolat van: a komponensek több egésznek is részei lehetnek, és ahhoz, hogy más objektumokon keresztül is elérhetők legyenek, túl kell élniük az aggregált egészüket.[3]
Az összetétel és annak részei közt erős „has-a” kapcsolat van: az összesített objektumnak egyedülálló felelőssége van arra vonatkozóan, hogy életben tartsa és tárolja a kompozicionált objektumokat. A kompozicionált objektum része legfeljebb egy összetételnek, ezért UML-ben az összetételnek szűkebb értelme van, mint egy általános objektum-összetételnek.
A grafikus jelölés a következőket ábrázolja:
- a propertyt mint egy típusos elemet a körbezárt osztályon belül
- az asszociációt, mint sima vonalat a társított osztályok között,
- az aggregációt, mint egy kitöltetlen gyémánt forma az aggregált oldalon, másik oldalon sima vonal
- az összetétel kitöltött gyémántként a kompozit oldalán és egy folytonos vonal.
Aggregáció
[szerkesztés]Az aggregáció abban különbözik az átlagos objektum-összetételtől, hogy nem jár tulajdonlással: összetétel esetén, ha a tulajdonlott objektum megsemmisül, akkor a benne lévő objektumok is megsemmisülnek. Aggregáció esetén ez nem feltétlenül igaz. Például: egy egyetemnek van több tanszéke (pl. kémiai tanszék stb.) és minden tanszéken több professzor is tanít. Ha az egyetem bezár, megszűnnek a tanszékei, de a professzorok továbbra is megmaradnak, így mondhatjuk, hogy az egyetem a tanszékek összetétele, a tanszékek viszont a professzorok aggregációja. Illetve, a gyakorlatban is láthatjuk, hogy egy professzor dolgozhat több tanszéken is, de az adott tanszék csakis egy egyetem tulajdona lehet.
Az összetételt általában úgy valósítják meg, hogy egy objektum egy másik objektumot is tartalmazzon. Például így néz ki C++ nyelven:
class Professor; // Máshol definiálva
class Department {
public:
Department(const std::string& title): title_(title) {}
private:
// Aggregáció: |Professors| tovább létezik, mint a |Department|.
std::vector<std::weak_ptr<Professor>> members_;
const std::string title_;
};
class University {
public:
University() = default;
private:
// Összetétel: |Department|s csak addig létezik, míg a „faculty”-k léteznek
std::vector<Department> faculty_ = {
Department("chemistry"),
Department("physics"),
Department("arts"),
};
};
Az aggregáció során az objektum csak hivatkozást vagy mutatót tartalmazhat az objektumra (és nem vállal felelősséget érte).
Néha az aggregációt összetételnek nevezik, amikor a közönséges összetétel és az aggregáció közötti különbségek nem fontosak.
A fenti kód így nézne ki UML osztálydiagramként:
Aggregáció COM-ban
[szerkesztés]A Microsoft komponensobjektum-modelljében (Component Object Model) az aggregáció azt jelenti, hogy egy objektum (mintha a tulajdonosa lenne), egy másik, tulajdonában lévő objektum, egy, vagy több interfészét exportálja. Formálisan ez jobban hasonlít az összetételhez vagy az egységbezáráshoz, mint az aggregációhoz. Ahelyett azonban, hogy az exportált interfészek a tulajdonlott objektum interfészeinek meghívásával lennének implementálva, maguk a tulajdonlott objektum interfészei kerülnek exportálásra. A tulajdonlott objektum felelős annak biztosításáért, hogy az IUnknown
-tól örökölt interfészek metódusai valóban meghívják a tulajdonos megfelelő metódusait. Ez garantálja, hogy a tulajdonos referenciaszáma helyes, és a tulajdonos összes felülete elérhető legyen az exportált felületen keresztül, miközben a tulajdonlott objektum egyéb (privát) felületei nem érhetők el.[4]
Speciális formák
[szerkesztés]Elszigetelés
[szerkesztés]Az összetett adattípus több példányának tárolására használt összetételt elszigetelésnek nevezzük. Ilyen tárolók például a tömbök, az asszociatív tömbök, a bináris fák és a láncolt listák.
Az UML-ben az elszigetelés 0..* vagy 1..* többszörösével van ábrázolva, jelezve, hogy az összetett objektum az összeállított osztály ismeretlen számú példányából áll.
Rekurzív összetétel
[szerkesztés]Az objektumok rekurzív módon is összeállíthatók, és típusukat ezután rekurzív típusnak nevezzük. A példák közé tartoznak a különféle fák, DAG-ok és grafikonok. A fa minden csomópontja lehet ág vagy levél; más szóval, minden csomópont egyben fa is, amikor egy másik fához tartozik.
Az UML-ben a rekurzív összetételt egy osztály önmagával való asszociációjával, aggregációjával vagy összetételével ábrázolják.
Összetett minta
[szerkesztés]Az összetett tervezési minta egy összetett típusokon alapuló objektumorientált tervezés, amely a rekurzív összetételt és az elszigetelést ötvözi, hogy összetett rész-egész hierarchiákat valósítson meg.
Kompozíciós típusok C nyelvben
[szerkesztés]Példa az összetételre C nyelvben:
struct Szemely
{
int kor;
char nev[20];
enum {allas_kereso, szakember, szakmabeli, nyugdijas, tanulo} foglalkoztatas;
};
Ebben a példában a primitív (nem összetett) int
, enum { allas_kereso, szakember, szakmabeli, nyugdijas, tanulo }
és a char[]
összetett tömbtípus kombinációja alkotja a Szemely
összetett szerkezetet. Minden Szemely
struktúrának „van” egy életkora, neve és foglalkoztatási típusa.
Azösszetétel fejlődése más programozási nyelvekben
[szerkesztés]C nyelvben egy rekordot struktúrának nevezünk; az objektumorientált nyelvekben (pl. Java, Smalltalk és C++) gyakran rejtve tartjuk a rekordjainkat az objektumok (osztálypéldányok) belsejében; az ML család nyelvei viszont egyszerűen csak rekordoknak nevezik őket. A COBOL volt az első széles körben elterjedt programozási nyelv, amely közvetlenül támogatta a rekordokat.
- 1959 – COBOL
01 customer-record.
03 customer-number pic 9(8) comp.
03 customer-name.
05 given-names pic x(15).
05 initial-2 pic x.
05 surname pic x(15).
03 customer-address.
05 street.
07 street-name pic x(15).
09 house-number pic 999 comp.
05 city pic x(10).
05 country-code pic x(3).
05 postcode pic x(8).
03 amount-owing pic 9(8) comp.
- 1960 – ALGOL 60
ALGOL 60-ban csak a tömbök voltak kompozíciós adattípusok.
- 1964 – PL/I
dcl 1 newtypet based (P); 2 (a, b, c) fixed bin(31), 2 (i, j, k) float, 2 r ptr; allocate newtypet;
- 1968 – ALGOL 68
int max = 99; mode newtypet = [0..9] [0..max]struct ( long real a, b, c, short int i, j, k, ref real r ); newtypet newarrayt = (1, 2, 3, 4, 5, 6, heap real := 7)
A láncolt lista deklarálható így is:
mode node = union (real, int, compl, string),
list = struct (node val, ref list next);
Az ALGOL 68 esetében csak a típusnév jelenik meg az egyenlőség bal oldalán, és a konstrukció balról jobbra készül – és olvasható – a prioritások figyelembevétele nélkül.
- 1970 – Pascal
type
a = array [1..10] of integer;
b = record
a, b, c: real;
i, j, k: integer;
end;
- 1972 – K&R C
#define max 99
struct newtypet {
double a, b, c;
float r;
short i, j, k;
} newarrayt[10] [max + 1];
- 1977 – FORTRAN 77
Fortran 77-ben ugyan vannak tömbök, de hiányoztak a formális rekord/struktúra definíciók. Az összetett szerkezetek jellemzően EQUIVALENCE
vagy COMMON
utasítások használatával készültek:
CHARACTER NAME*32, ADDR*32, PHONE*16
REAL OWING
COMMON /CUST/NAME, ADDR, PHONE, OWING
- 1983 – Ada
type Cust is
record
Name : Name_Type;
Addr : Addr_Type;
Phone : Phone_Type;
Owing : Integer range 1..999999;
end record;
- 1983 – C++
const int max = 99;
class {
public:
double a, b, c;
float &r;
short i, j, k;
}newtypet[10] [max + 1];
- 1991 – Python
max = 99
class NewTypeT:
def __init__(self):
self.a = self.b = self.c = 0
self.i = self.j = self.k = 0.0
# Initialise an example array of this class.
newarrayt = [[NewTypeT() for i in range(max + 1)] for j in range(10)]
- 1992 – FORTRAN 90
A tömbök és a string-ek a FORTRAN 77-ből öröklődtek, de egy új definíció is bevezetésre került: típus.
type newtypet
double precision a, b, c
integer*2 i, j, k
* No pointer type REF REAL R
end type
type (newtypet) t(10, 100)
A FORTRAN 90 frissítette és tartalmazta a FORTRAN IV NAMELIST
nevű koncepcióját.
INTEGER :: jan = 1, feb = 2, mar = 3, apr = 4
NAMELIST / week / jan, feb, mar, apr
- 1994 – ANSI Common Lisp
(defclass some-class ()
((f :type float)
(i :type integer)
(a :type (array integer (10)))))
Jegyzetek
[szerkesztés]- ↑ Gamma, Erich: Design patterns : elements of reusable object-oriented software | WorldCat.org (angol nyelven). www.worldcat.org, 1995. (Hozzáférés: 2023. május 9.)
- ↑ OMG (2017). "Unified Modelling Language Specification Version 2.5.1". www.omg.org. p. 109-110, 197-201. 2020. október 4.
- ↑ OMG: Unified Modeling Language Specification Version 2.5.1. www.omg.org, 2017. (Hozzáférés: 2020. október 4.)
- ↑ Aggregation. Platform SDK for Windows XP SP2. Microsoft. (Hozzáférés: 2007. november 4.)
Fordítás
[szerkesztés]Ez a szócikk részben vagy egészben az Object composition című angol Wikipédia-szócikk ezen változatának fordításán alapul. Az eredeti cikk szerkesztőit annak laptörténete sorolja fel. Ez a jelzés csupán a megfogalmazás eredetét és a szerzői jogokat jelzi, nem szolgál a cikkben szereplő információk forrásmegjelöléseként.