Programtervezési minták (GEIAL517M) Jegyzőkönyv

Hasonló dokumentumok
Java VI. Egy kis kitérő: az UML. Osztály diagram. Általános Informatikai Tanszék Utolsó módosítás:

Webes alkalmazások fejlesztése 8. előadás. Webszolgáltatások megvalósítása (ASP.NET WebAPI)

INFORMATIKAI ALAPISMERETEK

Bánsághi Anna

eseményvezérelt megoldások Vizuális programozás 5. előadás

PHP II. WEB technológiák. Tóth Zsolt. Miskolci Egyetem. Tóth Zsolt (Miskolci Egyetem) PHP II / 19

C# osztályok. Krizsán Zoltán

Adatbázis alapú rendszerek gyakorlat Adatbázis alapú alkalmazásfejlesztés Java, C# környezetben

Szervlet-JSP együttműködés

Objektumorientált programozás C# nyelven

Entity Framework alapú adatbáziselérés

INFORMATIKAI ALAPISMERETEK

Access adatbázis elérése OLE DB-n keresztül

C# nyelv alapjai. Krizsán Zoltán 1. Objektumorientált programozás C# alapokon tananyag. Általános Informatikai Tanszék Miskolci Egyetem

A Microsoft Visual Studio 2005 fejlesztőkörnyezet

C# feladatgyűjtemény Kovács Emőd, Radványi Tibor, Király Roland, Hernyák Zoltán

Szálkezelés. Melyik az a hívás, amelynek megtörténtekor már biztosak lehetünk a deadlock kialakulásában?

Grafikus felületek készítése 1.

Bosch Video Client. Kezelési útmutató

Objektumorientált programozás C# nyelven

strings.xml res/values/strings.xml fájlban hozzuk létre a hiányzó string adatforrásainkat A jelenlegi helyett ez álljon: <resources> <string

Osztály és objektum fogalma

Vizuális programozás gyakorlat

Objektumorientált programozás C# nyelven III.

OBJEKTUM ORIENTÁLT PROGRAMOZÁS JAVA NYELVEN. vizsgatételek

AIX 6.1. IBM Systems Director Console for AIX

Grafikus felületek a programozó szempontjából grafikus elemek absztrakt reprezentációja az egyes elemek tulajdonságait leíró adatstruktúrák.

PHP5 Új generáció (2. rész)

Eseményvezérelt alkalmazások fejlesztése II 12. előadás. Objektumrelációs adatkezelés (ADO.NET) Giachetta Roberto

CAD-CAM

ScopeImage 9.0. Kamera és képfeldolgozó szoftver. Felhasználói kézikönyv

Adatbázis rendszerek I

MUNKAANYAG. Angyal Krisztián. Szövegszerkesztés. A követelménymodul megnevezése: Korszerű munkaszervezés

Java felhasználói felület

C#, OOP. Osztályok tervezése C#-ban

BEACon TM. Verzió 2.0

JVJ DVD-8808 Könyöklő DVD lejátszó Használati utasítás

Grafikus felhasználói felületek. Abstract Window Toolkit, a java.awt és java.awt.event csomagok

OAF Gregorics Tibor: Minta dokumentáció a 3. házi feladathoz 1.

Objektumorientált programozás C# nyelven

SATEL. CA-64 RIASZTÓKÖZPONT ( es szoftver verzió) Telepítési útmutató

Széchenyi István Egyetem

Bevezetés a Programozásba II 11. előadás. Adatszerkezetek megvalósítása. Adatszerkezetek megvalósítása Adatszerkezetek

Intellio Video System 2. Csatlakozási útmutató a demószerverhez

Alap számológép alkalmazás

3. Gyakorlat Ismerkedés a Java nyelvvel

Elemi alkalmazások fejlesztése IV. Adatbázis-kezelés ActiveX vezérlıkkel - 1

Bevezetés a programozásba 2

WCF, Entity Framework, ASP.NET, WPF 1. WCF service-t (adatbázissal Entity Framework) 2. ASP.NET kliens 3. WPF kliens

INFORMATIKAI ALAPISMERETEK

117. AA Megoldó Alfréd AA 117.

Intézményi interface technikai dokumentáció

FELÜLET...13 PROJEKTTERV...14

Előzmények

A táblaszámítógép bemutatása

Objektum Orientált Szoftverfejlesztés (jegyzet)

Programozás BMEKOKAA146. Dr. Bécsi Tamás 1. Előadás

libgdx alapok, első alkalmazás

Book Template Title. Author Last Name, Author First Name

Powershell 1. gyakorlat

Java programozási nyelv 8. rész Grafikus felhasználói felület

Sorompó kezelés mérlegműszerrel

Mai számítógép perifériák. Számítógépes alapismeretek 1. beadandó. Lővei Péter (LOPSAAI.ELTE) 2010.

I. fejezet Hello Világ! Programozás tankönyv. II. Fejezet. Helló Világ! avagy a Miért?-ek elkezdődnek

Egy dinamikus adatbázis megvalósítása egy megrendelő-raktározó alkalmazáson keresztül.

Szoftvertechnolo gia gyakorlat

Szkeleton tervezése. 100 Generalis faliora. Csapattagok: Konzulens: Szabó András március 21.

Programozási technikák Pál László. Sapientia EMTE, Csíkszereda, 2009/2010

RIA Rich Internet Application

Szövegszerkesztő programok: Jegyzettömb, WordPad, Microsoft Word

Az anyagdefiníciók szerepe és használata az Architectural Desktop programban

SZET GYAK1: Követelmények ellenőrzése

STL. Algoritmus. Iterátor. Tároló. Elsődleges komponensek: Tárolók Algoritmusok Bejárók

Programozás I. 2. gyakorlat. Szegedi Tudományegyetem Természettudományi és Informatikai Kar

4. Öröklődés. Programozás II

A SZOFTVERTECHNOLÓGIA ALAPJAI

JAVA PROGRAMOZÁS 3.ELŐADÁS

ADATBÁZISKEZELÉS ADATBÁZIS

Eddig még nem használt vezérlőket is megismerünk: PlaceHolder, RadioButtonList.

Welcome3 Bele pteto rendszer

EMTP, EGY ÚJ LEVELEZÕ PROTOKOLL ÉS IMPLEMENTÁCIÓJA

Biztonság java web alkalmazásokban

1. BEVEZETÉS A RENDSZER ELEMEI, ARCHITEKTÚRÁJA... 5

Dell Latitude E5440 Kezelési kézikönyv

Kétdimenziós rajzolás WPF-ben

Rövidített felhasználói kézikönyv. H.264 ( 4/8/16 csatornás) Digitális video rögzítő

!!" KÉSZÍTK: ERDÉLYI LAJOS KOLLÁR NÁNDOR WD6OGW BUK8Y7

Programozás BMEKOKAA146. Dr. Bécsi Tamás 8. előadás

Budapest, oldal

Bánsághi Anna

Szerializáció. Tóth Zsolt. Miskolci Egyetem. Tóth Zsolt (Miskolci Egyetem) Szerializáció / 22

Programozás 1. 2.gyakorlat

Dell Latitude E5540 Kezelési kézikönyv

Kalapácsvetés 2016 szöveges

CellCom. Szoftver leírás

Kezelési és szerelési útmutató

Az üzembe helyezéstől. a nyomtatásig. Z45 Color Jetprinter. Az üzembe helyezéstől a nyomtatásig január.

Töltőfunkció Kezelési Utasítás

Modellalkotás UML-ben

Hello World Servlet. Készítsünk egy szervletet, amellyel összeadhatunk két számot, és meghívásakor üdvözlőszöveget ír a konzolra.

Átírás:

Miskolci Egyetem, Általános Informatikai Tanszék Programtervezési minták (GEIAL517M) Jegyzőkönyv

Tartalom 1 2 3 Létrehozó minták...3 1.1 Egyke...3 1.2 Factory...6 1.3 Builder...7 1.4 Prototype...9 Szerkezeti minták...10 2.1 Adapter...10 2.2 Bridge...12 2.3 Composite (Össztétel)...15 2.4 Decorator (Díszítő)...17 2.5 Proxy...19 2.6 Facade (Homlokzat)...21 Viselkedési minták...23 3.1 Command (Parancs)...23 3.2 Observer (Megfigyelő)...26 3.3 Chain of Responsibility (Felelősség lánc)...29 3.4 Mediator (Közvetítő)...31 3.5 State (Állapot)...35 3.6 Strategy (Stratégia)...38 2

1 Létrehozó minták 1.1Egyke Feladat: A fogyasztó saját ritmusában, saját algoritmusa szerint működve felhasználja a termelő által előállított terméket. Legyen a raktár egy csak egy példányban létező objektum. o a termelő beteszi a terméket, o a fogyasztó pedig kiveszi A fogyasztó és termelő számra nem kötött legyen véletlen érték 1-100 között (az elején érdemes fix darabszámmal dolgozni) A termelő és a fogyasztó sebességére nincs kikötésünk, így minden szálban véletlen ideig várakozzunk (100-1000 ms) A raktár limitált méretű, csak 3000 terméket képes tárolni. A termék fontos tulajdonsága a neve, amely azonosítja a létrehozó szál neve + sorszáma. Készítsen osztály diagramot az alkalmazás modellezésére! A feladat osztálydiagramja: 3

A diagram részei: Producer: Kliens oszály, ismeri a terméket és a raktárt Consumer: Kliens oszály, ismeri a terméket és a raktárt Repository: A Singleton. Definiál egy Instance statikus property-t, mellyel elérhetővé teszi az egyetlen példányt. A statikus get property lockolva van a párhuzamos hozzáférés miatt public static Repository Instance { get { lock (Repository.lockString) { if (instance == null) { instance = new Repository(); } return instance; } } } A termelő és a fogyasztó a raktár példányát csak a statikus property-n keresztül éri el. Ha már volt példányosítva akkor visszatér a példánnyal, ha még nem, akkor létrehozza az új raktár példányt. 4

Product: A termék osztálya A Singleton repository használata egyszerű: Új termék hozzáadása: Product p = Repository.Instance.AddProduct(new Product()); Termékeket így vehetünk ki a raktárból: Product p = Repository.Instance.GetProduct(); A Singleton kiváltja a globális változókat, így szabályozottan férhetünk hozzá globális objektumhoz. 5

1.2Factory Feladat: Az előző (termelő-fogyasztó) feladatban Különböző megvalósítású, de azonos felületű termékek létrehozása Factory mintával, hogy a termelőktől és a fogyasztóktól elszigeteljük a konkrét típusokat. Cél: Új termék bevezetésekor a termelőnek és a fogyasztónak minimális módosítás, ismeret legyen szükséges. A feladat osztálydiagramja Részei: Az előző feladatból: Consumer, Repository, Producter. A szerepük nem változott. Producer: A producer az előző feladatban betöltött szerepen kívül, ő lett a kliens. Ismeri a terméket és a gyárat, terméket kér a gyártól. Product: Fejlődött az előző feladathoz képest. A Product absztrakt osztály, a termékek jellemzőit foglalja össze. 6

Product1, Product2: Konkrét termékek. Közös ősük a Product ostály. ProductFactory: Van egy create metódusa, mely Product típusú objektummal tér vissza. Adott paraméter alapján eldönti, hogy milyen konkrét productot hozzon létre. Példa termékek példányosítására: ProductFactory productfactory = new ProductFactory(); Random r = new Random(); Product p = null; p = productfactory.create(r.next(1, 3)); A minta használatával új termékek bevezetésekor a kliens csak a paraméter változását tudja, változtatni csak a ProductFactory létrehozó metódusát kell. 1.3Builder Feladat: Készítsen egy C# alkalmazást, amely komponensek létrehozásának menetét mutatja be! Készítse el a komponens osztályt! o Legyen ToString metódusa, amely kiírja nevét, és az aktuális szerkezetét! A komponensek különböző felépítésük lehetnek (van neve string): o Portok 0..* (van neve, id-je, amely legyen egyedi, kapacitása) adat (kimenet vagy bemenet) típus (string) o LogInterfész 0 1 (van id-je) Készítsen építő osztályokat tipikus komponensekre! o Adatszűrő (1 bementi adatportja és 1 kimeneti adatportja van) o Monitor (1 bementi adatportja és 1 kimeneti adatportja van) o Információ forrás (1 kimeneti adatportja van) o Információ nyelő (1 bementi adatportja portja van) 7

A feladat osztálydiagramja A ComponentBuilder absztrakt osztály ismeri a Component osztály részeit és tartalmazza a Component osztály részeit előállító metódusokat. A Director osztály ismeri a ComponentBuilder absztrakt osztályt és használja metódusait. A Port és a LogInterface osztályok a Component részei. A klines létrehozza a Director-t és átadja neki ComponentBuilder megfelelő leszármazott osztályának a példányát. A főprogram: Director director = new Director(); ComponentBuilder cb = new MonitorBuilder(); director.setcomponentbuilder(cb); director.create(); Component c = director.getcomponent(); cb = new DataFilterBuilder(); director.setcomponentbuilder(cb); director.create(); Component c2 = director.getcomponent(); Console.WriteLine(c.ToString()); Console.WriteLine(c2.ToString()); 8

A program kimenete: A minta használatával a termék példányosítása ellenőrzötten történik, csak a director felügyelete mellett lehetséges, ami csak kész terméket ad át a kliensnek. 1.4Prototype Az előző feladat bővítése: A felhasználó tudjon több komponens példányt is létrehozni, amelyet egy listában tárolunk! Az új példányok mindig egy alapértelmezett értékkel jönnek létre, amelyet a felhasználó megváltoztathat. Gondoskodjon arról, hogy a listában levő elemek állapotát meg lehessen változtatni (konzol alkalmazásban egy menü)! Gondoskodjon arról, hogy a klónozott objektumok teljesen függetlenek legyenek a prototípus objektumtól (deep copy) A kibővített osztálydiagram: 9

A Prototype interfésznek van egy Clone metódusa, mellyel önmagát klónozza. A Comonent osztály implementálja a Prototype interfészt, ez az osztály a konkrét prototípus a modellben. A Prototípus minta egy egyszerű és hatékony módja objektumok másolásának. Az objektumok inicializálásának idejét rövidíti. 2 Szerkezeti minták 2.1Adapter Az adapter minta használatának gyakorlásához egy egyszerű példa elkészítése a feladat, amelyben szándékosan más néven akarjuk használni a metódusokat. Az elkészített feladatban egy egyszerű, négy alapműveletes számológép osztályhoz csinálok egy példát az osztály adaptálására. 10

A diagram részei: ICalculator: A cél felület interfésze. A Client osztály ismeri. Client: Az ügyfél osztály, amely felhasználja a Target interface objektumát RealCalc: Az illesztendő felület, meghatározza az interfészt, melyet illeszteni kell (az adaptee). MyCalculator: Összeilleszti az ICalculator interfészt a RealCalc felületével Példa a használatára: ICalculator calc = new MyCalculator(); double a = 20; double b = 5; Console.WriteLine("{0} Console.WriteLine("{0} Console.WriteLine("{0} Console.WriteLine("{0} + * / {1} {1} {1} {1} = = = = {2}", {2}", {2}", {2}", 11 a, a, a, a, b, b, b, b, calc.add(a, b)); calc.subtract(a, b)); calc.multiply(a, b)); calc.divide(a, b));

A kliensnek csak az ICalculator felületét kell ismernie, az adapter elrejti a művelteket ténylegesen végrehajtó osztályok részleteit. 2.2Bridge Feladat: Készítsen egy grafikus alkalmazást, amely 3 féle objektumot kezel: kör, négyzet, kereszt Mindegyiknek legyen alapértelmezett mérete: o A körnek az átmérő o A négyzetnek a két átfogó csúcs távolsága o A keresztnek a hossza Helyezzen el véletlenszerűen grafikus objektumokat a képernyőn Tegye lehetővé, hogy bármelyiket egy közös dialógusablakon (vagy frame) keresztül lehessen átméretezni, áthelyezni! (Vagy klikkelés, vagy combobox a kiválasztásra) Ha valaki megváltoztatja a kijelölt objektumot, akkor a beállító helyen az aktuális értéket lássuk! Használja a Bridge mintát! Definiáljon egy Shape osztályt, aminek van egy implementora, ami kör vagy négyzet vagy plusz jel. A Shape-nek vannak position, size tulajdonságai Ezek a tulajdonságok az implementort használják arra, hogy megváltoztassák az objektumok paramétereit 12

Érdemes a kirajzoláshoz is a Shape osztályt használni. Kép az elkészített alkalmazásról: A feladat osztálydiagramja Részei 13

Shape: Az elvont ábrázolás felület. Felületet biztosít a Circle, Square és Cross osztályoknak. A hozzá érkező kéréseket az IShapeDrawer Implementor felé továbbítja. Circle, Square, Cross: A finomított elvont ábrázolás osztályai. IShapeDrawer: Az implementor (megvalósító felület) osztály. Kirajzoló felületet biztosít. CanvasDrawer: A konkrét megvalósító osztály. Implementálja a az IShapeDrawer Implementort a wpf-es Canvas controlra tudja kirajzolni az alakzatokat és tuja törölni a Canvas-t. A grafikus objektumok létrehozása: Random r = new Random(); cd = new CanvasDrawer(canvas1); for (int i = 0; i < 30; i++) { int num = r.next(1, 4); Shape s = null; switch (num) { case 1: s = new Cirlcle(this.cd); break; case 2: s = new Square(this.cd); break; case 3: s = new Cross(this.cd); break; } s.size = r.next(10, 50); s.y = r.next(200); s.x = r.next(500); s.id = i; Shapes.Add(s); } Ha változik valamilyen paraméter, akkor az alakzatok újra rajzolása a következőképpen történik: cd.clear(); 14

foreach (Shape s in Shapes) { s.draw(); } A minta használatával az objektumokat kirajzoló programrészt lecserélhetjük úgy, hogy a többi osztályt nem kell módosítani (ha például a WPF-es Canvas helyett valami mást akarnék használni). 2.3Composite (Össztétel) Feladat: A komponensek névterekbe vannak hierarchikusan rendezve. Egy névtérben lehetnek komponensek és újabb névterek is. Minden komponensnek vannak tulajdonságai és metódusai a. Legfontosabb a komplexitás, ami egy lebegőpontos szám (mennyire bonyolult a komponens feladata) b. ToString metódus: összesítés, melyik elemből mennyi, majd alelemeit alatta kiírja c. ToXML metódus: a ToString XML verziója d. Count tulajdonság: az alatta lévő összes elem (komponens és névtér) e. ComponentCount tulajdonság: az alatta lévő komponensek száma. f. ContextCount tulajdonság: az alatta lévő komponensek száma Készítsünk egy alkalmazást, amely ezt a fa struktúrát kompozit minta alkalmazásával valósítja meg! a. Adott részfa (csomópont) elemére lekérdezhetjük, hogy mennyi a komplexitása (áthelyezhető-e a részfa egésze egy processzorra)! b. Készítsük el a ToString, ToXML metódusokat! Készítsünk egy grafikus alkalmazást, amely a fenti elemeket használja, és egy fa vezérlőben mutatja az elemeket! Kép az elkészült alkalmazásról: 15

A feladat osztálydiagramja Component: A faszerkezet levele (egy komponens) SoftwareElement: Az összetétel osztályok (Component és NameSpace) közös felülete. NameSpace: Összetétel osztály. Lehetnek gyerekei: NameSpace, vagy Component. 16

Részlet a hierarchia létrehozásáról: SoftwareElement root = new NameSpace("RootNS"); SoftwareElement c1 = new Component("component1", 2); SoftwareElement c2 = new Component("component2", 4);... (root as NameSpace).Add(c1); (root as NameSpace).Add(c2); Így olyan osztályhierarchia valósul meg, amely az alap objektumok rekurzívan építi egyre bonyolultabb objektumokká A kliensnek nem kell tudnia, hogy a kérést egy komponensnek vagy névtérnek adja át, ugyanis ezek egységesen vannak kezelve, ha a kérést levél kapja, akkor az végrehajtódik, ha belső csomópont, akkor továbbítódik a levelek felé. 2.4Decorator (Díszítő) Példafeladat: Készítsen egy Component osztályt, amely képes végrehajtani egy operációt, majd különböző dekorátorokkal módosítsa a viselkedését. Készítsen egy dekorátor osztályt, amely naplózza a mozgás tényét. Készítsen egy dekorátor osztályt, amely kimondja a kapott parancsot, és ha a pozícióba ér (esemény). Készítsen egy objektumot, amely naplózza is a mozgás tényét és ki is mondja a kapott parancsot. Az elkészített objektum: Component c; RobotComponent rc = new RobotComponent(new Point() { X = 0, Y = 0 }); MovingLoggerDecorator mld = new MovingLoggerDecorator(rc); SpeakerDecorator sd = new SpeakerDecorator(mld); c = sd; 17

c.moveto(new Point() { X = 12, Y = 54 }); A két dekorátor hozzáadásával a robot komponens megkapta a további képességeket. Az elkészített konzolos alkalmazás kimenete: Az elkészített feladat osztálydiagramja: 18

Az osztálydiagram részei Component: Absztrakt osztály, megadja a felületet azoknak az objektumoknak, melyek dinamikusan bővíthetőek lesznek. Egy absztrakt metódusa van. RobotComponent: A Component osztályból származik, implementálja a MoveTo metódust. ComponentDecorator: Egy Component típusú adattagja van. A Component típusú objektumokat tudja bővíteni, meghatároz egy felületet, amely illeszkedik a Component-re. SpeakerDecorator: A Component MoveTo metódusát kiegészíti úgy, hogy az naplózza a mozgás tényét. MovingLoggerDecorator: A Component MoveTo metódusát kiegészíti úgy, hogy kimondja a kapott parancsot, és ha a pozícióba ér. A minta használatának előnye, hogy a díszítők láncolásával több tulajdonságot egyszerűen tudnunk hozzáadni futásidőben. 2.5Proxy Feladat szövege Készítsen konzolalkalmazást, ami web service-t használva végez el valamilyen műveletet. A szolgáltatás elérése proxy objektumon keresztül történjen. A kliens kódon ne látszódjon, hogy a művelet egy távoli gépen hajtódik végre. Feladat megoldása: 1. Létrehoztam egy új ASP.NET webes alkalmazást és egy Console alkalmazást 19

2. A webalkalmazásban létrehoztam egy WebCalc nevű webservice-t, ami tud összeadni, kivonni, szorozni és osztani. 3. A webalkalmazást elindítottam a localhoston, a service wsdl elérhető volt a következő címen: http://localhost:11414/services/webcalc.asmx?wsdl 4. Ez után létrehoztam a console alkalmazást és Visual Studioban hozzáadtam a projekthez egy web referenciát az előbb létrehozott webservice-re. 5. A console alkalmazás Main metódusában használtam a service-t a Visual Studio által generált proxy osztállyal. static void Main(string[] args) { WebCalc.WebCalcSoapClient webcalcproxy = new WebCalc.WebCalcSoapClient(); int a = 3; int b = 6; Console.WriteLine("{0} + {1} = {2}", a, b, webcalcproxy.add(a, b)); Console.ReadKey(); } Az így létrehozott WebCalcSoapClient osztály példánya miatt a távoli végrehajtás helyinek tűnik. A Visual Studio által generált WebCalcSoapClient valójában soap kérés küld a webes szolgáltatásnak. A Console alkalmazás kimenete: 20

2.6Facade (Homlokzat) Feladat szövege: Készítsen konzolos alkalmazást, ami egy számítógép elindulását modellezi. A számítógép legalább 4 komponensből álljon. Használja a facade mintát. A feladat osztálydiagramja: 21

A diagram részei: Computer: A homlokzat. A kliens (user) kéréseit továbbítja az alrendszerek osztályai felé. Alrendszeri osztályok: CPU, Keyboard, VideoCard, DDRRAM, HDD. Az alrendszeri osztályok nem tudják, hogy ők egy Computer részei, csak elvégzik a kéréseket. A feladatban a Computer osztály Start metódusa modellezi egy számítógép elindulását. Beállítja a billentyűzet kapcsolóit, majd megnézi, hogy nyomtak-e billentyűt. Ha igen, akkor elindítja a BIOS-t, egyébként megkezdi a bootfolyamatot. Betölti a memóriába winchester bootszektorát, majd beállítja a processzor program counter regiszterét a memória boot címére. this.keyboard.capslock = false; this.keyboard.numlock = false; this.keyboard.scrolllock = false; if (this.keyboard.puffer.count!= 0) { this.biosstart(); } this.vcard.display("start computer...\n"); this.memory.load(ram.bootaddress, this.hdd.read(hdd.bootsectoraddress, HDD.SectorSize)); this.cpu.jump(ram.bootaddress); this.cpu.execute(); A használatának fő előnye, hogy a nagyon bonyolult metódushívásokat összegyűjthetjük egy metódusba. Az alrendszerek között jelentősen csökkentik az egymástól függést, laza kapcsolat alakítható ki közöttük. 22

3 Viselkedési minták 3.1Command (Parancs) Készítsen egy grafikus számológép alkalmazást, amely Operatorokat, operandusokat (számokat) tartalmaz, Látható a történet, Lehetséges tetszőleges számú művelet visszavonása (Undo), Lehetséges a többszöri ismétlésre (Redo), Véglegesítés (Commit), ilyenkor a történet kezdőpontja az adott pont lesz, előtte levő műveletek nem láthatóak nem vonhatóak vissza, A történetből tetszőleges elem újra elvégezhető. A command pattern-t implementáló számológép alkalmazást WPF-ben írtam meg. Képek az alkalmazásról: 23

24

A feladat megoldásának osztálydiagramja Részei: CalculatorCommand: absztrakt osztály. parancsaihoz biztosít egy absztrakt ősosztályt A CalculatorCommand leszármazottai egymáshoz rendelik a Calculator-t (a fogadó osztályt) és egy-egy műveletet. A Calculator megfelelő metódusainak hívásával implementálják az Execute és az Unexecute metódusokat A számológép o AddCommand: Parancs osztály az összeadáshoz. o SubtractCommand: Parancs osztály a kivonáshoz. o MultiplyCommand: Parancs osztály a szorzáshoz. o DivideCommand: Parancs osztály az osztáshoz. MainWindow: Hívó és ügyfél a modellben. Létrehozza a CalaculatorCommand példányokat és beállítja a fogadó osztályt, felkéri a létrehozott CalculatorCommandot, hogy hajtasa végre (Execute) a műveletet, vagy vonja vissza (UnExecute) a legutóbb végrehajtott műveleteket. Mindig a legutóbb végrehajtott, még nem visszavont műveletet vonja vissza. Calculator: A implementálja. fogadó osztály. 25 A számológép műveleteit

Példa a használatra: Parancsokat hozunk létre végrehajtjuk és tároljuk. calculator = new Calculator(); switch (lastoperation) { case "+": calculatorcommand = new AddCommand(calculator, value); break; case "-": calculatorcommand = new SubtractCommand(calculator, value); break; case "/": calculatorcommand = new DivideCommand(calculator, value); break; case "*": calculatorcommand = new MultiplyCommand(calculator, value); break; default: throw new InvalidOperationException("Operation: " + lastoperation); } calculatorcommand.execute(); Commands.Add(calculatorCommand); Így a kérelmeket objektumokba ágyazzuk, a kliensnek különböző kéréseket adhatunk át, amelyeket sorba rendezhetünk és vissza is vonhatunk. Mivel objektumba vannak ágyazva tudjuk a kéréseket ideiglenesen tárolni, könnyíti a kérések naplózását. 3.2Observer (Megfigyelő) Feladat: Készítsen grafikus alkalmazást, amely - Lehetőséget biztosít egy szín érték beállítására, - Felső részén 3 db csuszka található (R,G,B) színkomponensek állítására, - Alsó részeiben a beállított érték megjelenítése található: 26

o 3 db csak olvasható beviteli mező, o Egy adott színű panel, o 3 oszlop megfelelő magassággal. - Ha változtatjuk a felső részben levő csuszkát, akkor az alsó mezőben levő nézetek frissüljenek automatikusan. Képek az elkészített alkalmazásról: 27

A feladat osztálydiagramja Részei: IColorPickerSubject: Az alany interfész ebben a modellben. Interfész a megfigyelők csatolásához és értesítés küldéshez. IColorPickerObserver: Frissítő interfész az értesítendő objektumoknak. SliderValues: Az alany interfészt implementálja. Három értéket tartalmaz, a csuszkákhoz. A csuszkák változásáról értesítést küld a megfigyelőknek. RGBColor: Megfigyelő interfészt implementáló osztály. Egy színt reprezentál az RGB színkomponensekkel és ecset objektumot, amely színe az adott RGB. Columns: Megfigyelő interfészt implementáló osztály. A három tulajdonsága a három oszlop magassága százalékban. A minta használatával az objektumok létrehozása a következőképpen történik: public class ColorPickerDataContext { private RGBColor rgbcolor; private SliderValues sv; private Columns columnheights; public ColorPickerDataContext() 28

{ this.rgbcolor = new RGBColor(); this.sv = new SliderValues(); this.columnheights = new Columns(); sv.registerobserver(rgbcolor); sv.registerobserver(columnheights); }... Innentől, az sv változások esetén értesíti a megfigyelőit. Az alany és a megfigyelők között laza kapcsolat van. Az alany tud a megfigyelőkről, de egyéb információt nem tud, nincs is szükség rá, hogy tudjon. További előnye, hogy könnyen adható hozzá új megfigyelő, a meglévő kód módosítása nélkül. 3.3Chain of Responsibility (Felelősség lánc) Feladat: Készítsünk egy dialógus alapú grafikus alkalmazást, melyben három gomb (Betöltés, Mentés, Kilépés) található, és két check boksz (automatikus, manuális)! Attól függően, hogy melyik elem van kiválasztva, jelenítsünk meg help információt! A kilépés gomb kivételével minden elemhez legyen segítség információ, a dialógus ablakhoz is! Alakítsuk ki a következő felelősség láncot: Betöltés -> Mentés -> Összes gomb -> Alkalmazás Az általános Handle osztályba kell egy SetNextHandle metódus! Kép az elkészített alkalmazásról: 29

A feladat osztálydiagramja: HelpHandler: A help rendszer kéréseinek kezeléséhez definiál egy interészt. Implementálja a következő egyedhez a kapcsolatot. SaveButtonHandler, LoadButtonHandler, ButtonHelpHandler, FormHelphandler: Lekezeli a megfelelő kéréseket. Hozzáfér az utána következő help handlerhez. Ha tudja kezelni a kérést, akkor kezeli, egyébként továbbítja a következő help handlernek. Client: Létrehozza a láncot, kéréseket indít a lánc elején lévő help handlernek. Az elkészített alkalmazásban a felelősség lánc a következőképpen épül fel:... private HelpHandler starthelphandler; 30

public HelpSystem() { InitializeComponent(); SaveButtonHelpHandler SaveButtonHelpHandler(); LoadButtonHelpHandler LoadButtonHelpHandler(); ButtonHelpHandler bhh FormHelpHandler fhh = sbhh = new lbhh = new = new ButtonHelpHandler(); new FormHelpHandler(); sbhh.setnexthandler(lbhh); lbhh.setnexthandler(bhh); bhh.setnexthandler(fhh); this.starthelphandler = sbhh; }... A lánc kialakítása után help üzenetet a következő metódus állítja be: private void sethelpmessage(object sender) { string name = ((Control)sender).Name; Type type = sender.gettype(); toolstripstatuslabel2.text = this.starthelphandler.handle(name, type); } A minta használatával egyszerűsödik a help információk megjelenítése. Új GUI elem bevezetésével csak egy új osztályt kell elkészíteni, amely a HelpHandlerből származik. A kód többi részét nem kell módosítani. 3.4Mediator (Közvetítő) Közvetítő (Mediátor) minta Feladat szövege: Készítsünk egy dialógus alapú grafikus alkalmazást, melyben o egy városlista lista ablak található a lehetséges elemekkel (városok nevei) 31

o beviteli mező, o másik kiválasztott városok lista a felvett városok neveivel, o töröl gomb A következőképpen működjön: o Ha a városlista egy eleme ki van választva, akkor másoljuk be a szöveg tartalmát a beviteli mezőbe, engedélyezzük a hozzáad gombot o Az átmásolt szöveget a felhasználó át tudja írni. o Ha a hozzáad gombot megnyomtuk, akkor a szöveges mező tartalmát hozzáadja a kiválasztott városok listájába a töröl gomb engedélyezett lesz o Ha a töröl gombot megnyomtuk, akkor a kiválasztott városok lista törlődik, a töröl gomb tiltódik, a hozzáad gomb tiltódik Képek az elkészített alkalmazásról: 32

A feladat osztálydiagramja: 33

Az osztálydiagram részei CityChooserMediator: A közvetítő felület a kollégák között Mediator: Konkrét közvetítő. Ismeri a feladatban szereplő objektumokat. A Copy metódussal a SelectedCity Name property-jét állítja be. Az Add hozzáad egy nevet a városok listájához. A Choose hozzáad egy nevet a kiválasztott városok listájához. CityChooserColleague: Felület a kollégáknak. Ismeri a CityChooserMediatort. City: Konkrét kolléga osztály. Városlistát tartalmaz. A Choose metódussal jelzi a mediátornak, hogy kiválasztottuk egy elemét. Az Add metódussal hozzáad egy nevet a CityList propertyjéhez. A Clear metódus törli az elemeit. SelectedCity: Konkrét kolléga osztály. Egy nevet tartalmaz. A Choose metódussal jelzi a mediátornak, hogy property-jét hozzá kell adni a kiválsztott városokhoz. A minta használata: Példányosítjuk az osztályokat a következő módon: SelectedCity selected; City cities; City choosencities; Mediator m; 34

m = new Mediator(); cities = new City(m); choosencities = new City(m); selected = new SelectedCity(m); m.cities = cities; m.choosencities = choosencities; m.selected = selected; A kollégák ismerik a mediátort, de egymást nem és a mediátor is ismeri a kollégákat. Ez a minta laza kapcsolatot eredményez az objektumok között. Központosított vezérlést eredményez. 3.5State (Állapot) Feladat: Média lejátszó modellezése specifikáció alapján az állapot minta felhasználásával. Műveletek: pillanat állj, stop, előre lejátszás, hátrafele lejátszás, sebesség felező, sebesség kétszerező, elejére teker, végére teker. Alapból a film a 0 pozíción áll, és nem megy a lejátszás (stop állapot). Szimuláljunk egy 30 frame/sec-es videót, ami 5 perces, progressbar segítségével! Írjuk ki az alkalmazás állapotát! Írjuk ki az aktuális frame értékét, frissítsük a progressbart 100 ms-onként! 1. ábra A Média lejátszó Frissítsük a vezérlők értékét az állapottól függően! Működés Állapo t\funk ció Pause Forewar d Backward Pillan at állj Nem érhető el, nem csinál semmit Megállítja a lejátszást, állapotvál tás Megállítja a lejátszást, állapotváltá s 35 Begin Nem érhető el, nem csinál semmit End Nem érhető el, nem csinál semmit

Stop Nem érhető el, nem csinál semmit Megállítja a lejátszást, és a 0 pozícióra állít, állapotvál tás Megállítja a lejátszást, és a 0 pozícióra állít, állapotváltá s Nem érhető el, nem csinál semmit Nem érhető el, nem csinál semmit Előre játszá s Elkezd lejátszani előre 1x sebességg el, állapotvált ás Ha más sebesség gel játszik, akkor visszaállít 1x előre játszásra Nem érhető el, nem csinál semmit Elkezd lejátszani előre 1x sebességgel, állapotváltás Nem érhető el, nem csinál semmit Hátra játszá s Elkezd lejátszani hátrafele 1x sebességg el, állapotvált ás Nem érhető el, nem csinál semmit Ha más sebességge l játszik, akkor visszaállít 1x hátra játszásra Nem érhető el, nem csinál semmit Elkezd lejátszani hátrafele 1x sebességgel, állapotváltás Sebes ség felező Nem érhető el, nem csinál semmit A sebesség et felezi A sebességet felezi Nem érhető el, nem csinál semmit Nem érhető el, nem csinál semmit Sebes ség kétsz erező Nem érhető el, nem csinál semmit A sebesség et kétszerez i A sebességet kétszerezi Nem érhető el, nem csinál semmit Nem érhető el, nem csinál semmit Elejér e ugrik Pozíció a végére Pozíció az elejére, és játszik tovább Pozíció az elejére, és stop állapot Nem érhető el, nem csinál semmit Pozíció az elejére, és nem játszik tovább Végér e ugrik Pozíció az elejére Pozíció a végére, és stop állapot Pozíció a végére, és játszik tovább Pozíció a végére, és nem játszik tovább Nem érhető el, nem csinál semmit Kép az elkészített alkalmazásról: 36

A feladat osztálydiagramja: Részei: MediaPlayer: A állapot környezet osztály. PlayingState: Az MediaPlayer állapot kontextus állapotainak felülete Begin, End, Stop, Pause, PlayingForward, PlayingBackward: Kokrét állapotai a MediaPlayer kontextusnak. A MediaPlayer osztály példányosítása (a Video konstruktorának megadjuk a frame-ek számát és a rátát):... MediaPlayer mp;... 37

Video video = new Video(9000, 30); //five minutes this.mp = new MediaPlayer(video); this.mp.state = new Stop();... A minta használatával egyszerűbb, érthetőbb kódot kapunk. Könnyebb modellezni az összetett állapotokat. Ebben a feladatban volt 8 féle funkció és 6 féle állapot ami a minta használata nélkül ami egy 48 case-t tartalmazó switch lenne a minta nélkül. Könnyebb új állapotot felvenni mint egy hosszú switch case szerkezetet átlátni. 3.6Strategy (Stratégia) Feladat: Bővítsük az előző feladatot több média típus lejátszására Mp3 Wmv Avi Az aktuális média típust is kiírattam az alkalmazásban A futást ábrázoló képen lévő lejátszó így indult A feladat kibővített osztálydiagramja: 38

A diagram részei Media: A wmv, avi és mp3 algoritmuscsaládokhoz ad egy felületet. WMV, AVI, MP3: Konkrét algoritmuscsaládok. Az adott formátumnak megfelelően implementálják a médiát. MediaPlayer: a stratégia környezet osztály a wmv, avi és mp3 algoritmuscsaládokhoz. Az alkalmazásban egy wmv lejátszása a következőképpen történik:... MediaPlayer mp;... Media media = new Wmv(9000, 30); this.mp = new MediaPlayer(media); this.mp.state = new Stop();... A stratégia programtervezési minta használata egyszerűbb, érthetőbb kódot eredményez, mintha ugyanezt a működés a minta használata nélkül érnénk el, mivel a minta elrejti az algoritmus specifikus adatokat. Új algoritmus családdal bővíthetjük a mintát anélkül, hogy bármelyik osztályt módosítani kellene. Az aktuális algoritmus család futásidőben módosítható. 39