Czasem mówi się, że wzorce projektowe uzupełniają braki techniczne w językach programowania. Jeśli spojrzymy na kilka popularnych wzorców, to szybko d

Czasem mówi się, że wzorce projektowe uzupełniają braki techniczne w językach programowania. Jeśli spojrzymy na kilka popularnych wzorców, to szybko dostrzeżemy schemat. Wiele z nich krąży wokół szeroko rozumianego polimorfizmu. Podobnie sprawa ma się z bohaterem dzisiejszego wpisu. Wzorzec metody wytwórczej jest tak popularny i prosty zarazem, że niektórzy programiści prawdopodobnie używają go, nawet nie mając świadomości, że to robią. W praktyce trudno sobie wyobrazić projekt, który wykorzystuje interfejs i kilka jego implementacji, a nie korzysta z tego rozwiązania. Obecnie jednak użycie tego wzorca można trochę ograniczyć przy odpowiedniej konfiguracji IoC, ale o tym nieco więcej w dalszej części wpisu.   Wzorzec metody wytwórczej architektura   Poprawnie zaimplementowany wzorzec metody wytwórczej wykorzystuje cztery standardowe elementy*:

  • interfejs/klasę abstrakcyjną produktu,
  • klasę(y) konkretną produktu,
  • interfejs/klasę abstrakcyjną kreatora,
  • konkretną klasę kreatora.

* Wytłuszczonym drukiem oznaczyłem element sugerowany.   W praktyce bardzo często można zauważyć rozwiązania, w których trzeci element nie istnieje, a czwarty występuje w postaci klasy z wykształconą metodą statyczną. Klasa kreatora definiuje najczęściej parametryzowaną metodę wytwórczą, która służy do konstruowania obiektu implementującego interfejs naszego produktu. Pisałem we wstępie, że jest to prosty wzorzec — i nie kłamałem. Powyższa lista przedstawia maksymalny zakres tego wzorca projektowego.   Wzorzec metody wytwórczej przykład praktyczny   Przykład rozbijemy według punktów przedstawionych w akapicie poświęconym architekturze wzorca. Zaczniemy więc od utworzenia interfejsu produktu. Na potrzeby przykładu wybrałem tematykę motoryzacyjną. W ten sposób powstał prosty interfejs przedstawiający samochód (produkt) i wystawiający metodę, która pozwala na pobranie opisu auta: [sourcecode language="csharp"] public interface ICar { string GetDescription(); } [/sourcecode]   Oczywiście w realnym środowisku można ten interfejs w dowolny sposób rozszerzyć. W kolejnym kroku powstały trzy przykładowe implementacje:   [sourcecode language="csharp"] public class Opel : ICar { public string GetDescription() { return "This is Opel!"; } } public class Ford : ICar { public string GetDescription() { return "This is Ford!"; } } public class Volkswagen : ICar { public string GetDescription() { return "This is Volkswagen!"; } } [/sourcecode]   W ten sposób zrealizowaliśmy pierwsze dwa wymagane punkty. Kolejnym krokiem jest przygotowanie interfejsu (klasy abstrakcyjnej) kreatora:   [sourcecode language="csharp"] public interface ICarFactory { ICar MakeCar(string name); } [/sourcecode]   Oraz jego przykładowej implementacji:   [sourcecode language="csharp"] public class CarFactory : ICarFactory { private readonly Dictionary<string, ICar> cars = new Dictionary<string, ICar>() { { "opel", new Opel() }, { "ford", new Ford() }, { "volkswagen", new Volkswagen() } }; public ICar MakeCar(string name) { ICar car; this.cars.TryGetValue(name, out car); return car; } } [/sourcecode]   Kolejny raz postanowiłem użyć słownika, który pozwala mi na usunięcie switcha. Pierwszy raz tej sztuczki użyłem przy okazji tekstu na temat wzorca strategii. Oczywiście nic nie stoi na przeszkodzie, by użyte tu stringi zastąpić np. enumem.   Standardowo zwieńczeniem przykładu będzie kod klasy Program, która łączy wszystkie elementy w logiczną całość: [sourcecode language="csharp"] public class Program { public static void Main(string[] args) { ICarFactory carFactory = new CarFactory(); var car = carFactory.MakeCar("ford"); Console.WriteLine(car.GetDescription()); Console.Read(); } } [/sourcecode]   IoC a metoda wytwórcza Podobnie jak w przypadku singletona, również tu można częściowo pozbyć się tego wzorca z naszych projektów, w sytuacji gdy korzystamy z techniki IoC. W odniesieniu do popularnego Autofaca powstał cały artykuł na ten temat. Zainteresowanych zachęcam do zapoznania się z zagadnieniem i wybraniem optymalnego rozwiązania, dostosowanego do potrzeb.  

Jerzy Piechowiak

Altcontroldelete.pl

 


 

 Szukasz informacji o C#? Kliknij TU lub zerknij poniżej: