Strategy Patern (Strateji Örüntüsü)

Mustafa Erdem Köşk - 30/06/2017
strategy-patern-strateji-oruntusu

Izmirin kavurucu sicaklarindan herkese merhabalar..blush

 

Düzenli olarak belli araliklarla yazip, deginmek istedigim yazilim örüntülerinden bir yenisinle daha sizlerleyim. Sözü fazla uzatmadan konumuza geçersek ,strateji örüntüsü aslen bir sinifin methodunun islevinin çalisma zamaninda dinamik olarak degistirilmesini saglar(runtime). Ilk duydugumuzda kafamiz karisabilir bu sebeple bunu örnekle açiklamak çok daha faydali olabilir diye düsünüyorum. Bunu savunma sanayiinden çalismamdan ötürü silahlar üzerinden yapmak istiyorum. 

 

Öncelikle elimizde bir sürü silah çesidinin oldugunu düsünelim. Her birinin mermi kapasitesi birbirinden farkli olarak hesaplanacaktir. Bu durumda su sekilde bir durumla karsi karsiya kalacagiz.

 

 

public abstract class Silah{
 
    public abstract int KalanMermiAdediHesapla();
}
 
public class Mp5 extends Silah {
 
    public int KalanMermiAdediHesapla() {
      // bla bla bla 
    }
}
 
public class Mpt76 extends Silah {
 
    public int KalanMermiAdediHesapla() {
        // bla bla bla
    }
}
 
public class Jng90 extends Silah {
 
    public int KalanMermiAdediHesapla() {
      // bla bla bla
    }
}

 

 

Yukarida görmüs oldugunuz tasarim ile anlik olarak kalan mirmi miktarini hesapliyabildigimizi düsünün. Çagiran sinifimiz artik çagirdiginda kalan merminin hangi yöntemle hesaplanacagina karismiyor ve dogrudan bu islerler çagiran taraf için önemsizlesiyor.. Buraya kadar hersey güzel gidiyor degil mi ? Ancak isler biraz karisabilir...

 

Peki neden bu örüntüye ihtiyacimiz var kalitim neden bize yetmiyor ?

 

Peki simdi yeni bir istek oldugunu düsünelim. Silahin ücretinin hesaplanmasi gerekiyor olsun ancak bu parametre silahin adina göre degil bir silah kategorisine göre oldugunu düsünelim (piyade tüfegi vb). Simdi kalitimda hangi sinifin nereye dahil olmasi gerektigi ile alakali bir bilgi sahibi degiliz. Belki etrafindan dolasarak çözüm bulabiliriz ancak bu seferde sürekli kod kopyalamamiz gerekir. Unutmayan en iyi kod yazan kisi çok kod yazan degil anlamli en az kod yazan kisidir. Iste burada tam olarak strateji patern devreye giriyor.

 

 

 

Yukarida vermis oldugumuz problemi iki interface kullanarak basitçe nasil çözebilecegimizi sizlere gösterecegim.

 

public interface ISarjor {    
 
    public int KalanMermiAdediHesapla();
}
 
public class Mp5Sarjor implements ISarjor {
 
    public int KalanMermiAdediHesapla() {        
        return 5;
    }
}
 
public class Mpt76Sarjor implements ISarjor {
 
    public int KalanMermiAdediHesapla() {        
        return 4;
    }
}
 
public class Jng90Sarjor implements ISarjor {
 
    public int KalanMermiAdediHesapla() {        
        return 6;
    }
}
 
public interface IDegerHesap {
 
    public int DegerHesapla();
}
 
public class Tufek implements IDegerHesap {
 
    public int DegerHesapla() {
        return 7500;
    }
}
 
public class HafifMakina implements IDegerHesap {
 
    public int DegerHesapla() {
        return 3500;
    }
}

 

Suan için fiyat vb degerler çokta mantikli olmasa da aklinizda canlanmasi için ana temelleri yukarida belirttim.. Bu sefer kalitim kullanmayacagiz. Kalitimin isini iki farkli interface'e dagitmis olduk.

 

public class Silah{
 
    public ISarjor sarjor;
    public IDegerHesap deger;
 
    public Silah(ISarjor sarjor, IDegerHesap deger) {
        this.sarjor= sarjor;
        this.deger= deger;
    }
 
    public int KalanMermiAdediHesapla(){        
        return sarjor.KalanMermiAdediHesapla();
    }
 
    public int DegerHesapla(){        
        return deger.DegerHesapla();
    }
}

 

 Suan kafaniz biraz daha karismis olabilir ancak simdi main method bölümünde eminim kafanizdaki bütün sorular ve sorunlar cevap bulacak buna eminim...smiley

 

 public static void main(String[] args) {
 
        Silah silah= new Silah (new Mp5Sarjor(), new HafifMakina());
        int mp5MermiAdedi= silah.KalanMermiAdediHesapla();
        int mpg5SilahDegeri= silah.DegerHesapla();
 
        silah= new Silah (new Mpt76Sarjor(), new Tufek());
        int mpt76MermiAdedi= silah.KalanMermiAdediHesapla(); 
        int mpt76SilahDegeri= silah.DegerHesapla();

    }

 

Gördügünüz gibi suan için anlik olarak algoritmari birbiri arasinda degistirip çalisma zamaninda uygulanacak algoritmaya karar verebiliyoruz.Bugün sizlerle strateji örüntüsünü isledik elimden geldigince size önemini ve nasil çalistigini aktardim.

Baska bir yazimda görüsmek üzere..