Strategy Design Pattern

Gökhan Çelik
Yazılıma Dair
Published in
2 min readMay 1, 2021

Uzun bir aradan sonra, geçen haftalarda gerçek hayatta uygulamaya çalıştığım strateji tasarım örüntüsünün .NET ortamındaki bir uygulamasıyla geri dönüş yapmak istedim.

Strategy Design Pattern
Strateji Tasarım Örüntüsü

Strateji Tasarım Örüntüsü nedir sorusuna mülakatlarda şu şekilde cevap verebilirsiniz.

Strateji Tasarım Örüntüsü, aynı işi farklı şekillerde yapmaya yarayan sınıfları çalışma zamanında seçmeye ve o işi yaptırmaya olanak sağlayan davranışsal (behavioural) bir tasarım örüntüsüdür.

Peki, nasıl?

Bir dosyayı farklı ortamlara yüklemek istiyoruz diyelim. Öncelikle dosyaları ilgili ortama yüklemek için ilgili sınıfı seçen bir sınıf oluşturmakla başlayalım. Adına FileDelivererService diyelim. Başta aşağıdaki gibi geliştirmeye başlayalım sonra yeniden düzenleriz.

Bu sınıf bizim için ilgili ortama göndermek üzere dosyayı ve ortamın adını parametre alarak ilgili ortamın sınıfının bir örneğini oluşturuyor ve yüklenmesine yardımcı oluyor. Buraya kadar güzel fakat problem ne?

Üçüncü bir platforma dosya göndermek istediğimizde, bu methodu değiştirmek zorunda kalacağımızdan Deliver işlevi SOLID ilkelerinden Open-Closed ilkesini ihlal ediyor. Open-Closed ilkesi der ki,

Bir varlık (method, sınıf, modül…) genişlemeye açık (Open) ama değişmeye kapalı (Close) olmalıdır.

İyi de değiştirmeden nasıl yapacağız bu işi. İşte burada tasarım örüntülerinden strateji tasarım örüntüsü giriyor devreye.

Öncelikle iki ortama dosyayı göndermemizi sağlayan AzureBlobFileDeliverer ve DropboxFileDeliverer sınıflarımızı ortak bir arayüzden (interface) türetelim. Bu arayüzde ihtiyacımız olan Deliver işlevi ve ilgili sınıfı çalışma zamanında seçmemize yardımcı olacak Destination özelliği.

Destination özelliğine her bir sınıf için uygun bir değer veriyoruz. Her bir sınıfta, Deliver işlevini ilgili ortama dosya gönderecek şekilde uyguluyoruz.

IFileDelivererStrategy arayüzünü uygulamamızın Startup.cs dosyasında IoC konteynerimize her bir sınıf için kayıt ediyoruz.

Tüm bu geliştirmelerden sonra yeni FileDelivererService sınıfımızın son hali de şöyle olacak.

IFileDelivererStrategy arayüzünden IoC konteynerimize kayıt ettiğimiz tüm sınıflar constructorda FileDelivererService sınıfımıza inject olacak, bunları _strategies değişkenine atayarak sınıf içinde erişilebilir hale getirelim. Bunların arasından ilgili sınıfı seçmek için basit bir Linq FirstOrDefault/SingleOrDefault (Burası size kalmış, birden fazla olması durumunda patlamasını istiyorsanız SingleOrDefault kullanabilirsiniz.) işlevi ile ilgili sınıfımızı getirip Deliver işlevini çağırarak ilgili ortama dosyayı gönderiyoruz.

Şimdi üçüncü bir ortama da dosya göndermemiz istendiğinde Deliver işlevini değiştirmeye ihtiyaç duymadan, sadece gerekli ortama dosyayı gönderen sınıfı geliştirerek Deliver işlevini değişime kapalı hale getirmiş olduk.

Tüm projeye buradan erişebilirsiniz. Fırsat buldukça diğer tasarım örüntüleri ile ilgili yazı yazmaya çalışacağım.

Referanslar

https://stockup.sitebuilderreport.com/

--

--

Gökhan Çelik
Yazılıma Dair

Software Engineer over 9 years of experience working as a full stack developer both within a wide range and startup companies.