Factory Method – wzorce projektowe

Ten wpis będzie dotyczył kolejnego ze wzorców projektowych z kategorii wzorców konstrukcyjnych – Matoda Wytwórcza (ang. Factory Method).

Factory Method

Wzorzec ten udostępnia interfejs do tworzenia obiektów, gdzie samym utworzeniem zajmują się podklasy.

Składowe:

  1. Product – jest interfejsem obiektów generowanych przez metodę wytwórczą. Może być interfejsem lub klasą abstrakcyjną.
  2. ConcreteProduct – implementuje interfejs klasy Product.
  3. Creator – zawiera w sobie bazową metodę wytwórczą która zwraca domyślny typ produktu, czyli obiekt typu Produkt. Można tu również zaimplementować rozwiązanie pozwalające na wybranie konkretnego kreatora w zależności od podanego parametru.
  4. ConcreteCreator – przesłania bazową metodę wytwórczą w kreatorze. Zwraca pożądany obiekt typu ConcreteProdukt.

Poniżej znajduje się diagram obrazujący jak to mniej więcej wygląda

Factory Method UML class diagram.svg
By Trashtoy – My own work written with text editor., Domena publiczna, Link

Zastosowanie:

  • Metody wytwórcze są stosowane w wielu pakietach narzędziowych.
  • Można oprzeć na nich system obsługi wtyczek w aplikacji.
  • Gdy ciężko jest przewidzieć jakiej klasy mają być wytworzone obiekty.
  • Jeżeli chcemy, aby to podklasy danej klasy określały tworzone obiekty.

Przykładowy kod

  1. Tworzymy sobie część odpowiedzialną za nasz Product i ConcreteProdukt, czy interfejs IArchive oraz klasy ZipArchive i RarArchive
    public interface IArchive {
            void ChooseLibrary();
        }
    
        class ZipArchive : IArchive
        {
            public void ChooseLibrary()
            {
                Console.WriteLine("I chooses ZIP library to make a zip file");
            }
        }
    
        class RarArchive : IArchive
        {
            public void ChooseLibrary()
            {
                Console.WriteLine("I chooses RAR library to make a rar file");
            }
        }
  2. Teraz kolej na nas Creator. Będzie on również posiadał statyczną metodę wybierającą ConcreteProduct na podstawie przekazanego parametru. W tym przypadku enuma ArchiveType
        public abstract class Creator {
            public enum ArchiveType {
                RAR,
                ZIP,
            }
    
            public abstract IArchive CreateArchive ();
    
            public static Creator CreateCreator (Creator.ArchiveType type) {
                switch (type) {
                    case ArchiveType.RAR:
                        return new RarCreator ();
                    case ArchiveType.ZIP:
                        return new ZipCreator ();
                    default:
                        return null;
                }
            }
        }
    
  3. Nadeszła kolej na nasze ConcreteProducts, które przesłaniają metodę metody wytwórczej
        public class RarCreator : Creator {
            public override IArchive CreateArchive () {
                return new RarArchive ();
            }
        }
    
        public class ZipCreator : Creator {
            public override IArchive CreateArchive () {
                return new ZipArchive ();
            }
        }
    
  4. Nie pozostaje nic innego jak sprawdzenie, czy wszystko działa tak jak tego oczekujemy
        class Program {
            static void Main (string[] args) {
    
                Creator creator = Creator.CreateCreator(Creator.ArchiveType.RAR);
                IArchive archive = creator.CreateArchive();
    
                archive.ChooseLibrary();
    
                Console.WriteLine("-----------------------");
    
                creator = Creator.CreateCreator(Creator.ArchiveType.ZIP);
                archive = creator.CreateArchive();
    
                archive.ChooseLibrary();
    
                Console.ReadLine();
            }
        }
    

Wynikiem w konsoli będzie:

I chooses RAR library to make a rar file
———————–
I chooses ZIP library to make a zip file

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *