Wykład 7
Transkrypt
Wykład 7
Pool of Objects • Pula obiektów – rozszerzenie idei wzorca Singleton • Pozwala na przesunięcie odpowiedzialności za tworzenie obiektów na oddzielny obiekt • Umożliwia wielokrotne wykorzystanie poszczególnych instancji obiektów • Obiekty reprezentujące zasoby, które są czasowo alokowane na rzecz konkretnego klienta • Pozwala to istotnie ograniczyć koszt związany z tworzeniem i usuwaniem obiektów Technologie obiektowe Pool of Objects • • • • • Najważniejszym elementem jest klasa Pool Zajmuje się tworzeniem instancji klasy ReusableObject oraz zarządzaniem cyklem życia już utworzonych obiektów. Najczęściej klasa ta utrzymuje zbiór aktywnych obiektów ReusableObject, które są przekazywane klientom na żądanie i przyjmowane z powrotem po wykorzystaniu Klasa Pool posiada interfejs służący do tworzenia obiektu (metoda GetInstance()) oraz ich zwracania (returnInstance()) Z punktu widzenia klienta obiekt klasy Pool jest fabryką obiektów, ponieważ klient nie musi się zajmować ich tworzeniem, zarządzaniem, odtwarzaniem itd. Technologie obiektowe Pool of Objects Technologie obiektowe Pool of Objects • Pool – najważniejsze dwie funkcje to zdefiniowanie punktu dostępu do obiektów ReusableObject oraz zarządzanie cyklem ich życia • Obiekt ReusableObject musi posiadać zdefiniowany cykl życia: zestaw metod modyfikujących jego stan. Możliwość ponownego użycia przez innego klienta • Klient żąda obiektu ReusableObject za pomocą obiektu Pool i w ten sam sposób zwalnia przydzielony obiekt. Technologie obiektowe Pool of Objects • Kontenery obsługujące żądania HTTP • Dostęp do bazy danych Technologie obiektowe Factory Method • Podstawowy wzorzec kreacyjny • Zastąpienie prostych wywołań konstruktora, dedykowanym interfejsem (metodą), która przejmie odpowiedzialność za tworzenie i ew. inicjalizację obiektu danej klasy • Singleton jest specjalizowaną wersją FactoryMethod Technologie obiektowe Factory Method Technologie obiektowe Factory Method • Klient odwołuje się do dwóch interfejsów (lub kl. abstrakcyjnych) • • Creator – zawiera metodę tworzącą obiekty (produkty) Product – reprezentuje obiekty tworzone przez FactoryMethod • Oba interfejsy posiadają implementacje powiązane parami: obiekt klasy ConcreteCreator o przeciążonej metodzie factoryMethod(), tworzy instancję obiektu ConcreteProduct. • Podczas zmiany obiektu Creator, zmieniany jest jednocześnie tworzony produkt. Technologie obiektowe Factory method • Dualizm hierarchii klas produktu i kreatora • Abstrakcyjne traktowanie całego procesu tworzenia obiektów za pomocą wymiennych producentów • Z punktu widzenia klienta metoda factoryMethod() jest równoważna pod względem funkcjonalnym z konstruktorem: jej wywołanie powoduje utworzenie obiektu żądanego typu. • Konstruktory nie są polimorficze Factory Method pozwala metodzie tworzącej obiekty na wybór klasy obiektu i sposobu jego tworzenia. Technologie obiektowe Factory Method • Przeniesienie odpowiedzialności za tworzenie obiektów klasy Product z klienta na obiekt klasy Creator. • Wzorzec umożliwia tworzenie nie tylko instancji jednej klasy, ale całych ich hierarchii, z możliwością wyboru klasy i użytego konstruktora. • Bezpośrednie wywołanie konstruktora nie daje takiej możliwości. Technologie obiektowe Abstract Factory • Rozszerzenie koncepcji – Factory Method • Zdefiniowanie interfejsu do tworzenia rodzin obiektów, korzystając z dedykowanych klas zajmujących się produkcją obiektów. • Wzorzec ten służy do tworzenia obiektów, które istnieją w rodzinach (są jakoś ze sobą powiązane) i powinny być tworzone razem Technologie obiektowe Abstract Factory • • • • • Klient odwołuje się klasy AbstractFactory, służącej do tworzenia grupy obiektów. Każdy produkt tworzony jest przez osobną metodą, która sama stosuje wzorzec Factory Method. AbstractFactory jest klasą abstrakcyjną – nie definiuje w jaki sposób mają być tworzone odpowiednie produkty, deklaruje jedynie obecność odpowiedzialnych za to metod. Klient, wybierając odpowiednią fabrykę ConcreteFactory, decyduje jednocześnie o wyborze całej rodziny produktów. To pozwala zmieniać całe rodziny produktów w prosty sposób – posługując się inną implementacją fabryki. Technologie obiektowe Abstract Factory • Zastosowanie tego wzorca pozwala w łatwy sposób zmieniać całe rodziny produktów, zmieniając tylko ich fabrykę. • Ponadto, struktura wzorca pozwala łatwo wydzielić warstwę abstrakcji i implementacji (zarówno w przypadku fabryki jak i produktu) • Szczegóły implementacyjne są niewidoczne dla klienta • Dodawanie kolejnych rodzin produktów wiąże się z koniecznością zaimplementowania także nowej fabryki. Obiekt fabryki i tworzone przez niego obiekty tworzą ze sobą hermetyczną całość • Wzorzec stosuje się w sytuacjach, w których zestaw produktów jest zamknięty Technologie obiektowe Abstract Factory Technologie obiektowe Abstract Factory - przykład Załóżmy, że do picia herbaty używamy określonego zestawu naczyń i sztućców (w tym przykładzie potrzebuję filiżanki, spodka i łyżeczki). Na przykład wszystkie elementy muszą być z chińskiej porcelany, a w innym przypadku muszą być polskie i plastikowe. Technologie obiektowe Abstract Factory - przykład ITeaEquipmentAbstractFactory f = new ChineseTeaEquipment(); //ITeaEquipmentAbstractFactory f = new PolishTeaEquipment(); ICup cup = f.CreateCup(); ISaucer saucer = f.CreateSaucer(); ISpoon spoon = f.CreateSpoon(); Console.WriteLine("Łyżeczka: kolor={0}, długość={1}", spoon.Color, spoon.Length); Console.WriteLine(spoon.SayHello()); Console.WriteLine("Filiżanka: kolor={0}, pojemność={1}", cup.Color, cup.Capacity); Console.WriteLine(cup.SayHello()); Console.WriteLine("Spodek: kolor={0}, średnica={1}", saucer.Color, saucer.Diameter); Console.WriteLine(saucer.SayHello()); Technologie obiektowe Abstract factory – przykład cd. // Fabryka abstrakcyjna do tworzenia zestawu do picia herbaty interface ITeaEquipmentAbstractFactory { ICup CreateCup(); ISpoon CreateSpoon(); ISaucer CreateSaucer(); } // Fabryka konkretna #1 class ChineseTeaEquipment : ITeaEquipmentAbstractFactory { public ICup CreateCup() { return new ChineseCup(); } public ISpoon CreateSpoon() { return new ChineseSpoon(); } public ISaucer CreateSaucer() { return new ChineseSaucer(); } } Technologie obiektowe // Obiekty abstrakcyjne interface ICup : ITeaEquipmentItem { int Capacity { get; } } // Obiekty konkretne class ChineseCup : ICup { public int Capacity { get { return 10; } } public System.Drawing.Color Color { get { return System.Drawing.Color.White; } } public string SayHello() { return "I'm Chinese cup."; } } Abstract factory • Ktoś inny może sobie teraz łatwo utworzyć inny rodzaj zestawu do picia herbaty i nie będzie wtedy trzeba w ogóle modyfikować kodu klienta! • Wada fabryki abstrakcyjnej: Jeśli nagle zajdzie potrzeba dodania nowego obiektu, to taka operacja nie jest zbyt wygodna, bo wymaga dość sporo wysiłku i modyfikacji kodu w wielu miejscach. • Zestaw do picia herbaty jest od lat taki sam i potrzeba dodania nowego elementu raczej nie zajdzie. Technologie obiektowe Builder • Budowniczy (Builder) oddziela specyfikację (definicję) jakiegoś złożonego obiektu od procesu jego konstruowania. • We wzorcu tym nacisk jest położony na konstruowanie złożonych obiektów krok po kroku (etapami). • Części muszą być tworzone w jakiejś kolejności lub przy użyciu określonego algorytmu. Technologie obiektowe Builder - budowniczy • Struktura wzorca przypomina podział ról na budowie. • Klient odpowiada za zlecenie wykonania prac. • Odbiorcą zlecenia jest kierownik budowy (Director), który posiada projekt budowlany (Algorytm realizacji struktury) • Kierownik zna i dysponuje specjalistami od różnych dziedzin (klasy implementujące interfejs Builder) • Każdy z fachowców (swego rodzaju Factory) potrafi wykonywać produkty jednego rodzaju i przekazywać je kierownikowi. • Kierownik na podstawie projektu składa elementy tworzone przez fachowców i konstruuje strukturę i przekazuje klientowi. Technologie obiektowe Builder Technologie obiektowe Builder • • • • Bardzo wyraźny podział na warstwy różniące się odpowiedzialnością. Director odpowiada za zarządzanie obiektami typu Builder i zlecanie im prac. Zna on algorytm łączenia elementów składowych w całość. Każdy ConcreteBuilder związany jest z produktem, który umie wyprodukować. Zmiana implementacji obiektów Product nie wpływa na proces konstrukcji struktury. Technologie obiektowe Builder Kolejne kroki scenariusza budowania produktu: 1. Tworzymy instancję Konkretnego budowniczego odpowiedniego do oczekiwanego wariantu produktu. 2. Tworzymy instancję Nadzorcy i przekazujemy do niego referencję budowniczego. 3. Uruchamiamy w Nadzorcy metodę konstrukcji produktu, która zapewni użycie odpowiedniej sekwencji metod Budowniczego. 4. Po stworzeniu produktu pobieramy go od Nadzorcy. Technologie obiektowe Prototype Umożliwienie tworzenia obiektów na podstawie przykładowej instancji, a nie przez wywołanie konstruktora. Zupełnie inny sposób tworzenia obiektów niż Factory Method/Sigleton. Celem jego stosowania jest tworzenie nowych obiektów przez klonowanie już istniejącego wzorcowego obiektu. Obiekt poddawany klonowaniu Prototype posiada metodę clone() Metoda ta jest implementowana we wszystkich jego obiektach potomnych w ten sposób, że tworzy dokładną kopię bieżącego obiektu. Odrębna tożsamość obiektu. Klient żądając utworzenia kopii obiektu Prototype, wywołuje w bieżącej instancji metodę clone() Technologie obiektowe Prototype Technologie obiektowe Prototype W języku C# do implementacji prototypów można zastosować interfejs ICloneable Technologie obiektowe Wzorce kreacyjne • • • • • Singleton Factory Method Abstract Factory Prototype Builder Czym się różnią? Kiedy stosować? Technologie obiektowe Uwagi Performance: Cloning (using MemberwiseClone) is considerably less expensive than creating a new object afresh (with new operator). Note that one needs to override the MemberwiseClose() to perform a deep copy. Prototype pattern allows an object to create customized objects without knowing their class or any details of how to create them. So, it is this aspect it appears to be a lot like the Factory Method pattern. In both these patterns, the client can create any of the derived class objects without knowing anything about their own structure. But the difference between the two patterns is the fact that for the Factory Method concentrates on creating one object of a non existing object type as a fresh creation (by understanding the exact sub-type of the Creator class). The Prototype pattern Technologie obiektowe In this pattern, the client (or consumer) asks the Creator (or factory) for a specific type of object from a class hierarchy. The Creator method of the factory class delegates the creation of the specific object to the derived classes and return the object of the class of the type asked by client. In essence, you have a single point of contact for the creation of several objects of a class hierarchy. You can think of this as going to a airline ticket counter (controller) and asking for a ticket by giving your preference of the ticket type (first class, executive or economy). The user is not concerned with how the ticket is being generated, even though in an object representation the first class and the economy ticket are both derived from the base ticket class. Technologie obiektowe Abstract factory goes a step higher (more abstract) than the factory method pattern. In this case, one can have not just a single, but multiple factories with slight variations. It is responsible for creating objects belonging families of class hierarchies rather than just a single class hierarchy. A specific Factory class already exists. But the Factory will have slightly varying methods. Each method can produce an instance. The client can choose appropriate method and get the instance. Technologie obiektowe Abstract factory vs. Builder • • • • Mark #1: Both patterns have used a generic class as the entry-class. The only difference is the name of the class. One pattern has named it as “Client”, while the other named it as “Director”. Mark #2: Here again the difference is the class name. It is “AbstractFactory” for one and “Builder” for the other. Additionally both classes are of type abstract. Mark #3: Once again both patterns have defined two generic (WindowsFactory & ConcreteBuilder) classes. They both have created by inheriting their respective abstract class. Mark #4: Finally, both seem to produce some kind of a generic output. Technologie obiektowe Abstract factory vs. Builder • Abstract Factory: Emphasizes a family of product objects (either simple or complex) • Builder: Focuses on constructing a complex object step by step • Abstract Factory: Focus on *what* is made • Builder: Focus on *how* it is made • Abstract Factory: Focus on defining many different types of *factories* to build many *products*, and it is not a one builder for just one product • Builder: Focus on building a one complex but one single *product* • Abstract Factory: Defers the choice of what concrete type of object to make until run time • Builder: Hide the logic/ operation of how to compile that complex object • Abstract Factory: *Every* method call creates and returns different objects • Builder: Only the *last* method call returns the object, while other calls partially build the object Technologie obiektowe Jeszcze … Sometimes creational patterns are complementary: So you can join one or many patterns when you design your system. As an example builder can use one of the other patterns to implement which components get built or in another case Abstract Factory, Builder, and Prototype can use Singleton in their implementations. So the conclusion would be that the two design patterns exist to resolve two type of business problems, so even though they look similar, they are not. Technologie obiektowe