710 likes | 1.01k Views
Elemzési, tervezési minták (Analysis/Design Patterns). Benedek Zoltán (BME-AAIT) fóliáinak felhasználásával. Történelem, személyiségek, hivatkozások. 1987: OOPSLA’87, Orlando, Ward Cunningham, Kent Beck: „Using pattern languages for Object Oriented Programs” (Smalltalk, GUI)
E N D
Elemzési, tervezési minták (Analysis/Design Patterns) Benedek Zoltán (BME-AAIT) fóliáinak felhasználásával
Történelem, személyiségek, hivatkozások • 1987: OOPSLA’87, Orlando, Ward Cunningham, Kent Beck: „Using pattern languages for Object Oriented Programs” (Smalltalk, GUI) • 1991: Jim Coplien: Advanced C++ programming styles and idioms. • Gang of four (G4, GoF, Négyek bandája), Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides különböző könyvek külön majd együtt
Irodalom • Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides: Design PatternsElements of Reusable Object Oriented SoftwareAddison-Wesley 1994. • James W. Cooper: The Design Patterns Java CompanionAddison-Wesley Design Pattern Series 1998. • www.martinfowler.com
Világháló • Minták Honlapja: http://hillside.net/patterns/patterns.html • A Portland Mintatár: http://www.c2.com/ppr/ • Ward Cunningham WikiWiki-je: http://c2.com/cgi/wiki?WelcomeVisitors • Patletek adatbázisa: http://hillside.net/patterns/patlet/?FrontPage • Cetus Links Minták százai: http://www.objenv.com/cetus/oo_patterns.html • Brad Appleton Szoftver Mintagyűjtemény http://www.bradapp.net/links/sw-pats.html • AG Communications Rendszerminták http://www.agcs.com/patterns/ • Szervezeti minták honlapja: http://www.bell-labs.com/cgi-user/OrgPatterns/OrgPatterns
A (Tervezési) Minták és a speciális relativitáselmélet (avagy „sok igazság van a filozófiában”) • NEM SZENTÍRÁS!!!NEM A BÖLCSEK KÖVE!!! • NEM CÉL!!! HANEM ESZKÖZ!!! • MINDEN RELATÍV!!! (ne keverjük össze az ágyút a verébbel vagy a túzokkal!) • KONKRÉT VISZONYOKHOZ ILLESZTENI KELL!!! • LÉTEZIK MÁSFÉLE FILOZÓFIA IS!!!
Minták fogalmai • „Utasításjellegű információrög, ami bizonyos környezetben és erőviszonyok között felmerülő és visszatérő feladatok sikeres megoldáscsaládjainak lényegét és alapelképzelését rögzíti.” • 3oldalú reláció: „környezet”, „erőviszonyok”, „szoftver konfiguráció”: amely lehetővé teszi, hogy az erők magukat megoldják • 3oldalú reláció: „környezet”, „feladat”, „megoldás”: a környezet és a feladat által megadott kézenfekvő megoldás • Egy dolog, ami előfordul – egy utasítás a dolog létrehozására. Egyszerre dolog és folyamat – egy élő dolog és az őt létrehozó folyamat leírása.
Minták fogalma • A folyamat, ami létrehozza a dolgot, és a dolog, amit a folyamat létrehozott • 3-as szabály. Legalább 3 környezetben tesztelve… • Leendő minták: „proto-patterns”, „patlets” • Anti-patterns: 1. Elrettentő példák 2. Elrettentő helyzetet megfordító példák… • Best practices… (esettanulmány). Általános / általánosítható / jellegzetes / újrahasznosítható esetek, de ennél SOKKAL TÖBB • Hasznos, használható és használt! • „Kérdéses” műfaj. (Az eredmény mellett a filozófia, a megoldáshoz vezető út is érdekes)…
Minták fajtái • Szervezeti minták – ezzel nem foglalkozunk • Felépítmény (architectural) minták • Elemzési minták • Fogalmi (conceptual) minták • Tervezési (design) minták • Kódolási (programkészítési) minták (idiómák)
Tervezési minták fajtái (G4) • Mi a célja az adott mintának? • Létrehozó (creational) minták: nem „egyszerűen” példányosítunk… • Szerkezeti (structural) minták: egyszerűbb objektumokból bonyolultabb szerkezetek felépítése • Viselkedésmegadó (behavioral) minták • A minta hatóköre: • (Objektum): osztályok kapcsolata, öröklődés • (Osztály): objektumok kapcsolata, asszociáció
Model-View-Controller (Smalltalk)(Document/View Microsoft) Megjelenítés vezérlés GUI eszközök (controls) Kétirányú kapcsolat (szinkron/aszinkron) adatábrázolás
Minta:Időpont • Időpont ábrázolása valamilyen felbontásban, valamilyen helyen- milyen felbontásban? (évjárat dátum Timestamp)- milyen helyen? (időzónák)- műveletek különböző pontosságú adatok között
Kétféle megoldás a Date típusra Felület (interface) csak műveletdefiníciók Tulajdonságok: adatmodell / megvalósítási modell
Burkolóosztályok (adapterek, wrapperek) Burkolóosztály, amelyben az alaposztály összetevő Burkolóosztályképzés alosztályképzéssel
Range (Szakasz) • Összehasonlítható/rendezhető típusok felett • Műveletek: szakaszba esés, átlapolás • Osztálymintákkal (template) megvalósítható • Sorbarendezés, mint extra művelet • Nyitott végű szakasz
Accounting Entry (Számla tétel) • Időpont • Összeg • Partner • Helyszín • Hány számlánk van? (Kinek?)
Account (Számla) • Tételek halmaza, ahol a tételek összegezhetőek (+(x:Entry):Entry) • A tételek, a történetük maguk fontosabbak, mint az összegük • Nem feltétlenül pénztől van szó (fogyasztás, csapadék, teljesítmény stb.) • Indirekciós lehetőség, szűrhető a tételek többi körülményei alapján
Időfüggés, időgép • Diszkrét időfüggés: a változás ugrásszerű • Milyen változásokat kell rögzíteni? Csak jelenidejű változások. Tranzakcióba foglalás • Csak háttérben tárolt (perzisztens) objektumokra • Alapesetben a legfrissebb adatokkal dolgozunk • Az időgép bármilyen korábbi dátumra visszaállítható • Időbeli változások egyetlen elemre • Egy konkrét objektumháló (pillanatfelvétel) időben összeegyeztethető (konzisztens)-e • Időfüggő adatok köre • Időfüggés finomsága (az egész rendszerre/egy objektumra/egy tulajdonságra) • Idődimenziók száma (bi-temporal, 2 idődimenzió)
Temporal Property • Lekérdezés (accessor) – időpont függvényében • Módosítások- hozzáfűző – az idősor végén, múltbeli, jelen, jövőbeli- módosító – az időszakaszok egymást kizárják?- beszúró – egyéb konzisztenciakérdések- törlő – (!!!) • Megvalósítás: 1. egyszerű lineáris vektor 2. Időfüggő gyűjtemény (temporal collection)
Temporal Object • Időben változó objektum: változás, tartalom állandóság, identitás. • Pillanatkép: vagy az egészre, vagy egy tulajdonságra nézve • Történet, módosítás • Csak az objektum változik, vagy a hálózat (a kapcsolatok változásait is modellezni kell-e)
Explicit változatok Időfüggés kétirányú láncolt listával
Egy időfüggő osztályból 2 osztály (állandó/változó) keletkezik • TempEnabled alaposztályból származik az állandó, örökli az időfüggés kezelését • Temporal alaposztályból származik a változó rész • Egy időfüggő kapcsolat örököl a Temporary kapcsolóosztálytól • Rendezett, idő szerint indexelt gyűjtemény • Új változat létrehozása csak aktuális időben, tranzakcióba foglalva/explicit hívásra
Műveletek • - oldest: a művelet előállítja a legöregebb adat időpontját • - actual: a művelet előállítja a legfiatalabb adat időpontját • - létrehozás (constructor). Az alaposztály létrehozása során az időfüggő vektornak is létrejön a legelső eleme. • -időfüggő tulajdonságok elérése: az időfüggő objektumra mutató navigációval, az időadat szerinti indexeléssel. Az indexelés algoritmikus megoldása olyan részletkérdés, amelyet nem tárgyalunk. • - consistent: ellenőrzi, hogy a paraméterként megadott időpontban az objektum összes időfüggő összetevője élő-e • - renew: újabb időfüggő példány létrehozása. A példány tulajdonságai a létrehozás után teljesen megegyeznek a korábbi példányéval. A tulajdonságértékek ezek után a tulajdonság-elérő műveletekkel módosíthatók.
Gang Of Four (GoF) minták • Könyv: Kiskapu kiadó • Létrehozó: (creational) • A minták általában a megadott osztályok további kidolgozásával és példányosítással, illetve példányosításra használhatók… • Szerkezeti: (structural) • A minták objektumösszetételekre épülnek • Viselkedési (behavioral): • A minták a megadott osztályok példányai közötti kommunikációra épülnek
GoF létrehozó minták • Singleton: egypéldányú osztályok létrehozására • Prototype: létező objektumok lemásolására • Builder: összetett szerkezetek létrehozására • Factory Method: • AbstractFactory: közös témához köthető objektumok létrehozására szolgál
Singleton • Olyan osztály megadása, amely megakadályozza, hogy többszörösen példányosítsák. • Ezt úgy éri el, hogy az osztály tartalmazza saját egyetlen példányát (statikus, osztály hatókörű) • Az egyetlen példány elérése statikus (osztály hatókörű) elérő (accessor) művelettel • A Singleton konstruktora csak privát lehet! (hogy ne tudjok bárki új példányt létrehozni belőle) • Késői kezdőértékezés • Vigyázat a statikus accessorral! Nem származtatható le belőle újabb osztály • Globális változóhoz hasonló működésmód (állandónak látszó környezeti információk tárolása vagy csak funkcionális osztály) • Singleton törlése… (?)
Builder • Cél: valamilyen külső reprezentáció beolvasásakor a reprezentáció felismerését és az adatszerkezet létrehozását különválasztani • Megoldás: a Director a Builder burkolója (Builder része Directornak). • A Director:construct eljárása létrehozza a teljes Product szerkezetet. • A construct eljárás meghívja a Builder:buildPart1(), …buildPartN() eljárásait, amelyek a Builderen belül létrehozzák a Product részeit. • A létrehozás után a Builder:getResult:Product eljárással lehet az eredményt megkapni.
Prototype A Prototype típusú objektumból új példányokat úgy hozhatunk létre, hogy meghívjuk a clone():Prototype módszert. Ez létrehozza az alapobjektum egy másolatát.
Factory Method A munkához szükséges objektumokat a ConcreteCreator:factoryMethod állítja elő. Ennek az eredménye az absztrakt Product típus. A változatlan specifikáció mellett egy vagy több ConcreteProduct létezik, a factoryMethod természetesen konkrét típusú objektumokat állít elő.
AbstractFactory A munkához szükséges objektumokat a programban nem a new operátorral állítjuk elő, hanem a Factory osztály createProduct (polimorf) hívásával. A Factory osztályban nemcsak egyetlen createProduct eljárás van, hanem ilyenekből egy csokorra való. Ha új ConcreteProduct típusra van szükségünk, akkor nem szükséges az absztrakt kódot módosítani, hanem csak a megfelelő ConcreteFactory osztályt kell létrehozni. Ilyen módon hozzuk létre pl. a CORBA objektumokat (a távoli szerverről csak a Factory objektum azonosítóját szerezzük meg, a többit már a megfelelő hívások eredményeképpen kapjuk meg).
GoF szerkezeti minták • Adaptor: • Bridge: • Composite: • Decorator: • Facade: • Flyweight: • Proxy:
Adaptor • Klasszikus Wrapper osztályszerkezet/Objektum adapter/objektumkompozícióval • Target: interface, definíció, ezt kapja/használja/várja az ügyfél • Client: ügyfél, aki használja • Adapter: olyanná alakítja az Adaptee interfészt, amilyet a kliens szeretne • Adaptee: ezen végzünk átalakítást
Adaptor • Adapter osztályszerkezet többszörös öröklődéssel (osztály adapter) • Target: interface, definíció, ezt kapja/használja/várja az ügyfél • Client: ügyfél, aki használja • Adapter: olyanná alakítja az Adaptee interfészt, amilyet a kliens szeretne • Adaptee: ezen végzünk átalakítást
Bridge • Abstraction-Implementor felületek: a szokásos Wrapper szerkezet • RefinedAbstraction, ConcreteImplementor: konkrét megvalósítások • Eredmény: a megvalósítás teljesen függetlenedik a definíciótól
Composite • Összetett objektumok kezelése, amikor objektumok egy csoportját úgy kezeljük, mintha egyetlen objektum volna. • A ténylegesen egyszerű (Leaf) és az összetett (Composite) objektumok egyöntetű kezelése (Component felület) • Az objektumok egy faszerkezetet feszítenek ki • operation() { for each g in children g.operation(); } 0..* children
Decorator • Decorator egy burkolóosztály, amivel új műveleteket adunk az eredeti (Component) osztályhoz. • Decorator() (konstruktor) paramétere a kibővítendő Component példány. • Valójában a ConcreteDecorator adja hozzá az új műveleteket. • Előbb a Component objektumot hozzuk létre, majd ezzel létrehozzuk a Decoratort
Facade (homlokzat) • A Facade osztály több különböző osztályhoz biztosít egyszerűsített felületet. Ilyen lehet pl. több osztály, alrendszer, vagy nagyobb lélegzetű objektumkönyvtár.
Proxy • Objektum helyett egy helyettesítő objektumot használ, ami szabályozza az objektumhoz való hozzáférést. • Pl. Szövegszerkesztő, sok nagyméretű képpel. Csak akkor jelenítjük meg/töltjük be a képeket, ha odagörgetünk • Egyetlen példányt hozunk létre, és (szükség szerint) proxy példányt. • Minden műveletet a megvalósított osztálypéldány végez el • Ha a proxy megszűnik, akkor megszűnhet a megvalósított példány is
Proxy • Subject: közös interfészt biztosít a Subject és a Proxy számára (ezáltaltud a minta működni, ez a lényeg!) • RealSubject: a valódi objektum, amit a proxy elrejt • Proxy: helyettesítő objektum. Tartalmaz egy referenciát a tényleges objektumra, hogy el tudja azt érni. Szabályozza a hozzáférést a tényleges objektumhoz, feladata lehet a tényleges objektum létrehozása és törlése is. • Távoli Proxy • Távoli objektumok lokális megjelenítése átlátszó módon. A kliens nem is érzékeli, hogy a tényleges objektum egy másik címtartományban, vagy egy másik gépen van • Virtuális Proxy • Nagy erőforrás igényű objektumok igény szerinti létrehozása (pl. kép) • Védelmi Proxy • A hozzáférést szabályozza különböző jogok esetén • Smart Pointer • Egy pointer egységbezárása, hogy bizonyos esetekben automatikus műveleteket hajtson végre (pl.:lockolás)
Flyweight (lepkesúly) • Ha nagyon nagyszámú objektumot kezelünk, akkor fontos, hogy csak kevés felesleges adatot tároljunk • Nincsenek osztályfüggvényeik, hogy a vtable pointer ne foglaljon helyet • Pl: egy word-processor karakterei. Nem tárolhatunk minden betűt a formattálásával együtt – csupán egy hivatkozást tárol a formattálásra • Azonosan formattált szövegszakaszok összefogása egyetlen blokkba
GoF viselkedési minták • Chain of Responsibility • Command • Interpreter • Iterator • Mediator • Memento • Observer • State • Strategy • TemplateMethod • Visitor
Template Method • Cél • Egy műveleten belül algoritmus vázat definiál, és a váz néhány lépésének implementálását a leszármazott osztályra bízza. • Példa: Framework-ben dokumentum megnyitása • A framework-ben legyen adott két osztály, Application és Document. Ezekből kell a programozónak egy-egy saját osztályt leszármaztatnia, amikben megvalósítja az alkalmazás specifikus viselkedést.
Template method • A példában az OpenDocument egy ún. template method • Meghatározza a műveletek sorrendjét • Meghív néhány absztrakt műveletet, melyeket a leszármazott osztályban felül kell definiálni, hogy meghatározott viselkedést rendeljünk hozzá az aktuális igényeknek megfelelően // Az Application osztály a framework része public class Application { public void OpenDocument (string name) { if (!CanOpenDocument(name)) { // cannot handle this document return; } // a DoCreateDocument-et a adott alkalmazás megírásakor az // az Application-ból leszármazottMyApplication osztályban // felül kell definiálni, itt lesz majd értelmesen „kitöltve” Document doc = DoCreateDocument(); if (doc != null) { _docs.AddDocument(doc); AboutToOpenDocument(doc); doc.Open(); doc.DoRead(); } }
Template method • Struktúra