Strateji(Strategy) tasarım deseni, behavioral tasarım desenlerinden biridir. Bir dizi algoritma tanımlar, bu algoritmaların erişimi için arayüz sağlar ve algoritmaları tanımlarken birbirlerinin yerine kullanılabilir özellikte tasarlar. Ayrıca client runtime zamanında dilediği algoritmayı seçebilir. Yani, istenilen şartlara göre farklı sınıf ve metotların yazılarak kullanılmasını sağlayan bir tasarım desenidir.
Strategy Pattern Ne zaman Kullanılır?
Belirli bir iş için birden çok algoritmaya(yönteme) sahip olduğumuzda kullanılır.
Strategy Pattern Nasıl Kullanılır?
Öncelikle bir algoritma interface’i oluşturulur. Daha sonra oluşturulan interface’i implement edecek algoritma sınıfları yaratılır. Context sınıfı yaratılır. Bu sınıf içerisinde algoritma interface türünden algoritmaların set edilmesi için bir metod bulunur. Bu metod sayesinde Context sınıfı algoritma nesnesini tutmuş olur. Son olarak bir Client sınıfı oluşturulur. Bu sınıf Context sınıfından ve algoritma sınıflardan nesneler üreterek işlemlerin yapılmasını sağlar.
Yeni bir ASP.NET Core MVC 5 Web Uygulaması oluşturarak teorik olarak öğrendiklerimizi uygulayarak pekiştirelim.
Aşağıdaki Shipping sınıfını oluşturalım.
Daha Sonra, bir demo ödeme sayfası oluşturmamıza yardımcı olacak aşağıdaki Checkout sınıfını oluşturalım.
HomeController adında bir controller açalım ve controller’a aşağıdaki private metodu ekleyelim. GetShippings methodu örnek gösterimimizde uygulaması için gönderim yöntemlerinin bir listesini döndürür.
Checkout sınıfının bir instancesını oluşturacak ve döndürecek başka bir private GetOrder metodu oluşturalım.
Aşağıdaki kod parçacığında gösterildiği gibi HomeController’ın Index view’i içinde GetOrder metodunu çağıralım. Modeli basitçe Razor görünüm sayfasına döndürecegiz.
Basit bir ödeme formu oluşturduğumuz razor görünümü sayfasının kodu aşağıdadır. Gönderi yöntemleri, kullanıcının gönderim yöntemlerinden birini seçebilmesi ve kullanıcı seçimine göre gönderim hesaplama algoritmalarından birini çalıştırabilmemiz için bir combobax içerisinde gösterilmektedir.
Yaptığımız uygulamayı çalıştıralım ve aşağıdaki ekran görüntüsüne sahip bir demo ödeme sayfası görelim.
Strateji modelini uygulamak için ilk adım, tüm algoritmalar tarafından uygulanacak ortak bir arayüz belirlemektir demiştik yukarıda. Uygulamamız için buna IStrategy interface adını verelim. İnterface, orderTotal’ı parametre olarak kabul eden ve son toplamı döndüren tek bir CalculateFinalTotal metoduna sahiptir.
Daha sonra, yukarıdaki interface’si tüm algoritmalara uygulayalım. Demo uygulamamız için, farklı kargo ücretleri ile nihai toplamı hesaplamak için Ücretsiz Kargo, Yerel Kargo ve Dünya Çapında Kargo olmak üzere üç algoritmaya ihtiyacımız olduğunu var sayalım. Üç algoritmayı da tek tek uygulayalım.
FreeShippingStrategy Sınıfı:
LocalShippingStrategy Sınıfı:
WorldwideShippingStrategy Sınıfı:
Yukarıdaki sınıflarda çok basit nakliye oranları hesaplamaları yaptım.
Strateji kalıbı uygulamamıza devam edelim ve aşağıdaki IShipping interfacesini oluşturalım.
Daha sonra, yukarıdaki interface’i aşağıdaki Shippings sınıfına uygulayalım.
SetStrategy metodu bize metodun parametresi ile geçirilen strateji stratejisi yerine sağlayacaktır.
Son olarak, mevcut strateji için CalculateFinalTotal’ı metodunu çalıştıran ExecuteStrategy metodunu yazdık.
Şimdi yukarıdaki Shippings sınıfını kullanarak HomeController’ımızda farklı gönderim algoritmalarını kullanmaya hazırız, ancak önce onu .NET Core DI Container’a kaydetmemiz gerekiyor. Bunu Startup.cs sınıfının ConfigureService metoduna aşağıdaki satırı ekleyerek yapabiliriz.
services.AddScoped<IShipping, Shippings>();
Daha sonra, kullanacağımız yerde enjekte ediyoruz.
Son olarak kullanıcı Hesapla butonuna tıkladığında çağrılacak olan Index action metodumuzu yazalım. Kullanıcı tarafından seçilen gönderim yöntemine göre uygun stratejiyi ilişkilendirmek için SetStrategy yöntemini nasıl kullandığıma dikkat edin . Strateji belirlendikten sonra ExecuteStrategy , nihai toplamı hesaplamak için uygun sevkiyat stratejisini otomatik olarak kullanacaktır.
Uygulamamızı çalıştıralım ve farklı nakliye yöntemleri seçerek nihai toplamı hesaplamaya çalışalım. Son sipariş toplamını buna göre yapacağız.
Özet
Strategy Pattern, verimli daha okunabilir ve bakımı kolay yazılımlar oluşturmamıza yardımcı olur. Çalışma zamanında dinamik olarak eklenebilen/değiştirilebilen yeniden kullanılabilir ve değiştirilebilir bileşenlerle yazılım oluşturmamızı sağlar.
Umarım bu makaleyi ve bu design patterni anlaşılması kolay bir şekilde açıklamak için kullandığım örneği beğenmişsinizdir.