Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014 6. előadás Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014
Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014 Tervezési minták Eddig Singleton (Egyke) Simple Factory Ma Adapter (Illesztő) Bridge (Híd) Composite (Összetétel) Observer (Megfigyelő) Strategy Dependency injection Template Method (Sablonfüggvény) MVC,MVP Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014
Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014 Adapter - Illesztő A cél egy olyan új osztály/objektum létrehozása, ami a korábbi osztály felhasználásával megvalósít egy elvárt új interfészt Például: a korábbi osztály rendelkezik Vezetéknév és Utónév tulajdonságokkal, de Teljesnév tulajdonsággal nem, és nekünk erre a tulajdonságra van szükségünk Megvalósítási módok Öröklődés Beágyazás Kiegészítés Bővítő metódus Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014
Megoldás öröklődéssel public class Alap { public Alap(string V, string U) { Vezetéknév = V; Utónév = U; } public string Vezetéknév{ get; set; } public string Utónév { get; set; } Előfeltétel, hogy az alap osztály ne legyen sealed Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014
Megoldás öröklődéssel public class Leszármazott:Alap { public Leszármazott(string V, string U):base(V,U){} public string Teljesnév { get { return Vezetéknév + " " + Utónév; } } } Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014
Megoldás öröklődéssel static void Main(string[] args) { Leszármazott l = new Leszármazott("Duli", "Fuli"); Console.WriteLine(l.Teljesnév); Console.ReadLine(); } Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014
Megoldás beágyazással public class Beágyazott { Alap Alap; public string Teljesnév { get { return Alap.Vezetéknév + " " + Alap.Utónév; } } public string Vezetéknév get { return Alap.Vezetéknév; } set { Alap.Vezetéknév = value; } public string Utónév get { return Alap.Utónév; } set { Alap.Utónév = value; } public Beágyazott(string V,string U) Alap = new Alap(V,U); Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014
Megoldás beágyazással static void Main(string[] args) { Beágyazott b = new Beágyazott("Zsákos", "Bilbó"); Console.WriteLine(b.Teljesnév); Console.ReadLine(); } Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014
Megoldás kiegészítéssel public partial class Alap { public Alap(string V, string U) { Vezetéknév = V; Utónév = U; } public string Vezetéknév { get; set; } public string Utónév { get; set; } Előfeltétel, hogy az alap osztály el legyen látva partial jelzővel Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014
Megoldás kiegészítéssel public partial class Alap { public string Teljesnév get return Vezetéknév + " " + Utónév; } Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014
Megoldás kiegészítéssel static void Main(string[] args) { Alap a = new Alap("Zsákos", "Frodó"); Console.WriteLine(a.Teljesnév); Console.ReadLine(); } Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014
Megoldás bővítő metódussal Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014
Megoldás bővítő metódussal public sealed class Alap { public Alap(string V, string U) { Vezetéknév = V; Utónév = U; } public string Vezetéknév { get; set; } public string Utónév { get; set; } Jól alkalmazható olyankor is, ha a származtatás tiltott. Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014
Megoldás bővítő metódussal public static class Bővítő { public static string Teljesnév(this Alap a) return a.Vezetéknév + " " + a.Utónév; } Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014
Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014 Bridge - Híd Egy képzeletbeli okos TV, amivel nézhetünk Kábel TV-t Műholdas adást IPTV-t A felhasználó lekérheti a műsort (Guide) és indíthatja a kiválasztott műsorforrás megtekintését Absztrakció: műsor lekérés, indítás Minden műsorforrás esetén más a megvalósítás Forrás: http://www.codeproject.com/Articles/434352/Understanding-and-Implementing-Bridge-Pattern-in-C Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014
Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014
Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014 Interfész interface IVideoSource { string GetTvGuide(); string PlayVideo(); } Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014
Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014 Megvalósítás class LocalCabelTv : IVideoSource { const string SOURCE_NAME = "Local Cabel TV"; string IVideoSource.GetTvGuide() return string.Format("Getting TV guide from - {0}", SOURCE_NAME); } string IVideoSource.PlayVideo() return string.Format("Playing - {0}", SOURCE_NAME); Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014
Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014 LocalDishTv class LocalDishTv : IVideoSource { const string SOURCE_NAME = "Local DISH TV"; string IVideoSource.GetTvGuide() return string.Format("Getting TV guide from - {0}", SOURCE_NAME); } string IVideoSource.PlayVideo() return string.Format("Playing - {0}", SOURCE_NAME); Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014
Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014 IPTvService class IPTvService: IVideoSource { const string SOURCE_NAME = "IP TV"; string IVideoSource.GetTvGuide() return string.Format("Getting TV guide from - {0}", SOURCE_NAME); } string IVideoSource.PlayVideo() return string.Format("Playing - {0}", SOURCE_NAME); Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014
Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014 RefinedAbstraction class MySuperSmartTV { IVideoSource currentVideoSource = null; public IVideoSource VideoSource { get { return currentVideoSource; } set { currentVideoSource = value;} } public void ShowTvGuide() { if (currentVideoSource != null) { Console.WriteLine(currentVideoSource.GetTvGuide()); else { Console.WriteLine("Please select a Video Source to get TV"+ " guide from"); Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014
Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014 RefinedAbstraction public void PlayTV() { if (currentVideoSource != null) Console.WriteLine(currentVideoSource.PlayVideo()); } else Console.WriteLine( "Please select a Video Source to play"); } } } Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014
Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014 class SuperSmartTvController { static void Main(string[] args) { MySuperSmartTV myTv = new MySuperSmartTV(); Console.WriteLine("Select A source to get TV Guide and Play"); Console.WriteLine("1. Local Cable TV\n2. Local Dish TV\n3. IP TV"); ConsoleKeyInfo input = Console.ReadKey(); switch (input.KeyChar) { case '1': myTv.VideoSource = new LocalCabelTv(); break; case '2': myTv.VideoSource = new LocalDishTv(); break; case '3': myTv.VideoSource = new IPTvService(); break; } myTv.ShowTvGuide(); myTv.PlayTV(); } } Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014
Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014 Futás Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014
Composite - Összetétel A Composite tervezési mintát olyan feladatokhoz találták ki, ahol egy objektum szerepelhet önálló egységként és szerepelhet objektumok gyűjteményeként. Pl. egy kép objektum lehet egy önálló rajzegység (pl. egy vonal ), de összefoghat további vonal, téglalap, rajz objektumokat is, mint az ábra esetében. Az objektumok ilyetén szerkezetére tekintsünk úgy, mint egy faszerkezetre. Forrás: Mathias Bartoll, Nori Ahari, Oliver C. Moldez: Design Patterns in C# Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014
Az összetétel minta szerkezete A feladat megoldására az Összetétel tervezési minta a következőket javasolja. Készítsünk egy absztrakt osztályt (Component), ami tartalmazza a megjelenítéshez (Operation()), új gyermek hozzáadásához (Add()), gyermek eltávolításához (Remove()), gyermekek lekérdezéséhez (GetChild()), stb. szükséges metódusok deklarációit. A Component osztálynak két leszármazottja van: Egy olyan, amiből levél objektum lesz a fában (Leaf), azaz olyan, ami már nem tartalmaz gyermek objektumokat (pl. vonal, téglalap). Ha ehhez egy gyermeket próbálunk hozzáadni, kivétel keletkezik. Egy olyan, ami gyermekeket tartalmazhat (Composite). Amikor egy ilyen objektumon meghívjuk az Operation metódust, akkor ő meghívja minden gyermek objektumára az Operation metódust. A gyermek objektumok esetén csak azt adjuk meg, hogy típusuk Component absztrakt osztály leszármazottja kell legyen. Az „ügyfél” osztály, aki igénybe veszi ezt a fajta megoldást egy Component típusú (azaz annak egy leszármazott típusával rendelkező) osztállyal kerül kapcsolatba. Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014
Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014 Implemen-táció Nézzünk meg egy egyszerűsített implementációt az Összetétel tervezési mintához. Az absztrakt osztállyal kezdünk, neve legyen graphic. Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014
Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014 line osztály levél A levél objektum típusát megvalósító line osztály. A másik levél osztály a text. Implementációja hasonló a text-hez. Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014
Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014 Picture osztály csomópont Picture osztály A csomópont osztály implementációja Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014
Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014 Observer - Megfigyelő A megfigyelő minta lehetővé teszi, hogy a rendszer egy része értesüljön arról, hogy a rendszer egy más részében bekövetkezik egy esemény. Ez 1:n függőségi kapcsolat az objektumok között. Ha a kiemelt objektum állapota változik, akkor a függő objektumok automatikusan értesülnek (és frissülnek). Alkalmazási terület: ha egy objektumban bekövetkező változás esetén több más objektum változtatása szükséges. Szerepkörök: A Subject a megfigyelés tárgya. Ebből egy van. Kell rendelkezzen egy olyan interfésszel, ami lehetővé teszi, hogy a megfigyelők futási időben rákapcsolódhassanak illetve lekapcsolódhassanak. Ezt biztosítják az Attach és a Detach metódusok. Az Observer a megfigyelő. Ebből lehet több. Kell rendelkezzen egy olyan interfésszel, ami lehetővé teszi, hogy értesítést fogadjon a Subject-től. Ezt biztosítja az Update() metódus. A gyakorlatban ez nem jelent mást, mint eseményvezérelt alkalmazás fejlesztését. A Subject eseményt tesz közzé, amire az Observer eseménykezelő metódusa feliratkozik. Az Observer mintát valósítja meg a klasszikus közzétevő-feliratkozó modell, amivel Vizuális programozás tárgy keretében találkoztunk. Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014
Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014 Közzétevő osztály A Stock a közzétevő osztály. Definiál egy eseményt (AskPriceChanged) és egy metódusreferenciát (AskPriceDelegate), ami meghatározza, hogy milyen szignatúrájú metódus lehet eseménykezelő, azaz iratkozhat fel az eseményre. Ha az AskPrice tulajdonság értéke változik, akkor előállítja az eseményt. Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014
Megfigyelő (feliratkozó) Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014
Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014 Fel/leiratkozás Mindkét osztályból létrehozunk egy-egy példányt, majd az AskPriceChanged metódust beregisztráljuk az eseményhez (feliratkozás). Egy ideig várakozik, majd ha lefutott a ciklus leiratkozik az eseményről. Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014
Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014 Strategy - stratégia Egy algoritmus családot definiál, befoglalja és cserélhetővé teszi az érintett algoritmusokat. Olyan esetekben ajánlott az alkalmazása, amikor egy alkalmazás egy bizonyos szolgáltatást igényel, és ez a szolgáltatás többféleképpen oldható meg. Az algoritmus kiválasztás történhet a felhasználó által vagy számítási hatékonyság, stb. alapján. Péda: különböző tömörítési eljárások alkalmazása, mentés különböző formátumokba. Általában mindegyik viselkedési módot/megoldást külön osztállyal (ConcreteStrategyA..C) valósítják meg. Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014
Megoldások/stratégiák Mindegyik megoldás (stratégia) a Strategy interfészt kell megvalósítsa, ami azt jelenti, hogy implementálnia kell az AlgorithmInterface metódust. Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014
Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014 Illesztő modul Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014
Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014 Használat Az ügyfélmodul az illesztő modulnak (Context) megadja, hogy melyik stratégiát kell alkalmazni, majd igénybe veszi a szolgáltatást a ContextInterface metódus meghívásával. Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014
Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014 Dependency Injection Interfész konkrét osztálynév helyett A Client csak az IService interfészről kell tudjon, az azt megvalósító Service osztály nevét nem kell ismerje Megoldások Constructor Injection Property (Setter) Injection Method Injection Forrás: http://www.dotnet-tricks.com/Tutorial/dependencyinjection/67LX120413-Implementation-of-Dependency-Injection-Pattern-in-C Osztályok és komponensek közötti laza csatolást tesz lehetővé. Az erős kapcsolatok elkerülése könnyebbé teszi a későbbi változtatásokat és a kód karbantartást. „Építő” (builder) objektumokat használ az objektumok inicializálásához és lehetővé teszi, hogy az objektumok közötti függőségeket „befecskendezzük” (inject) az osztályon kívülről. Reduces class coupling Increases code reusing Improves code maintainability Improves application testing Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014
Constructor Injection A szolgáltatást nyújtó osztály public interface IService { void Serve(); } public class Service : IService public void Serve() Console.WriteLine("Service Called"); //To Do: Some Stuff This is the most common DI. Dependency Injection is done by supplying the DEPENDENCY through the class’s constructor when instantiating that class. Injected component can be used anywhere within the class. Should be used when the injected dependency is required for the class to function. It addresses the most common scenario where a class requires one or more dependencies. Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014
Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014 Az ügyfél osztály public class Client { private IService _service; public Client(IService service) { this._service = service; } public void Start() Console.WriteLine("Service Started"); this._service.Serve(); //To Do: Some Stuff A konstruktor paraméterként megkapja a szolgáltatást végző objektum referenciáját. A szolgáltatás a Start metódus meghívásával indítható. Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014
Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014 Használat class Program { static void Main(string[] args) { client = new Client(new Service()); client.Start(); Console.ReadKey(); } Itt a Program osztály látja el az építő szerepet. Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014
Property (Setter) Injection A szolgáltatást nyújtó osztály public interface IService { void Serve(); } public class Service : IService public void Serve() Console.WriteLine("Service Called"); //To Do: Some Stuff Also called Setter injection. Used when a class has optional dependencies, or where the implementations may need to be swapped. Different logger implementations could be used this way. May require checking for a provided implementation throughout the class(need to check for null before using it). Does not require adding or modifying constructors. Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014
Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014 Az ügyfél osztály public class Client { private IService _service; public IService Service { set { this._service = value; } public void Start() { Console.WriteLine("Service Started"); this._service.Serve(); //To Do: Some Stuff Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014
Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014 Használat class Program { static void Main(string[] args) Client client = new Client(); client.Service = new Service(); client.Start(); Console.ReadKey(); } Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014
Method Injection A szolgáltatást nyújtó osztály public interface IService { void Serve(); } public class Service : IService public void Serve() Console.WriteLine("Service Called"); //To Do: Some Stuff Inject the dependency into a single method, for use by that method. Could be useful where the whole class does not need the dependency, just the one method. Generally uncommon, usually used for edge cases. Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014
Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014 Az ügyfél osztály public class Client { private IService _service; public void Start(IService Service) { this._service=Service Console.WriteLine("Service Started"); this._service.Serve(); //To Do: Some Stuff } Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014
Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014 Használat class Program { static void Main(string[] args) Client client = new Client(); client.Start(new Service()); Console.ReadKey(); } További olvasmány: http://en.wikipedia.org/wiki/Dependency_injection Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014
Template Method - Sablonfüggvény http://www.dofactory.com/Patterns/PatternTemplate.aspx#_self1 Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014
Az absztrakt ős osztály abstract class AbstractClass { public abstract void PrimitiveOperation1(); public abstract void PrimitiveOperation2(); // The "Template method" public void TemplateMethod() { PrimitiveOperation1(); PrimitiveOperation2(); Console.WriteLine(""); } } Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014
Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014 Leszármazott - A class ConcreteClassA : AbstractClass { public override void PrimitiveOperation1() { Console.WriteLine("ConcreteClassA.PrimitiveOperation1()"); } public override void PrimitiveOperation2() Console.WriteLine("ConcreteClassA.PrimitiveOperation2()"); } Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014
Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014 Leszármazott - B class ConcreteClassB : AbstractClass { public override void PrimitiveOperation1() { Console.WriteLine("ConcreteClassB.PrimitiveOperation1()"); } public override void PrimitiveOperation2() Console.WriteLine("ConcreteClassB.PrimitiveOperation2()"); } Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014
Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014 Használat class MainApp { /// <summary> /// Entry point into console application. /// </summary> static void Main() { AbstractClass aA = new ConcreteClassA(); aA.TemplateMethod(); AbstractClass aB = new ConcreteClassB(); aB.TemplateMethod(); // Wait for user Console.ReadKey(); } } Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014
Model-View-Controller (MVC) Modell – az üzleti logikát megvalósító komponens View – a felhasználói felületet megvalósító réteg, egy modellhez több nézet is tartozhat Controller – módosításokat hajt végre a modellen (meghívja a modell metódusait), lehetővé teszi az aktuális nézet kiválasztását, fogadja a nézettől érkező felhasználói utasításokat – ez a komponens felelős az alkalmazás kezeléséért Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014 Forrás: http://www.tankonyvtar.hu/hu/tartalom/tamop425/0038_informatika_Projektlabor/ch01s04.html
Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014 MVC alapelvek „Loose coupling” „Program to the interface” Eredmények Jobb karbantarthatóság Könnyebb újrahasznosíthatóság Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014
Model-View-Presenter (MVP) Az MVC továbbfejlesztése. Fő változás: a modell a megjelenítőt értesíti a változásról. A fejlesztés célja, hogy a nézetben a lehető legkevesebb logika legyen Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014 Forrás: http://www.tankonyvtar.hu/hu/tartalom/tamop425/0038_informatika_Projektlabor/ch01s04.html
Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014 MVC<->MVP Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014
MVVM Unit Tests View Integration Tests ViewModel Model Service Proxies XAML, Code Behind Bindings Behavior Actions ViewModel Properties, Commands, View Logic Data Events Model Service Proxies Web Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014 Forrás: http://houseofbilz.net/codemash/MVVM.ppt
Tervezési minták osztályozása Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014 Forrás:http://nik.uni-obuda.hu/erdelyi/CASE/DesignPattern_Singleton.pdf
Tervezési minták osztályozása Létrehozási Szerkezeti Viselkedési Singleton (Egyke) Adapter Observer Simple Factory Bridge Strategy Dependency Injection Composite Template Method MVC MVP Dr. Johanyák Zs. Csaba - Szoftvertechnológia - 2014