Monthly Archives: November 2007

Refactoring-Decompose Conditional

Kodun okunulabilirdiğini arttıran en önemli Refactoring yöntemlerinden biride Decompose Conditional yani türkçeye çevirmeye çalışırsak Şartlı ifadeleri ayırma diyebiliriz.Küçük bir örnek üzerinde nasıl yapıldığını görürsek daha iyi anlaşılacağını umuyorum.Aşağıda daha önce uğraştığım verilen veritabanındaki tablolar için sınıf oluşturan programdan ufak bir sınıfın constructor metodunu görüyorsunuz.


private const int USER_TABLE_ATTRIBUTE = 0;
private TableDefs tableDefs; 
public MDBResolver(string mdbPath)
{
	this._mdbPath = mdbPath;
	DAO.DBEngineClass dbEng = new DAO.DBEngineClass();
	DAO.Database db = dbEng.OpenDatabase(this._mdbPath,false, false, "");
	tableDefs = db.TableDefs;
	ArrayList tables = new ArrayList();
	for(int tableIndex = 0; tableIndex < tableDefs.Count; tableIndex ++)
	{

                if (tableDefs[tableIndex].Attributes == USER_TABLE_ATTRIBUTE)
		{
		Table table ;
                string tableName=tableDefs[tableIndex].Name; 
                table= new Table(tableName,this.GetFields(tableDefs[tableIndex].Name));
		tables.Add(table);
		}
	}
	db.Close();

	this._tables = (Table[])tables.ToArray(typeof(Table));
}
//geriye kalan metodlar........
//....................

İlk gözüme çarpan yukarıdaki kodun okunulabilirliğinin kötü olduğu. Çünkü kodu okuduğumda bana konuşma dilindeki gibi ne yapmaya çalıştığını ifade edemiyor.Kodu iyice incelediğimde ne yapmaya çalıştığını anlıyorum. Verilen veritabanındaki tabloları alıp bir tableDefs nesnesine atıyor ardından bu nesne içindeki tabloları alıp eğer USER_TABLE ise bunu sınıfını oluşturacağı tablolar listesine atıyor.Çünkü işimize yaramayacak olan Sistem tablolarının sınıflarını üretmesini istemiyoruz.

Kırmızı satıra baktığımızda bir if kontrolü görüyoruz.Tablonun USER_TABLE olup olmadığını kontrol ediyor. O satırın içindeki parantezleri iyice okumadığımız zaman USER_TABLE kontrolü yaptığını anlayamıyoruz.Şimdi Refactoring yaparak kodumuzu aşağıdaki gibi değiştirelim.


private const int USER_TABLE_ATTRIBUTE = 0;
private TableDefs tableDefs;
public MDBResolver(string mdbPath)
{
	this._mdbPath = mdbPath;
	DAO.DBEngineClass dbEng = new DAO.DBEngineClass();
	DAO.Database db = dbEng.OpenDatabase(this._mdbPath,false, false, "");
        tableDefs = db.TableDefs;
        ArrayList tables = new ArrayList();
	for(int tableIndex = 0; tableIndex < this.tableDefs.Count; tableIndex ++)
	{

		if (isUserTable(tableIndex)) 
		{
		Table table ;
                string tableName=tableDefs[tableIndex].Name; 
                table= new Table(tableName,this.GetFields(tableDefs[tableIndex].Name));
		tables.Add(table);
		}
		}
	db.Close();

	this._tables = (Table[])tables.ToArray(typeof(Table));
}

private bool isUserTable(int tableIndex)
{
        return this.tableDefs[tableIndex].Attributes == USER_TABLE_ATTRIBUTE;
}

//geriye kalan metodlar........
//....................


Yukarıdaki yeşil satırda eski şartlı ifademizi nasıl değiştirdiğimizi gördünüz. Önceden if içinde bulunan ifadeyi ayrı bir metod olarak ayırdık.Yani şartlı ifadeyi ayrıştırdık.Kod artık okunduğunda gayet kolaylıkla anlaşılabilir hale geldi.Bu şekilde if-else şartlı kontrol yapıları içindeki anlaşılması zor olan kontrolleri ayrı bir metod içine alarak ayırmaya Decompose Conditional deniyor. Sonuçta tek satır içeren ufak bir metod ortaya çıktı gereksiz olarak görebilirsiniz fakat kodun okunulabilirdiği temizliği ilerisi için her zaman daha önemli. Kodun diğer kısımlarıda aslında Refactoring gerektiriyor bunun farkındayım amacım sadece Decompose Conditional olduğu için diğerlerini sizlere bırakıyorum…

Neden Kod İçin Açıklama Satırları Yazmamalıyız?

Kod açıklama satırları denince hemen okul yılları aklıma geliyor . Hocalarımız üstüne basa basa kodumuza açıklama satırı yazmamız gerektiğini vurgulardı. Hatta ödevlerde,projelerde açıklama satırı olmayan kodlardan puan kırarlardı yanlış hatırlamıyorsam. Ayrıca yeni bir programlama dili öğrendiğimizde ilk olarak nasıl açıklama satırı koyarız onu öğrenirdik.

İlk zamanlar bunu neden yaptığımızı hiç sorgulamamıştım ama o açıklama satırları kodun okunuşunu,şeklini bozduğu için pek sevmezdim diyebilirim. Fakat yinede açıklama satırlarını bol bol kullanıp, kullanmayanları da uyarırdım.Peki neden kodumuza açıklama satırı koyma ihtiyacı duyuyoruz hiç düşündük mü?İlk başlarda gerekli olduğunu düşündüğüm için bunu hiç sorgulamamıştım fakat şimdi düşündüğümde o zamanlar koyduğum çoğu açıklama satırının şimdi gereksiz olduğunu anlıyorum. Peki neden gereksizdi? Çünkü o açıklama satırları okunulabilirliği,anlaşılabilirliği düşük olan kötü kodun kendim ya da başkaları tarafından anlaşılabilmesi için yazılmıştı. Kod okunduğu zaman ne yaptığını ifade edemiyordu bende bu yüzden açıklama satırları ile kodun ne yaptığını ifade etmeye çalışıyordum. Kodumuzun okunduğu zaman kolaylıkla anlaşılabildiğini düşünün o zaman bu kod için açıklama satırları yazmamıza gerek olurmu sizce? Bence olmaz çünkü kodun kendisi açıklama satırları gibi kendini ifade ediyor.Bu yüzden tekrar açıklama satırı koymaya gerek kalmayacaktır.

İş yerindeki çalışma arkadaşım bana Commentless Programming savunucusu diye bir ünvan takmıştı.Tabi bunun benim ortaya attığım bir fikir olmadığını söylemem gerekir. İlk olarak kod açıklama satırlarının bir kötü kod belirtisi olduğunu Martin Fowler’ın Refactoring Improving the Design of Existing Code kitabında okumuştum. Fowler kitabında benimde çok hoşuma giden “Kod açıklama satırları kötü kokan kodun fazla kokmasın diye üzerine sıkılmış deodorantlardır.” ifadesini kullanıyordu. Daha sonrada kendi deneyimlerimle çoğu yerde açıklama satırlarının gereksiz, çoğu zaman kötü yazılmış bir kodun belirtisi olduğunu gördüm.

Ufak tefek birkaç örnekle neden ve hangi durumlarda açıklama satırlarının gereksiz olduğunu anlatmaya çalışacağım.Bu örnekleri mümkün oldukça gerçek hayatta yazılmış kodlardan kesitler alıp göstereceğim. Öncelikle en fazla karşılaştığım açıklama satırlarından başlamak istedim.

Gereksiz açıklama satırları

public class MapObject{
    Map mapData = null;
    MapList mapList = null;
    Vector mapJList = new Vector(4, 1);

    /**
     * Consructor, Creates a new instance of MapObject
     */
    public MapObject() {
        MapListLoader mapListLoader = new MapListLoader();
        mapList = mapListLoader.loadMapList();
        Logger.printDebugMessage("Maps loaded...");
        mapJList = createMapJObjects(mapList);
    }
}

class User {
    private String address;
    //..

    /*
    gets address
     */
    public String getAddress() {
        return address;
    }
}

Şimdi yukarıdaki kodda gördüğünüz açıklama satırına bir bakalım.MapObject sınıfındaki Consructor’ının üzerine “Consructor, Creates a new instance of MapObject” yani anlamazsınız diye söylüyorum demiş yazan “bu bir yapıcı metod ve bu sınıfın yeni bir örneğini oluşturur.” :) Evet bunun zaten bir yapıcı metod olduğunu görebiliyoruz. Her Java, C# kullanıcısıda bunun böyle olduğunu açıklama satırını okumadan da anlayabilir.İkinci User sınıfımızda da javada zaten bir getter olan ayrıca gayet anlaşılır getAddress metodunun üzerine “Adresi getirir” açıklama satırı eklenmiş. Bunlara benzer açıklama satırları oldukça gereksizdir. Ekranda boşu boşuna yer kaplayıp diğer kodun okunmasını zorlaştırır.Bu tarz açıklama satırlarını hiç düşünmeden elimizden geldiğince hızlı sililiyoruz.

Değişkenler için kullanılan açıklama satırları

public class GetMapInfo{
    private static String strMapDir = ""; // map physical path
    private static String strMapServerURL = ""; // Map Connection URL
    //.................
}

Yukarıda gördüğümüz açıklama satırlarıda düzgün isim verilmemiş değişkenleri ifade etmek için kullanılmış. Mesela ilk değişkenin ismi strMapDir açıkçası ben ilk gördüğümde harita klasörü gibi bişey anlıyorum fakat yanındaki yorum satırını okuyunca haritanın fiziksel yolunu ifade ettiğini anlıyorum.Diğer strMapServerURL değişkenine baktığımızda da yanına açıklama satırı yazma gereği duyulmuş çünkü değişkenin ismi tam olarak kendini ifade edemiyor bu yüzden açıklama satırlarından yardım alınmış. Şimdi bu değişkenleri düzgün isimlendirip açıklama satırlarını kaldırdığımızda aşağıdaki gibi olan kodumuza bakalım.

public class GetMapInfo{
    private static String mapPhysicalPath = "";
    private static String mapConnectionURL= "";
    //.................
}

Şimdi yukarıdaki koda baktığımızda değişkenlerin isimleri ne olduklarını gayet iyi ifade ediyor.Gördüğünüz gibi değişkenleri düzgün isimlendirdikten sonra bu değişkenler için tekrar açıklama satırı yazmaya gerek kalmadı.

Metodlar ve parametreleri için kullanılan açıklama satırları

    /**
     * Builds LayerList object with Layer list
     * @param list Layer list
     * @return LayerList
     */
    private LayerList loadLayerList(List list){
        Layer layer = null;
        LayerList layerList = new LayerList();
        for(int i = 0; i<list.size(); i++){
            layer = (Layer) list.get(i);
            layerList.add(layer);
        }
        return layerList;
    }

Yukarıda gördüğünüz metodun açıklama satırına bakacak olursak metodun ne yaptığını ve parametre olarak gelen list değişkeninin ne ifade ettiğini yazmış.Açıklama satırına bakacak olursak verilen Layer(katman) listesi ile bütün katmanların bilgilerini içinde barındıran LayerList nesnesi oluşturduğunu yazıyor buraya kadar güzel metodun ne yapmak istediğini anlıyoruz.Fakat metod ismine baktığımızda loadLayerList ben açıkçası “harita listesini yükle” anlıyorum.Açıklama satırlarını okumasam sanki bir veritabanından ya da başka biryerden LayerList nesnesini yükleyeceğini sanırdım ama öyle olmadığını açıklama satırı bana söylüyor.İkinci açıklama satırıda parametre olarak alınan list parametresinin bize Layer listesi olduğunu ifade ediyor fakat metoda baktığımızda (List list) gibi parametre aldığını görüyoruz açıklama satırlarını okumadan da bu list parametresinin Layer listesi olduğunu anlamamız çok zor.Buradaki problem düzgün verilmemiş metod ve paramatre isimlerinden kaynaklanıyor. Metod ismi metodun ne yaptığını ifade edemediği için,parametre ismide kendisini ifade edemediği için açıklama satırlarının yardımına başvurulmuş sorun geçici olarak çözülmüş. Fakat biz bu metodu ve aldığı parametreyi aşağıdaki gibi düzgün olarak isimlendirirsek açıklama satırlarına gerek kalmayacak.

<span style="color: blue">
    private LayerList buildLayerList(List layerList){
        Layer layer = null;
        LayerList layerList = new LayerList();
        for(int i = 0; i<list.size(); i++){
            layer = (Layer) list.get(i);
            layerList.add(layer);
        }
        return layerList;
    }

Açıklama satırlarını silip metodumuzun ismini private LayerList buildLayerList(List layerList) olarak değiştirdik. Şuanda metodun adını okuduğumda bana direk olarak ne yaptığını ifade edebilir hale geldi adından da anlaşıldığı gibi buildLayerList yani LayerList nesnesi oluşturuyor.Parametre olarak alınan listeninde layerList olduğunu parametre adından kolaylıkla anlayabiliyorum. Gördüğünüz gibi düzgün isimlendirilmiş metod ve parametreler açıklama satırlarına gerek kalmayacak şekilde kodun okunulabilirdiğini arttırıyor.

Metodların içinde kullanılan açıklama satırları

private void Aktivasyon_Load(object sender, System.EventArgs e)
{
    //Disk modelinin bilgilerini al
    ManagementClass clsDiskSurucu = new ManagementClass("Win32_DiskDrive");
    ManagementObjectCollection DiskSurucu = clsDiskSurucu.GetInstances();
    ManagementObjectCollection.ManagementObjectEnumerator DiskSurucuEnumerator;
    DiskSurucuEnumerator=DiskSurucu.GetEnumerator();
    DiskSurucuEnumerator.MoveNext();
    ManagementObject DSS = (ManagementObject)DiskSurucuEnumerator.Current;
    string diskModel = DSS["Model"].ToString();

    //BIOS seri numarasının bilgilerini al
    ManagementClass clsBios = new ManagementClass("Win32_BIOS");
    ManagementObjectCollection Bios = clsBios.GetInstances();
    ManagementObjectCollection.ManagementObjectEnumerator BiosEnumerator;
    BiosEnumerator=Bios.GetEnumerator();
    BiosEnumerator.MoveNext();
    ManagementObject BBios = (ManagementObject)BiosEnumerator.Current;
    string biosSeriNumarasi = BBios["Caption"].ToString();

    //Disk modeli ile BIOS seri no string olarak alınıyor ve şifre oluşturuluyor
    sifre= biosSeriNumarasi + diskModel;
    //Oluşturulan makina bağımlı string md5 ile hashleniyor
    sifreHash = FormsAuthentication.HashPasswordForStoringInConfigFile(sifre, "md5");


    //Oluşan hashli stringi alanlarına yerleştiriliyor
    SKod1.Text = sifreHash.Substring(0, 3);
    SKod2.Text = sifreHash.Substring(3, 3);
    SKod3.Text = sifreHash.Substring(6, 3);
    SKod4.Text = sifreHash.Substring(9, 3);
    SKod5.Text = sifreHash.Substring(12, 3);
}

Yukarıda gördüğümüz bu küçük C# metodu içinde birçok açıklama satırı kullanılmış.Açıklama satırlarını okumadan anlayamıyorsunuz ama Metod kısaca aktivasyon işlemleri için bazı işlemler yapıyor.Yorum satırlarına baktığınızda önce diskin modelini alıyor ardından bios seri numarasını alıyor ardından bunları birleştirerek bazı alanlara yerleştiriyor. Bu tarz; içinde açıklama satırı bulunduran metodların problemi çok fazla iş yapmaları, aslında içlerinde birden fazla potansiyel metod barındırmalarıdır bunu da yorum satırlarından kolaylıkla anlayabilirsiniz. Burada yorum satırları mantıksal olarak ayrı olan üç ayrı işlemi ifade etmek için kullanılmış.Bunlar diskin modelini alma,bios seri numarasını alma ve bunları bazı alanlara yerleştirme.Bu tarz yorum satırları bize kodumuzun Refactoringe ihtiyacı olduğunun sinyalini verir.Kodumuzu tekrar düzenleyerek yorum satırlarını silip aşağıdaki gibi değiştiriyoruz.

private void Aktivasyon_Load(object sender, System.EventArgs e)
{		
sifre=GetBiosSeriNumarasi()+GetDiskModel();
sifreHash=FormsAuthentication.HashPasswordForStoringInConfigFile(sifre,"md5");
HashVeriyiAlanlarinaYerlestir();
}

private void HashVeriyiAlanlarinaYerlestir()
{
        SKod1.Text=sifreHash.Substring(0,3);
        SKod2.Text=sifreHash.Substring(3,3);
        SKod3.Text=sifreHash.Substring(6,3);
        SKod4.Text=sifreHash.Substring(9,3);
        SKod5.Text=sifreHash.Substring(12,3);
}

private static string GetBiosSeriNumarasi()
{
        ManagementClass clsBios= new ManagementClass("Win32_BIOS");
        ManagementObjectCollection Bios = clsBios.GetInstances();
        ManagementObjectCollection.ManagementObjectEnumerator BiosEnumerator;
        BiosEnumerator=Bios.GetEnumerator();
	BiosEnumerator.MoveNext();
        ManagementObject BBios =(ManagementObject)BiosEnumerator.Current;
	return BBios["Caption"].ToString();
}

private static string GetDiskModel()
{
        ManagementClass clsDiskSurucu= new ManagementClass("Win32_DiskDrive");
        ManagementObjectCollection DiskSurucu = clsDiskSurucu.GetInstances();
        ManagementObjectCollection.ManagementObjectEnumerator DiskSurucuEnumerator;
        DiskSurucuEnumerator=DiskSurucu.GetEnumerator();
	DiskSurucuEnumerator.MoveNext();
	ManagementObject DSS = (ManagementObject)DiskSurucuEnumerator.Current;
	return DSS["Model"].ToString();
}

Yeniden düzenlenmiş metodlarımıza bakacak olursanız açıklama satırlarına ihtiyaç duymadan kodu okuyarak ne yapıldığını rahatlıkla anlayabilirsiniz.En önemli avantajlarından biride uzun metodumuzu yorum satırlarına göre 3 ayrı metoda bölmemiz oldu.Ve bu yorum satırlarımız aslında yeni gelen bu 3 metodun adları oldu.Metodların adlarını okuduğumuzda gayet açık olduğu görülebilir.

Gördüğümüz gibi kod açıklama satırları çoğu zaman kötü yazılmış kodun belirtileridir.Bu açıklama satırlarını kodumuza düzgün isim vererek, küçük küçük mantıksal parçalara ayırarak vb. tekniklerle ortadan kaldırabiliriz.Bu yüzden açıklama satırlarına çoğu zaman kodun düzeltilmesi gerektiğini belirten fırsatlar olarak bakıyorum. Tabi hiç açıklama satırı yazmayacakmıyız tarzı bir soru aklınıza geliyor olabilir.Yazacağız ama sadece gerektiği durumlarda ve çoğu durumda gerekmeyecek buna inanabilirsiniz.Belki yazdığınız bir metodda kullandığınız algoritmanın neden kullanıldığını yada daha sonra okuyan için dikkate alması gereken açıklamalar yapabilirsiniz. Ama genellikle kodun ne yaptığını açıklama satırları ile değilde daha düzgün okunabilir temiz kod yazarak sağlamaya çalışın.

Unit Test Yazmanın Faydaları

Aklıma gelmişken kendi açımdan bizzat Test Driven Development pratikleri kullanarak geliştirdiğim yazılımlar sonucu edindiğim TDD faydalarından aklıma gelenleri yazmak istedim.

  1. Daha hızlı yazılım geliştirme
  2. Çok daha az hata içeren kod
  3. Testler kodun çalıştırılabilir örnek dökümanını oluşturur.
  4. Daha iyi tasarıma sahip daha kaliteli kod
  5. Hataların daha çabuk bulunması ve düzeltmesi
  6. Kullanıcı bakış açısından yazılan daha anlaşılabilir kod
  7. Basit ,gereksiz kompekslik içermeyen kod
  8. Kodun tekrar düzenlenmesini oldukça kolaylaştırması
  9. Daha eğlenceli

Bunlar kendi deneyimlerim sonucundan edindiğim izlenimler. Eğer denemediyseniz pek anlamlı gelmeyebilir fakat iyice kullanıp faydalarını gördüğünüz zaman tadından yenmez :)

Zaman baskısı, Bitmeyen Mesailer…

People under time pressure don’t work better;
they Just work faster.

Peopleware kitabını okurken karşılaştığım güzel paragrafı hemen yazayım dedim. Yazılım dünyasında bitmek bilmeyen mesailer, fazla çalışmalar,hafta sonları çalışmalarının ne kadar faydalı olduğunu oldukça güzel özetlemiş. Baskı altında fazla çalışmak malesef daha iyi ,daha verimli çalışmamızı değil sadece daha hızlı çalışmamızı sağlıyor. Yorumu size bırakıyorum…

Tecrübe Konuşuyor!

İnternette gezinirken, Andres isimli arkadaşın 10 yıllık profosyonel yazılım mühendisliği kariyerinde öğrendiği en önemli şeyleri anlattığı bu harika yazını okudum.Yazısını buradan okuyabilirsiniz.

Top ten things ten years of professional software development has taught me

Özellikle ilk maddeye dikkatinizi çekmek istiyorum . İlk maddede Object Orientation(Nesneye Yönelim) hakkında düşündüğünüzden çok daha zor olduğunu söylemiş ve 10 seneyi aşkın tecrübesine rağmen halen nasıl daha iyi tasarım daha iyi modelleme yapmayı öğrendiğini yazmış. Bende Andres gibi Bilgisayar Mühendisliği mezunu olarak onunla tamamen aynı fikirdeyim.Neredeyse tüm Bilgisayar Mühendisliği bölümlerinde Object Oriented sadece sınıf,nesne,kalıtım vb.. kavramlar üzerinde durulup öğretiliyor. Yani işin söz dizimi veriliyor bir bakıma, ama gerçek anlamda Object Oriented tasarım, modelleme,programlama konularından bihaber olarak çoğu yazılımcı piyasaya atılıyor. Ve işin kötüsü herkes Object Oriented olarak yazılım geliştirdiğini sanmasına rağmen doğru düzgün Object Oriented yazılım geliştiren kişilerin,firmaların sayısı özellikle ülkemizde çok az.Bence bu on maddenin hepside çok uzun başlıklar altında incelenebilir çünkü gerçekten oldukça faydalı ve hepimizin gözden geçirmesi gereken bir liste. Belki yıllar sonra öğrenebileceğimiz şeyleri bizim için çok güzel bir şekilde özetlemiş.

Kötü Tasarımın Belirtileri

Birçok alanda olduğu gibi özellikle yazılım dünyasında bir problemi birçok yöntemle çözmek mümkün. Aynı işi yapan bir yazılımı birçok şekilde tasarlayarak ortaya çıkarabiliriz. Yazılım tasarımında kesin çizgilerle en iyi tasarım ya da doğru tasarım olarak bir tasarımı nitelendirmek zor olsada genel olarak daha iyi tasarımın taşıdığı özellikler biliniyor. Bu konuda daha önce okuduğum Agile Principles, Patterns, and Practices

Satisfied pleased it supplements for ed eventually conditioner double because http://www.goprorestoration.com/viagra-free-trial lotions – clean to http://www.vermontvocals.org/drugs-that-cause-ed.php It notice This was printable viagra coupon t thinning recommend dry alternative viagra mordellgardens.com the s, adult viagra buy have you. As The. And cialis pills also Well more 100 mg cialis be as.

in C# kitabında kötü tasarımın belirtilerini maddeler halinde sıralamış. Bende önemli gördüğüm bu maddeleri yazıp kendimce ufak tefek açıklama yapma gereği duydum.Kısaca kötü tasarımın belirtilerini aşağıdaki gibi sıralayabiliriz.

  • Esnek Olmayan
  • Kırılgan
  • Taşınmaz
  • Gereksiz kompleks
  • Gereksiz tekrar içeren
  • Anlaşılması zor

Esnek Olmayan : Kısaca değişim maliyetinin yüksek olması diyebiliriz. Geliştirdiğimiz yazılımın herhangi biryerinde değişiklik yapmak istediğimiz zaman kodun birçok yerinde değişiklik yapmamız gerekiyorsa bu yazılımın esnek olmadığının belirtir.

Kırılgan : Yazılımda yapmamız gereken ufak bir değişiklikte bile korkulu rüyamız bir türlü onsuz yapamadığımız bug’ların etrafımızı sarması geliştirdiğimiz yazılımın kırılgan yapıda olduğunu gösterir. Ben bu filmi daha izlemiştim dimi? :) Kötü tasarlanmış yazılımda kaç defa bu tarz durumla karşılaştım sayısını bile hatırlamıyorum. Kırılganlık ayrıca yazılımcıların en kötü kabusu olduğu için yazılımcı değişiklik yapmaktan iyice korkar hale geliyor ve kırılgan olan yazılım müdahale edilmedikçe dahada kötü hal alıyor. Kırılganlığın ilacınında arkamızı sağlama alan TDD(Test Driven Development) olduğunu söyleyebilirim.

Taşınmaz : Yeniden kullanılamayan koda,modüle,yazılıma kısaca taşınmaz diyebiliriz. Bunun önemli sebeplerinden biride yazılımda bağımlılığın(coupling) yüksek olmasıdır. Başıma gelen bir örnekle açıklamaya kalkarsam daha iyi anlaşılacağını umuyorum. Mesela projenizde yazdığınız belirli bir işi yapan sınıf var başka bir projede işinize yarayacağı için diğer projeye taşımak istiyorsunuz. Sınıfı aldınız kopyalayıp diğer projenin kaynak koduna attınız. Bir baktınız diğer projede hatalar çıkmaya başlamış. Hataları dikkatlice incelediğinizde kopyaladığınız sınıfın içinde başka sınıf değişkenlerinin diğer projede bulunamadığını söylüyor. Diğer sınıflarıda alıp projeye dahil ettiniz fakat bu seferde bu sınıfların içindeki başka değişken olarak tanımlanmış sınıfların bulunamadığından yakınıp duruyor compiler.Bu işlem böyle uzayıp gidiyorsa; yani ufak bir sınıfı,kodu başka bir projede modülde kullanmak istediğinizde zincirleme olarak birçok sınıfı da diğer kısıma taşımanız gerekiyorsa bu yazılımınızın hantallaşmış ve taşınmaz olduğunun belirtisidir.İlacı Refactoring ve TDD diyebiliriz.

Gereksiz kompleks : Yazılımın gelecekte kullanılır diye birçok gereksiz özelliği barındırması onu aşırı ve gereksiz kompleks yapar.Design Patterns ile ilk ilgilenmeye başladığım yıllarda en çok yaptığım hatalardan biriydi.Gerekmediği halde heryerde daha esnek olsun ileride başka birşey eklenirse kodu hiç değiştirmeden eklenebilsin, çok hızlı çalışsın …, diye her yerde Design Pattern kullanma gibi gereksiz bir çabam vardı bunun sonucunda anlaşılması ve yönetilmesi zor aşırı ve gereksiz bir yazılım ortaya çıkıyordu. Bu derdin devasıda Basit tasarım(Simple Design) diyebiliriz.

Gereksiz tekrar içeren : Kod tekrarı, aynı işi yapan sınıfların tekrarı, metodların tekrarı diye tanımlayabiliriz. Biz yazılımcıların başına en çok bela açan şeylerden birisidir.Ayrıca kırılgan ve esnek olmayan yapıya yol açar diyebiliriz. Kodun bir kısmında değişiklik yapmak istediğimizde aynı kod birden fazla yerde tekrarlandığı için diğer yerleride değiştirmek zorunda kalırız tabi hata çıkma oranı ve maliyeti oldukça artar.Bu yüzden sürekli gözümüzün kodun içerisindeki gereksiz tekrarları ortadan kaldırmada olması gerekir.Yani ilacımız Refactoring.

Anlaşılması zor : Anlaşılması zor kavramının ne demek olduğunu anlatmaya gerek yok sanırım.Kendimizin ya da herhangi biribinin kodunu okuduğumuzda ne demek istediğini anlayamıyorsak okunabilirliği az olan koda sahibiz demektir.Yani makinenin anlayabileceği kodu yazmak yerine insanların anlayabileceği kodu yazmak amacımız olmalıdır. Ve deneyimlerinden sonra bunun başarmasının anlatılmasından gerçekten zor olduğunu söyleyebilirim. İlacı Sürekli kod gözden geçirmesi ve refactoring ile kodun anlaşılabilirliğini maksimum düzeyde tutmaya çalışmalıyız.

Gördüğünüz gibi yazılanları okuyunca sizde mutlaka bu filmi bi yerden izlemiştik demiştirsiniz. Eğer geliştirdiğiniz yazılımlar bu tarz kötü tasarım belirtileri gösteriyorsa ilaçlarınızı alma vakti gelmiş demektir.Çünkü bu belirtiler ne kadar az olursa işiniz o kadar kolay olacaktır.

Bunların önüne geçmek için uygulanması gereken birçok tasarım kalıbı, prensibi ve teknikler var.Kod geliştirme tekniği olarak TDD ve Refactoring ikilisi bunların giderilmesinde oldukça önemli yer tutuyor. Ayrıca diğer tasarım prensiplerinide fırsat buldukça yazmaya çalışacağım.