Adat-kontextus-interakció
Az adat-kontextus-interakció (DCI) a számítógép-programozás egyik paradigmája, egymással kommunikáló objektumok elkészítéséhez. Céljai:
- Az objektumorientált kód olvashatóság javítása azzal, hogy a rendszer viselkedése egyenrangú az objektumokkal
- A lassan változó rendszerről való tudás és a gyakran változó viselkedés elkülönítése, ahelyett, hogy a kettőt egyesítenénk egy interfészben
- Segít megindokolni a fejlesztőknek, hogy rendszerszintű állapotról és viselkedésről tudjanak gondolkodni, az objektumok állapotával és viselkedésével szemben
A paradigma elkülöníti a zip tartománymodellt (adatok), a használati esetektől (kontextus) és a szerepektől (interakció). A modell-nézet-vezérlő kiegészítője. A modell-nézet-vezérlő tovább használható, mint mintanyelv, hogy elkülönítse az adatokat, feldolgozásukat és megjelenítésüket.
Leírása
[szerkesztés]Adatok
[szerkesztés]Az adatok arra a kérdésre adnak választ, hogy: Mi ez a rendszer? Az adatok javarészt statikus adatmodellekből és kapcsolataikból állnak. Az adatszerkezeteket hagyományos osztályokként valósítják meg. Használati eseteket nem valósítanak meg, azokat az interakció határozza meg. Kezelik a fizikai adattárakat, és tartalmazzák a felhasználó és a többi részt vevő által megadott mentális modellt. A modell-nézet-vezérlő modelljére emlékeztetnek.
Az adat objektumra példa egy bankszámla. Interfésze tartalmazná az egyenleg lekérdezését, továbbá a betételt és a kivételt a számlára, illetve számláról. Az interfész nem tartalmaz tranzakciókat, vagy olyan metódusokat, amelyek más objektumokat vagy felhasználói közreműködést igényelnek. A bankszámla tartalmaz egy primitív műveletet a betét növelésére, de a deposit műveletet az interakcióra hagyja.
Az adatobjektumok osztályai származhatnak tartományvezérelt fejlesztésből, így állhatnak altípus kapcsolatban az adatok rendszerezésére. Habár ez csökkenti az osztályok számát, az adat-kontextus-interakció olyan számítástechnikai modellt tükröz, ami inkább objektumokban, mint osztályokban gondolkodik. Emiatt, amikor adatokról van szó, sokkal inkább a futási időben létrejövő példányokra gondolunk, mint az osztályokra.
Kontextus
[szerkesztés]A kontextus tagjai azok az osztályok, amelyek példányai egy algoritmus, egy jelenet vagy használati eset szerepeit valósítják meg, vagy ezeket futási időben objektumokra vetítik, és feldolgozzák a használati esetet. Egy szerep pontosan egy objektumhoz kapcsolódik; megfordítva viszont egy objektum több szerepet is betölthet. A kontextus a megfelelő algoritmus hívásakor, jelenet kezdetekor vagy használati eset indulásakor példányosul. Összegezve, a kontextus kapcsolja össze az adatokat és az algoritmusokat.
A kontextusosztályok megfeleltethetők egy vagy több használati esetnek, jelenetnek vagy algoritmusnak. A kontextusobjektum feladata, hogy azonosítsa a részt vevő objektumokat, és szerepeket társítson hozzájuk, amely szerepnek megfelelő felelősséget kapnak. Társíthatja a metódusokat, amelyek mindegyike az adott használati esetnek, jelenetnek vagy algoritmusnak egy kis részének logikáját valósítja meg. A szerep által végrehajtott metódusként a szerepre kiválasztott objektum metódusa hívódik meg. A kontextus által megvalósított kapcsolat párba állítható az objektumorientáció által létrehozott polimorfizmussal. Az általános üzleti funkcionalitás komplex, dinamikus algoritmusok összessége, amelyeket több kontextus és többszörös kontextusok és az azokban levő szerepek decentralizálnak.
Minden kontextusnak saját hatóköre van, ami magában foglal azonosítókat, amelyek megfelelnek a szerepeknek. A kontextusban szereplő objektumok ezekkel a nevekkel hivatkozhatnak egymásra. Ezek az azonosítók metódus nélküli szerepek. Végrehajtás közben ezek a nevek a megfelelő szerepet betöltő objektumhoz vannak hozzárendelve.
Kontextusra lehet példa két végpont közötti adatátvitel, ahol a SourceAccount és a DestinationAccount szerepek használják az adatmodelleket (bankszámlák).
Interakció
[szerkesztés]Az interakció arra a kérdésre felel, hogy: mit csinál a rendszer? Az interakciókat szerepekként valósítják meg, amiket objektumok töltenek be futásidőben. Ezek az objektumok kombinálják az adatmodellek állapotait és metódusait egy vagy több szerep metódusaival. A szerepek állapotával nem kell számolni, mivel a szerepeknek nincs állapota. Jó stílusban az objektumok csak szerepükkel hivatkoznak egymásra. A self is szerep, csak speciális; ez kapcsolja össze az objektumot a szerepével. A szerep metódusa ezen keresztül hívhatja az objektum metódusát. Ezek a kapcsolatok csak futásidőben állnak fenn; ehhez használnak generikusokat, sablonokat, hogy a kötés mindig létrejöjjön, habár maga a minta nem teszi ezt kötelezővé.
A szerepek megfelelnek a felhasználó mentális modelljeinek a rendszerben levő entitásokról. A szerep felelősségek egy csoportját foglalja magába. Míg a klasszikus objektumorientált programozásban az objektumok és osztályok foglalják magukban a felelősséget, addig a minta ezeket a szerepeknek tulajdonítja. Egy használati esetben levő objektumnak felelősségei vannak, amiket a szerepe határoz meg. A legtöbb modern programozási nyelvben van lehetőség nyelvi szinten is leírni szerepeket, és a szerep metódusok injektálhatók objektumokba, de a megvalósítás módja nyelvfüggő. Az injekció lehet teljesen dinamikus, futásidejű, mint a Rubyhoz és a Pythonhoz hasonló nyelvekben, és statikus más nyelvekben, mint Smalltalk-Squeak, Scala és C++. A Qi4j programozási környezet szintén módot ad a szerep injektálására Javában.[1] A Java 8 interfészeinek alapértelmezett metódusa használható arra, hogy a szerepeket típusbiztosan meg lehessen valósítani.
Példánkban a SourceAccount és DestinationAccount szerepek elvégzik az átutalást.
Sajátosságai
[szerkesztés]A minta az objektumok kommunikációját a közös topológiájú hálózatokra korlátozza, amiből minden használati esethez tartozik egy. Ezek a hálózatok explicitek a szerepek közötti interakciókban, míg klasszikusan emergensek. A szerepek a topológiák pontjai; részlegesen osztályozzák az objektumok viselkedését, amelyek elfoglalhatják ezeket a csúcsokat. A topológia leírás a futásidejű rendszerről.
Egy objektumorientált program objektumok dinamikus és összetett rendszere, ugyanúgy, ahogy a valós objektumok is összetettek és dinamikusak. Tekintsünk egy pincért egy étteremben! A pincér maga is összetett objektum: az én pincérem, aki felveszi és kihozza a rendelésemet, az étterem alkalmazottja munkaidővel és fizetéssel, és egy személy az étteremben, akli a 150 fő között foglalkoztatva van. A Waiter (pincér) osztálynak mindezeket meg kell ragadnia.
Az adat-kontextus-interakció minta mindezeket az aspektusokat különböző szerepekre osztja. Futásidőben a szerep azonosítja az objektumot. Használati eset végrehajtása közben (például bor felszolgálása) a pincér egyértelműen azonosít egy objektumot egy adott időpontban. Lehet azzal érvelni, hogy több pincér lehet egy asztalnál, azonban a használati eset végrehajtása alatt különböző felelősséggel, például az egyik felveszi a rendelést, a másik kiszállítja. Ha egyeznek a felelősségek, akkor is különböző szerepnek kell tekinteni őket, megkülönböztethetők számokkal vagy egy tömb elemeiként. Így a szerep egyértelműen azonosítja az objektumot a használati esetben.
A minta egy objektumként kezeli a pincért, és nem úgy, mint ami különböző részekből, egy személyből, egy alkalmazottból és egy pincérből áll. Az objektum azonossága független a szerepétől; az adatokhoz tartozik. A szerepek csak aliasok, és nem önálló objektumok; ez skizofréniát okozna. Ebben az értelemben minden pincér ember. Ez a pincér alapvető része. Az objektum több különböző azonosságot vesz fel, attól függően, hogy milyen használati esetekben vesz részt; ez az interakció része. Egy szerep azonban egyszerre egy objektumhoz tartozik. Kódolási időben a szerepek különbözőképpen csoportosíthatók. A kód szerkezetét a használati esetek határozzák meg, amelyekben különböző időben különböző objektumok vehetnek részt; ez is az interakcióhoz tartozik.
Egy objektum több használati esetben is részt vehet, ezért különböző időpontokban más szerepet vehet fel. A szerepek interfészt valósítanak meg, amire szerep típusként hivatkoznak. Színházi értelemben az objektuok új szerepet kapnak minden használati esetben. Például a tűzvédelmi oktatáson a pincérünk az étterem egy alkalmazottja, és betölti a személy szerepet is.
Összesítve, a mintát a következők jellemzik:
- Az adatmodell a tartomány szerkezetét, és nem viselkedésének szerkezetét tükrözi.
- Az objektumok dinamikusan változó szerepeket töltenek be a használati esetek során.
- Minden használati eset kezdetén a kontextus határozza meg, hogy egy használati eset szerepeit mely objektumok töltik be.
- A szerepek közötti interakciók hálózata ugyanaz, mint végrehajtási időben az objektumok hálózata.
- Ez a hálózat dinamikusan változik a különböző használati esetek végrehajtása alatt.
- A szerepek hatókörét a használati eset időtartama határozza meg, de az egyes objektumok több használati esetet is túlélhetnek, miközben több szerepet játszanak különböző használati esetekben.
Végrehajtási modell
[szerkesztés]A minta tekinthető eseményvezérelt paradigmának, ahol bizonyos események használati esetet indítanak. A használati eset lehet rövid, vagy hosszú élettartamú. Az eseményeket triggereknek nevezik, és egy környezetben hajtódnak végre, amibe a program be van ágyazva. A környezet lehet a modell-nézet-vezérlő vezérlője, vagy más rendszerszintű kód.
A trigger hatására a környezetben létrejön egy kontextus objektum. Az objektum típusát a végrehajtandó használati eset határozza meg, amit a triggertől érkező információ és a rendszer állapota határoz meg. Például egy pénztárgépnek különböző kontextusai lehetnek a különböző pénzügyi műveletek számára, mint egyenleg lekérdezése, betétel, kivétel, átutalás. A kontextus objektum elindítja a trigger metódust, hogy elindítsa a használati esetet.
Minden kontextus tartalmazza a részt vevő szerepeket, és a kontextus feladata, hogy objektumokat rendeljen hozzájuk a triggertől kapott információ és a rendszer állapota alapján. Az objektumok bárhol lehetnek a környezetben, lehet, hogy adatbázis tartalmazza, vagy lehet, hogy létre kell hozni őket; ezt a minta nem határozza meg. Egy kontextuson belül egy szerepet legfeljebb egy objektum tölt be.
Ezután a kontextus kiosztja a szerepeket az objektumok között. Egy objektum több szerepet is kaphat. Erősen típusos nyelvekben, mint a Ruby és a Python, a kontextus injektálja a szerepeket az objektumokba. A legtöbb dinamikus nyelvben bármely objektum felkérhető bármelyik szerepre, de a nem megfelelő kombináció MESSAGE NOT UNDERSTOOD hibaüzetet ad futás közben. Statikus típusozású nyelvekben (Scala, C++) az objektumok előzetes elrendezése biztosítja, Például a Scala névtelen osztályt hoz létre, ami a tartomány osztály logikáját kombinálja a szerep megalkotásához használt vonások használati eset logikájával. A szerepeket hatékonyan hozzárendelik példányosítás után a tartomány objektumokhoz.
A kontextus meghívja a használati eset első résztvevőjének szerep metódusát. Innentől kezdve a szerepek egymást hívják. Egy szerep a selfen hívhatja azt az objektumot is, ami azt a szerepet kapta.
Megvalósítása
[szerkesztés]A minta olyan tervezési folyamaton alapul, ami megkülönbözteti az adatmodelleket a használati esetektől. Az adatmodell gyakran informális tartományelemzésen alapul. A rendszer funkcionalitásának végfelhasználói modelljét jellemző szerepek a használati esetekből származnak. A minta általános tervezésének egy általános megközelítése a karcsú architektúra,[2] amiről a Lean Architecture ír.[3]
A megvalósításhoz használt technika függ a programozási nyelvtől. A szerepek lehetnek generikusak, sablonok, osztályok vagy vonások. Az alapvető tartománylogikát ettől függetlenül kell megvalósítani, követve a konvencionális objektumorientált gyakorlatot, és többnyire osztályokkal valósítják meg. Minden szerep kódot injektálnak az objektumba, ami a használati eset ideje alatt játssza. A szerepek megvalósításához metódus injekcióra van szükség, ezt például a népszerű vonások teszik lehetővé.[4] A vonásokat egyes nyelvek támogatják, mint a Scala, másokban magára a futás idejű injektálásra van lehetőség. Javában ez annotációkkal jelezhető.
Több különböző példa megvalósítás létezik: Smalltalk-Squeak,[5] C++,[6] C#,[7] Ruby,[8] JavaScript,[9] Python,[10] Qi4J (Java),[11] Scala, Perl,[12] PHP,[13] és más nyelvek számára. Ezek közül több megtalálható a minta megalkotóinak fulloo.info oldalán.[14]
Története
[szerkesztés]A mintát Trygve Reenskaug, a modell-nézet-vezérlő kidolgozója alkotta meg. A jelenlegi leírások legtöbbje Reenskaug és James O. Coplien könyvét követi.
A minta Trygve Reenskaug szerep alapú modellezéséből nőtt ki.[15] Trygve felismerte, hogy a programozók gondolkodásában központi szerepet foglalnak el a szerepek, gyakran így gondolnak az objektumokra. A nyelvek osztályorientált fejlődése elvette a motivációt attól, hogy objektumokban gondolkodjanak, emiatt nehéz követni, hogy mi történik futás időben. Továbbá mivel az objektumorientált nyelvekben osztályokra korlátozódik a logika kifejezése, ami miatt a programozónak az adatok szerkezetét a logikával együtt kell megvalósítania. Ez természetellenes, szemben a szerepek keretein belül körvonalazott viselkedéssel. Emiatt nehezebb gondolkodni a programról, mintha procedurális lenne, és klasszikus Fortranban lenne írva.
Trygve fontosnak érezte megindokolhatóindokolható programszerkezetek létrehozását, és ötletét 2000-től elkezdte terjeszteni. 2006-ra már működő modellje volt. Schärli 2008-ban bevezette a vonásokat; ebben Trygve ötleteinek természetes programnyelvi kifejezését látta meg. Az új prototípust Baby programozási környezetben írta meg, Squeak nyelven. Jim Coplien 2007-ben társult Trygvéhez, és 2008 közepére C++-ban is megalkotta a prototípust. Steen Lehmann, Rickard Öberg és Niclas Hedhman alkalmazta az ötletet Rubyra és Javára a Qi4j keretrendszerrel. Dániában a 2008 szeptemberében tartott JaOO konferenciát követően további nyelvekre adaptálták.
Az objektumorientáció fejlődése követte az adat-kontextus-interakció elvét. Ezek ugyan egymagukban nem valósítják meg a modellt, de utalnak arra, hogy a minta által megcélzott problémák hosszú távúak és alapvetőek:
A mixinek zárt formában tartalmaznak specifikus funkcionalitást, viszont nem tartalmaznak következetes mechanizmust arra, hogy használati eset szintjén több mixint kapcsoljanak össze. A mixinek a szerepekhez állnak közel.
A multimetódusok korai kísérletek voltak arra, hogy teljesen elkülönítsék a metódusokat és a vele kapcsolatban álló objektumokat. Azonban hiányzik a minta szerinti különbségtétel az általános algoritmusok és azok között, amelyek hozzákapcsolhatók egy-egy objektumhoz. A minta fogalmai szerint egy algoritmust zárt formában szélesebb körben kell újrahasznosítani különböző típusú objektumok különböző készletein. A kontextus objektumok explicit, intelligens diszpécserként működnek, ami analóg a multimetódusokkal.
Az igazán objektumorientált nyelvek, például a Self megpróbálják lebontani az osztályalapú programozás és az objektumalapú végrehajtás kettősét. Míg ez segít a programozónak figyelemmel kísérni az objektumokat, addig ezek a nyelvek feláldozzák a kód szintű tudást a közöttük levő kapcsolatokról. A minta ezt a tudást a kontextusokban és a szerep metódusok közötti statikus kapcsolatokban állítja helyre.
A dependency injection hosszú távú megközelítés arra, hogy futási időben megváltoztassa egy objektum működését azáltal, hogy külső objektumot injektál valamelyik adattagba, ami dinamikusan cserélhető. A legtöbb megvalósítás azonban skizofréniát okoz, amin az adat-kontextus-interakció segít. Egyes rendszerek, mint az Elmo ezt a megközelítést használják, ami elbonyolítja a metódusok egyértelműsítést és a duplikált nevek problémáját.[16]
A multiparadigma egyik próbálkozása az volt, hogy a viselkedést procedurálisnak, a szerkezetet objektumorientáltnak tervezte. Ez lehetővé tette a szabad hozzáférést, összhangban a C++ tervezési elveivel. Ellenben ez a módszer nem tudta kifejezni a kapcsolatot a procedurális és a szerkezeti részek között, és nem tudta megközelíteni az adat-kontextus-interakció koherenciáját.
Talán az aspektusorientált programozás áll legközelebb az adat-kontextus-interakcióhoz, holott az aspektusorientáció inkább alkalmazkodik a programozó elképzeléseihez, mint a felhasználó elképzeléseihez a használati esetekről. Erős eszköztámogatás nélkül nehezebb megérteni, hogy mit csinál az aspektusorientált program egy adott pointcutban. A fő különbség az, hogy az adat-kontextus-interakcióban az algoritmus szerkezete az elsődleges, és külső kóddal való interakciója másodlagos, míg az aspektusorientált programozásban a popintcutok és a javaslatok egyenrangúak, ugyanolyan aktívvak, ezért mindkettőt meg kell érteni, habár fizikailag különböznek. Adminisztratívan csoportosítja az egymáshoz kapcsolódó helyi egyedi módosításokat; ezek együtt keresztmetszik a kód elsődleges szerkezetét. A minta egy algoritmus szemantikus kifejezése első osztályú elemzéssel, ami létező objektummetódusokat hív. Aspektusorientáltan nézve az adat-kontextus-interakciónak van egy nagy javaslata, amit számos szabályozott pointcutba injektál.
A szereporientált programozás az aspektusorientált programozás kiegészítése például fogalmi modellezéssel.[17] Korai kísérletek 1991-ben egymástól függetlenül határozták meg a szerepeket.[18] 2002-től kiemelik, hogy a szerepek függenek a kontextustól (csapat,[19] intézmény[20]). A szereporientált programozásban a szerepeket belső vagy alapvető dolgokként definiálják, ami megfelel a minta szerinti adat-szerep különbségtételnek. A kontextus fogalma lényegében ugyanaz, és mindkettő kiemelten kezeli a szerepek közötti interakciókat.
A kettő közötti különbségek az eltérő módszerekből adódnak. A szereporientált programozás új eszközökkel bővíti az objektumorientált nyelvet, és támogatja az öröklődést, szabadon kombinálva az új lehetőségekkel, míg az adat-kontextus-interakció ellenjavallja, mondván, hogy a szerepek nem öröklődnek,[21] mivel mentális modellekre támaszkodik. A minta elkerülendőnek tartja a skizofréniát, míg a szereporientált nyelvek szerzői módszert nyújtanak a hasított objektumok kezelésére.[22] Az adat-kontextus-interakció szerzői egy későbbi cikkükben bemutatták, hogy igenis lehet probléma a skizofrénia a szereporientált programozásban, ellenpéldájukhoz a Dijkstra-algoritmus módosítását használták fel.[23]
Jegyzetek
[szerkesztés]- ↑ Qi4j framework
- ↑ Lean Software Architecture web page, http://www.leansoftwarearchitecture.com
- ↑ James Coplien and Gertrud Bjørnvig, Lean Architecture for Agile Software Development. Wiley: 2010.
- ↑ Nathaniel Schärli et al. Traits: Composable units of behavior. http://scg.unibe.ch/archive/papers/Scha03aTraits.pdf
- ↑ The Common Sense of Object Oriented Programming by Trygve Reenskaug, http://heim.ifi.uio.no/~trygver/2009/commonsense.pdf
- ↑ Full OO DCI Documentation C++ Examples, http://fulloo.info/Examples/C++Examples/index.html
- ↑ C# source code on Object-Composition Google group,http://object-composition.googlegroups.com/web/20090504_C%23_DCI.zip?gda=KuAYkEcAAADrRvU1tICZInrYQGkdqcjVB9LJpDFQtNZStXvSrZaE07Ryyh4ndddBwXohD2r2F8gbzHe87USdioT9uNiA7PHaeV4duv6pDMGhhhZdjQlNAw[halott link] 17.10.2009
- ↑ Ruby source code on Object-Composition Google group,https://groups.google.com/group/object-composition/browse_thread/thread/561f638b43f1b960# 17.10.2009
- ↑ JavaScript source code on Object-Composition Google group,https://groups.google.com/group/object-composition/browse_thread/thread/8ec4cf18e127cc3e# 17.10.2009
- ↑ https://pypi.python.org/pypi/roles
- ↑ Qi4j source code on Object-Composition Google group,https://groups.google.com/group/object-composition/browse_thread/thread/fe317e615b9008fe# 17.10.2009
- ↑ Release on CPAN: https://metacpan.org/release/DCI Archiválva 2012. január 24-i dátummal a Wayback Machine-ben
- ↑ PHP source code on Google, https://code.google.com/p/php-coredci
- ↑ Lásd fullo.info/Examples
- ↑ Trygve Reenskaug. Working with Objects: The OOram Software Engineering Method. Prentice-Hall, 1995.
- ↑ James Leigh, Elmo User Guide, http://www.openrdf.org/doc/elmo/1.5/user-guide.html Archiválva 2011. július 21-i dátummal a Wayback Machine-ben
- ↑ Friedrich Steimann, On the representation of roles in object-oriented and conceptual modelling, 2000, http://www.fernuni-hagen.de/ps/veroeffentlichungen/zeitschrift_46129.shtml Archiválva 2016. október 7-i dátummal a Wayback Machine-ben
- ↑ Joel Richardson and Peter Schwarz, Aspects: extending objects to support multiple, independent roles, 1991, http://www.informatik.uni-trier.de/~ley/db/conf/sigmod/RichardsonS91.html Archiválva 2007. október 17-i dátummal a Wayback Machine-ben
- ↑ Stephan Herrmann, Object Teams: Improving Modularity for Crosscutting Collaborations, http://www.objectteams.org/publications/index.html#NODe02, 2002
- ↑ Guido Baldoni et al., Roles as a coordination construct: introducing powerJava, 2005, http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.77.6337
- ↑ J. Coplien, posted in Object-Composition Google group, https://groups.google.com/forum/?hl=en#!topic/object-composition/haza-J2Doz8 21.10.2010
- ↑ Stephan Herrmann, Demystifying Object Schizophrenia, 2010, http://www.objectteams.org/publications/index.html#MASPEGHI10
- ↑ James O. Coplien, and Trygve Mikkjel Heyerdahl Reenskaug, The data, context and interaction paradigm. In Gary T. Leavens (Ed.): Conference on Systems, Programming, and Applications: Software for Humanity, SPLASH '12, Tucson, AZ, USA, October 21–25, 2012. ACM 2012, ISBN 978-1-4503-1563-0, pp. 227 - 228, http://dl.acm.org/citation.cfm?id=2384782&dl=ACM&coll=DL.
Források
[szerkesztés]- The DCI Architecture: A New Vision of Object-Oriented Programming by Trygve Reenskaug and James O. Coplien
- object-composition Google group with several early implementations of DCI by individuals
Fordítás
[szerkesztés]Ez a szócikk részben vagy egészben a Data, context and interaction című angol Wikipédia-szócikk 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.