niedziela, 25 grudnia 2011

Prototype Design Pattern

Wzorzec Prototype (prototyp) - mówi o tworzeniu obiektów na podstawie prototypu. Jak inne wzorce z grupy wzorców kreacyjnych, wzorzec ten ukrywa przed klientem proces tworzenia obiektu. W przeciwieństwie do innych obiektów, wzorzec ten tworzy kolejne obiekty na podstawie prototypu - klasy która została zainicjowana początkowymi wartościami. Wykorzystanie tego wzorca nie jest duże w przypadku aplikacji biznesowych, przydaje się on natomiast w przypadku aplikacji używanych przez inżynierów.
W .NET istnieje interfejs ICloneable, który dostarcza metody Clone.
Spójrzmy na diagram klas dla tego wzorca:






Klasy, które uczestniczą we wzorcu:
Prototype - udostępnia interfejs klonowania obiektu
ConcretePrototype1 i ConcretePrototype2 - implementują interfejs Prototype dając możliwość klonowania samego siebie
Client - tworzy nowe obiektu poprzez wywołanie metody Clone

Jak wspominałem wcześniej w .NET istnieje już gotowy interfejs ICloneable. Zobaczmy w jaki sposób można go zaimplementować:


Code:
using System;

namespace PrototypeExample
{
    class Program
    {
        static void Main(string[] args)
        {
            var person = new Person{FirstName = "Jacek", LastName = "Kowalski", BirthYear = 2000};
            Console.WriteLine(person);
            var clone = person.Clone();
            Console.WriteLine(clone);
        }
    }

    class Person : ICloneable
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public int BirthYear { get; set; }

        public override string ToString()
        {
            return string.Format("{0} {1} {2}", FirstName, LastName, BirthYear);
        }

        public object Clone()
        {
            return new Person{FirstName = FirstName, LastName = LastName, BirthYear = BirthYear};
            //equals to: return this.MemberwiseClone();
        }
    }
}

W kodzie w metodzie Clone widać zakomentowany kod. Otóż należy być bardzo uważnym podczas implementowania metody Clone. Chodzi o to iż są dwa rodzaje klonowania - deep copy oraz shell copy. Shell copy wykonuje tzw. płytką kopię czyli przepisuje wartości pól. Deep copy przepisuje to co znajduje się pod danym polem. Jeżeli jakieś pole jest referencją, to w przypadku shell copy przepiszemy tylko tę referencję, jeżeli mamy do czynienia z deep copy - obiekt zostanie skopiowany.

Miejmy powyższe zdanie w pamięci i zgodnie z zaleceniami większości deweloperów, podczas implementowania interfejsu ICloneable implementujmy deep copy.

Brak komentarzy:

Prześlij komentarz