Fatih İzgi
Kodcular
Published in
3 min readFeb 5, 2023

--

Command Design Pattern Nedir?

Design Patterns eğitim serisindeki ilk yazımızda, tasarım desenlerinin “Yazılımcıların sıklıkla karşılaştığı problemlere ve yazılımların doğasında bulunan genel ihtiyaçlara getirilen çözümler” olduğunu söylemiştik. Sık karşılaşılan problemlerden bir tanesi ise; istemcinin hizmetlerini hem ne yapıldığından hem de nasıl yapıldığından habersiz karşılayabilme ihtiyacıdır.

Konuya başlamadan önce problemin ne olduğunu biraz analiz edelim :

Eski zamanlarda imparatorluklar haberleşmek için birbirlerine elçi yollardı. Bir kralın diğer krala elçi ile “Sizi bekliyoruz” haberi yolladığını varsayalım. Bu cümle aslında hem savaş daveti hem de antlaşma teklifi olabilecek bir mesaj içermektedir. Elçinin mesajı ilettikten sonra ne olacağı hakkında hiçbir fikri yoktur ancak mesajı alan kral ne yapması gerektiğini anlar. Peki mesajı gönderen kral neden bu kadar kısa ve öz bir mesaj göndermiş olabilir? Öncelikle, mesajın uzaması elçinin kafasını karıştırabilir ve mesajı iletirken yanlış aktarımlar yapabilir. Ayrıca, iki imparatorluk arasındaki bir meseleyi elçinin tüm ayrıntıları ile biliyor olması tehlikeli bir durumdur. Yazılım dünyasında da bu durum aynen geçerlidir. İstemcilerin, bir işlemin nasıl yapıldığını bilmemesi gerekir. Örneğin, eldeki verilere göre uygulanabilecek en iyi sıralama veya arama algoritmasının seçimi/gerçekleştirimi istemcilere bırakılmamalıdır. İstemci yalnızca “Sırala” demelidir ve eldeki veriler en uygun şekilde sıralanmalıdır(Bir önceki yazımızda, bu problemi çözmek için Strategy Design Pattern yapısını kullanabileceğimizi söylemiştik). Bununla beraber, bazı anlar olur ki istemcilerin, yalnızca nasıl yapıldığını değil aynı zamanda ne yaptığını da bilmemesi gerekir. Örneğin, istemci yalnızca “Yap” demeli ve eldeki veriler en uygun algoritma ile sıralanmalıdır. Aslında istemci “Yap” dediğinde elindeki verilerin sıralanacağını mı yoksa silineceğini mi yoksa başka bir şey mi olacağını bilemez. Bu sebeple Command Design Pattern, Strategy Design Pattern’ın daha kapsamlı hali olarak düşünülebilir.

Not : Command Design Pattern yapısında istemcinin kullanacağı metot bir gelenek olarak execute() olarak isimlendirilir.

Aşağıdaki kuralları destekleyen basit bir e-ticaret sitesi tasarlayalım :

1- Yalnızca satın alma ve iade etme işlemleri gerçekleştirilecek.

2- Buton üzerinde yalnızca “Tamam” yazıyor olacak. Buton satın alma ekranında satın alma işlemini; iade ekranında iade işlemini gerçekleştirecek.

3- Satın alınacak ürünün döviz kuru belirlenecek ve döviz kuruna göre ilgili hesaptan ödeme veya iade işlemi gerçekleştirilecektir.

Command Design Pattern, isteği nesneye çevirerek, farklı algoritmaların (istemcilerin ne yapıldığından ve nasıl yapıldığından haberi dahi olmadan) uyum içerisinde çalışmasını sağlamak amacı ile kullanılır. Davranışsal(Behavioral) tasarım desenlerinden bir tanesidir ve kullanılması ile birlikte yazılım bakım maliyetinin azaltılması, karmaşıklıktan uzak bir yapının elde edilmesi ve hata riskinin minimum düzeyde tutulması gibi faydalar elde edilir.

Öncelikle problemimizi yazılıma aktarmak adına örnek bir yapı oluşturalım :

Görüldüğü gibi User isimli bir sınıf tanımladık. Bu sınıftan üretilecek olan kullanıcı nesneleri Dolar ve Euro hesapları ile birlikte satın aldıkları bazı ürünlere sahipler.

İleride kullanacağımız sabitleri tanımlamak ve örnek nesne üretebilmek adına iki sınıf daha tanımlayalım :

Artık Command yapısını projemize eklemeye başlayabiliriz :

Command isimli Interface ile hangi metodu zorunlu tutacağımızı bildirdik. AbstractCommand soyut sınıfı ile birlikte alt sınıflarda ortak olarak bulunması gereken özellik ve metotları tanımladıktan sonra ana işlemlerimizi temsil eden Payment ve Repayment alt sınıflarını da tanımladık. Eğer satın alma işlemi gerçekleştirilecek ise Payment sınıfı nesnesi kullanılacak; eğer iade etme işlemi gerçekleştirilecek ise Repayment sınıfı nesnesi kullanılacaktır.

Dizaynın istemci tarafını inceleyecek olursak :

Output :

Dolar Hesabından Ödeme İşlemi Gerçekleştirildi.

Dolar Hesabı Bakiyesi : 850.0USD

Euro Hesabı Bakiyesi : 2000.0EUR

Satın Aldığınız Ürünler :

Telefon

Dolar Hesabına İade İşlemi Gerçekleştirildi.

Dolar Hesabı Bakiyesi : 2000.0USD

Euro Hesabı Bakiyesi : 2000.0EUR

Satın Aldığınız Bir Ürün Bulunmamaktadır!

Eğer satın alma ekranı açık ise istemci Payment sınıfı nesnesini metoda parametre olarak geçerken; iade ekranı açık ise Repayment nesnesini parametre olarak geçmektedir. Böylece satın alma ve iade etme işlemini belirleyen şey metoda geçilen parametre haline gelmiştir. Yani istek, bir nesneye dönüştürülmüştür. execute() ismi verilen ve isminden tam olarak ne yaptığı anlaşılmayan metot, alınan bir parametreye göre gerekli işlemi yapmaktadır. Ayrıca istemci, gerçekleştirilen işlemin detaylarını da (ilgili hesabın seçilmesi, para çekme veya yatırma gibi) bilmemektedir.

TÜM YAPI :

Command Design Pattern konusunun ayrıntılarını ve inceliklerini öğrendiğimize göre tüm yapıyı incelemeye başlayabiliriz :

Yararlandığım Kaynaklar :

1- GeeksForGeeks

2- RefactoringGru

3- Tutorialspoint

--

--