Prototype Design Pattern
Merhaba sevgili pattern severler;
Köşemizin bu haftaki konuğu: Prototype Design Pattern. Kendisine hoş geldin diyoruz.
Prototype: Hoş bulduk Şişman Adam. Beni davet ettiğin için ben teşekkür ederim.
Evet; okurlarımız seni çok merak ediyorlar. Bize biraz kendinden bahseder misin?
Prototype: Elbette. Ben de Yaratımsal Tasarım Kalıpları (Creational Design Patterns) kategorisi altında yer alan desenlerden biriyim. Haliyle ben de bir nesne yaratılırken programcının karşısına çıkabilecek bir problemi çözmek üzere geliştirildim. Önce size problemi izah edeyim. Üretilip belleğe aktarılması zaman açısından maliyetli olan bir nesne olduğunu varsayalım. Ayrıca uygulamanızda, bu nesneden birkaç tane olacağını düşünelim. Bu durumda, her nesne için aynı üretim sürecini tekrar tekrar yaptığınızda, söz konusu maliyet daha fazla olacaktır. İşte bu maliyeti nasıl azaltabiliriz? Acaba söz konusu nesnelerin hepsini tek tek üretmek yerine sadece birini üretip diğerlerini ondan klonlasak daha iyi bir performans olmaz mı? İşte ben bunu yapan bir tasarım deseniyim.
Anladım sanırım. Ancak yine de bize bir örnek vererek netleştirebilir misin?
Prototype: Tamam. Yalnız bilmeni isterim ki, şu an bu yazıyı okuyan herkes verilecek örneğin de az önce benim söylediklerimin de senin tarafından yazıldığını biliyor. Neden böyle bir tarz yapıyorsun ki? Hayır yani, maksadın tasarım desenini anlatmak mı goygoy yapmak mı? Nedir yani.
Pardon da sen eğer benim can verdiğim bir karaktersen bana niye atar yapıyorsun ki? Tarz benim yazı benim. Neden kurallarıma uymuyorsun ki?
Prototype: Ben bu şartlar altında röportaja devam edemeyeceğim yalnız. İşim var gücüm var benim. Ha örneği vereyim de okurlara da ayıp olmasın bari.
Diyelim ki bir şirkette her hafta, haftalık satış raporu hazırlıyorsunuz. Her hafta, yeni bir Excel dosyası açıp, tüm tablo tasarımlarını tek tek yapıp sonra da değerleri mi girersiniz? Yoksa bir önceki raporu kopyala-yapıştır yapıp yalnızca değerlerini mi güncellersiniz? Evet, gerçek hayatta bilgisayarda yaptığınız işler nasıl kopyala – yapıştır ile hızlanıyorsa; aynı durum, yaratılması uzun süren nesneler için de geçerlidir. Sadece “kopyalanabilir” olmasını sağlamanız yeterli. İşte ilk nesneyi yaratıp diğerlerini ondan kopyaladığınızda beni kullanmış olursunuz.
Neyse, ben gidiyorum artık.
Verdiğin bu örnek güzeldi bence. Röportaj isteğimi kırmadığın için teşekkür ederim. Seni kızdırdıysam da kusura bakma yani.
Prototype: Yok ya tamam. Bu aralar biraz gerginim ben de. Neyse sonra görüşürüz o zaman. Sen artık kod örneğine devam edersin buradan. Görüşürüz.
Evet sevgili dostlar; konuğumuz durumu açıkladı aslında. O halde ben de kod tarafında bir örnek geliştirerek makaleyi tamamlayayım.
Bellekte zaten hazır olan nesneyi kopyalayıp değerlerini değiştirmek, özellikle oyunlarda sıklıkla karşılaşılan bir yöntemdir. Mesela, Age Of Empires’da nasıl ki bir sürü işçiniz olması veya Diablo’ da aynı yaratıktan bir sürü saldırması, buna örnek gösterilebilir. Ben de bu aralar Ercan Bozkurt (selamlar olsun) hocamın sosyal paylaşımında görüp oynadığım bir oyun üzerinden örnek vereceğim size… Asphalt 8 Airborne
Bu oyunda minimum 6 araba ile birlikte yarışıyorsunuz. Bu uygulamanın programcısı olduğunuzu varsayıyoruz. Şimdi düşünelim; tüm otomobillerin iskelet formları aynı, varsayılan özellikleri de öyle. O halde, yalnızca birini sıfırdan üretip, diğerlerini buradan kopyalarsak çok anlamlı bir hareket yapmış oluruz değil mi? İşte gelin bu senaryoyu örneğimize (Console Application) uygulayalım şimdi.
İlk olarak, kopyalanabilir bir araba nesnesi oluşturarak başlayalım işe… İşte geliyor.
.NET Framework içinde, “kopyalanabilirlik” yeteneği kazandırmak için geliştirilmiş bir interface var: ICloneable. Bu interface, geliştirdiği sınıfa Clone metodunu ekliyor gördüğünüz gibi.
Önceden belleğin heap tarafına eklenmiş referans bir tipin sadece üyelerini kopyalamak için .NET’ de yer alan MemberwiseClone() metodunu kullandım gördüğünüz gibi. Yani değerleri değil; üye bilgilerini aldım. Buna yüzeysel (shallow) kopyalama diyebiliriz. Bir de tüm değerleri kopyalamak isteyebilirsiniz tabii. O zaman da Deep Copy yöntemini kullanmanız gerekebilir (ayrıntılı bilgi için: tıklayın) .
Şimdi yarış esnasında kullanılacak arabaları tutacak koleksiyonu hazırlayalım dilerseniz. İşte geliyor:
Tamamdır istediğim kadar arabayı ekleyebileceğim bir koleksiyonum var artık. O halde, pattern’i kullanarak arabalarımızı ekleyelim.
Dikkat ederseniz; new
Araba() ifadesini yalnızca prototip isimli araba nesnesini üretirken kullandım. Bunun dışındaki diğer araba nesneleri, ilk nesnenin birer kopyası olarak oluştular. Fakat yine de 6 farklı arabayı da yarışçılar koleksiyonuna eklemiş oldum. Yine de uygulamanın çıktısına bir göz atalım:
Tabii en yüksek hız değerini değiştirmediğim için o değer sabit kaldı. Fakat neticede 6 farklı nesneyi, prototipi klonlayarak elde edebildim.
Evet sevgili dostlar… Bir desenimizi daha burada bitirmiş olduk. Bir dahaki yazımızda görüşmek dileğiyle…
Yapısal desenleri de anlatmayı düşünüyor musunuz?
Çok faydalı olacak, şimdiden teşekkürler.