wtorek, 24 lipca 2012

[Wzorce projektowe] Prototype

Analogia z życia:

Podróżując lubimy robić zdjęcia. Są one pamiątką z miejsc, które odwiedziliśmy i chwil, które przeżyliśmy. Może się tak zdarzyć, że wywołamy pewne zdjęcie, na którym jest grupa osób. Gdy każda z tych osób obejrzy zdjęcie, dojdzie do wniosku, że chce takie samo. Możemy oczywiście zebrać całą grupę, pojechać w to samo miejsce i zrobić jeszcze zdjęcie kilka razy. Ale na 100% będzie ono inne, a jego zrobienie będzie nas kosztowało sporo wysiłku, czasu a może i pieniędzy. Można także zrobić kopię u fotografa, przez co zaoszczędzimy sobie wymienionych kłopotów.

Zastosowanie:

Prototyp jest jednym z najprostszych, o ile nie najprostszym wzorcem projektowym. Stosuje się go wszędzie tam, gdzie jest potrzebna kopia pewnego obiektu, a jej utworzenie w sposób tradycyjny wydaje się bezsensowne. Proces tworzenia może być np. bardzo długi (pobieranie z bazy danych, pobieranie pliku), W innym przypadku odtworzenie obiektu może wymagać wywołania szeregu metod lub też stan obiektu może być w pewnym sensie niestabilny i trudny do odtworzenie w ogóle.


Zasada działania:


Używając języka C# wystarczy zaimplementować interfejs ICloneable dla obiektu, który chcemy klonować, pamiętając o zasadach tworzenia kopii : Deep vs Shallow Copy. Dla obiektów z propercjami prostych typów wystarczy metoda MemberwiseClone().

Przykład implementacyjny:


public class RandomMelody : ICloneable
    {
        public List<int> Frequencies { get; set; }
        public List<int> Durations { get; set; }

        internal RandomMelody(){}

        public RandomMelody(int n)
        {
            Frequencies = new List<int>();
            Durations = new List<int>();

            Random r = new Random();

            for (int i = 0; i < n; i++)
            {
                Frequencies.Add((r.Next()%300) + 400);
                Durations.Add((r.Next() % 25) + 100);
            }
        }

        public void Play()
        {
            for (int i = 0; i < Frequencies.Count; i++)
            {
                Console.Beep(Frequencies[i], Durations[i]);
            }
        }

        public object Clone()
        {
            var rm = new RandomMelody();
            rm.Durations = new List<int>();
            rm.Frequencies = new List<int>();
            for (int i = 0; i < Durations.Count; i++)
            {
                rm.Durations.Add(Durations[i]);
                rm.Frequencies.Add(Frequencies[i]);
            }
            return rm;
        }
 class Program
    {
        static void Main(string[] args)
        {
            var s1 = new RandomMelody(10);
            var s2 = new RandomMelody(10);
            var s3 = s1.Clone() as RandomMelody;

            Console.WriteLine("Original song");
            s1.Play();
            Console.WriteLine("New song");
            s2.Play();
            Console.WriteLine("Original song");
            s1.Play();
            Console.WriteLine("Copy");
            s3.Play();
        }
    }

Brak komentarzy:

Prześlij komentarz