18 Eylül 2011 Pazar

Strategy Pattern

Yazılım tasarımı yaparken bazen aynı tipteki objelerin çalışma anında farklı özellikler göstermesini bekleriz. Yani objelerimizin polimorfik davranmasını isteriz. Bu programcılık dünyasında alışık olduğumuz polymorphism özelliğinden yararlanarak gerçekleştirlen bir tasarım kalıbıdır.

Burada amaç sınfıımızda değişmeyen yerler ile değişen yerleri birbirinden ayırmaktır. Değişmeyen yerler zaten inheritance ile tekrar kullanabilir kodlar elde etmemizi sağlayacak. Ama değişen yerler inheritance durumunda sürekli bakım(maintenance) gerektiren alanlardır ve vakit kaybına neden olan kısımlardır. Yeniden yeniden değişiklik yapmamıza sebep olan kısımları sabit kalan kısımlardan ayırıp bunları encapsulate edersek. Yani diğer kısımlardan soyutlar ve kendi içinde bir yapı kurarsak daha başarılı bir tasarım ortaya koymuş oluruz. Bunu sağlamak için Strategy Pattern kullanırız. Burada yapacağımız şey sürekli değişen kısımları alıp burada da kendi içerisinde bir sınıflandırma ve hiyerarşi sağlayarak tek tip ama farklı davranışlar sergileyen bir yapı kurmak.

    Örnek vererek açıklayalım; Bir tane simülasyon yaptığımızı düşünelim. Simülasyonda çeşit çeşit hayvanları simüle edelim. Tasarım olarak düşünürsek tüm hayvanları Animal nesnesinden türetelim tüm hayvanlarda ortak olan özellikler
     * Hareket ederler.
     * Belirli şekillere sahiptirler.

Bu Animal sınıfı abstract bir sınıf olacaktır. Çünkü tüm hayvanlar için ortak olan özellikler burada kodlanacaktır. Bu Animal sınıfından Cat, Fish, Bird sınıflarını türetelim. Bu hayvanlarda hareket etme farklı şekillerde gerçekleşir.  Animal sınıfı içerisinde move adında bir method tanımlayıp karada yürüme hareketini kodlayabilirz.Altsınıflarda da karada yürümekten farklı hareketler için örneğin yüzme ya da uçmak için bu methodu override edebiliriz.Ancak her  farklı hareket için bunu override etmek tekrar kullanılabilir kod yazmak için pek de mantıklı bir çözüm değil. Bu noktada Strategy Pattern kullanarak çalışma zamanında belirtilen hayvan için hangi hareket şekli uygunsa ona karar verip o hareketi gerçekleştirmesini sağlayabiliriz. Dikkat edersiniz Animal sınıfından türetilen sınıflarda değişen kısım move işlemidir. Bunu Animal sınıfından alıp kendi içerisinde encapsulate edersek; MoveBehavior adında bir interface oluşturursak ve bu sınıftan da WalkBehavior , SwimBehavior, FlyBehavior sınıflarını türetirsek kendi içinde özelleşmiş ama aynı tipten türetilmiş objeler elde ederiz. Yani MoveBehavior tipindeki bir değişkenimize WalkBehavior objesi atarsak yürüme, SwimBehavior objesi atarsak yüzme, FlyBehavior objesi atarsak uçma işi yapacaktır.  Bu şekilde Animal sınıfı içersinde MoveBehavior tipinde bir değişken tutarsak ve bunun set edilme işlemi alt sınıflar tarafından gerçekleştirilirse çalışma zamanında bu değişkene hangi tip obje atanırsa o sınıfa özgü hareket sergilenecektir. Çalışma zamanında bir hayvan farklı hareketler gerçekleştirebilir. Örneğin bir ördek havadayken uçmakta karadayken de yürümektedir. Strategy Pattern sayesinde çalışma zamanında hareket şeklini değiştirebiliriz.




MoveBehavior Sınıfı:



WalkBehavior Sınıfı:



SwimBehavior Sınıfı:



FlyBehavior Sınıfı:



Animal Sınıfı:



Cat Sınıfı:



Fish Sınıfı:



Bird Sınıfı:



AnimalSimulator Sınfı:



Ekran Çıktısı: