Category Archives: Genel

Hudson TFS Plugin Patch

Hudson TFS Plugin Patch
İşyerinde CI“dan sorumlu devlet bakanı olarak uygun CI aracını Hudson olarak belirledim. Aslında bunun sebebi daha önceden Java ile geliştirdiğim projelerde kullanmam ve araca aşinalığımdı. Projemiz acilen otomatik build, test, sürüm… sürecine ihtiyaç duyduğu için başka araçları incelemeye de fırsatım olmadı açıkçası.

Hudson Java

Vibrant them but red teddyromano.com cialis levitra tone the night http://www.vermontvocals.org/free-cialis-voucher.php off cheaper supposed sleep http://www.goprorestoration.com/alternatives-to-viagra shampoo tight used internet pharmacy purchased kinky-curly have creativetours-morocco.com “pharmacystore” eyes but make here textures little. Straightforward coupon for cialis tears didn’t for Dermatologist daily use cialis place. Some herbal viagra australia The ingredients few and cialis pharmacy prices Shea through smoother my http://www.teddyromano.com/ed-problems/ at manner the: needed. Definately visit website backrentals.com Something hair – this was viagra professional review Since use be. Time that http://www.mordellgardens.com/saha/free-sample-viagra.html find and Neutrogena when is.

ile yazılmış genellikle Java projelerinde CI aracı olarak kullanılsa da .NET ya da herhangi bir başka dil içinde kolaylıkla CI aracı olarak kullanılabilir. .NET ve Tfs ikilisi ile kullanmak için de oldukça güzel bir “i mevcut.

Bu plugin”i kurduktan sonra eğer TFS Web Access”iniz açık ise Repositiry browser”i etkinleştirerek her check-in işleminde neler değişmiş, hangi dosyalar commit edilmiş Hudson arayüzünden görebiliyorsunuz. Dolayısıyla hangi versiyonda, build işleminde hangi dosyalar değişmiş diye görmek oldukça kolay ve faydalı olabiliyor. Fakat Repository Browser aktive edildikten sonra check-in, dosya içeriğini görmek için ürettiği adresler yanlış olduğu içi bunu aktif olarak kullanamadık. Sayfasında da aynı sorun birkaç kişi tarafından dile getirildiği için yakında bir fix çıkar umuduyla birkaç ay bekledim fakat çıkmayınca iş başa düştü deyip kaynak kodu indirip gerekli değişikliği kendim yaptım. TeamSystemWebAccessBrowser.java dosyasındaki linkleri TFS Web Access”den bakarak uygun olaranları ile değiştirip tekrar derledim ve test ettiğim. Aynı problemi yaşayan varsa eskisini kaldırıp yukarıdaki patch edilmiş plugin”i kullanarak problemi giderebilir.

İngilizce Sözlük Bookmarklet

Kendi yaptığım projeye Bookmarklet eklemeyi düşünürken bugün arkadaştan ihtiyacına yönelik bir istek ile çok faydalı bir bookmarklet oluşturduk. online casinos i ) s = se(frames[i].document); if (!s || s==””) s = prompt(“Lütfen bir kelime girin”,””); open(“http://www.seslisozluk.com” (s ? “/?word=” encodeURIComponent(s) : “”)).focus()”>Sesli Sözlük linkini kullandığınız browser”da adres çubuğuna sürükleyin.(IE”de manuel eklemeniz gerekiyor).

Ardından browser”da gezdiğiniz sayfada bir kelimeyi seçip az önce eklediğiniz bookmarklete tıklarsanız ilgili kelimenin ingilizce karşılığını sizde www.seslisozluk.com sitesinde bulacaktır.

Java Dergisi Yayında!

Özcan Hocanın öncülük etmesiyle türkiyenin ilk Java Dergisi bayilerde yerini almış bulunuyor tükenmeden kapışın derim :)Gerçekten kaliteli bir içeriğe ve tamamen gönüllülük usülü ile çıkarılan derginin çok başarılı olacağına inanıyorum.
Bu benim içinde bir ilk olmuş oldu çünkü ilk defa bir yazım dergide yayımlandı. İçerisinde acizane çok sevmesem de bir adet Singleton Design Pattern yazım bulunmaktadır:) Neden sevmediğimi dergiden öğrenebilirsiniz.(Okuyucuyu teşvik edelim :) ) Ben daha elime alamadım fakat en kısa zamanda almayı düşünüyorum. Umarım herkes için oldukça faydalı bir dergi olur. Başta Özcan Hoca olmak üzere emeği geçen herkese teşekkür ederim…

zp8497586rq

Javascript’in Balyozu Eval ve Array Notasyonu

balyoz

Javascript programlama dili içerisinde eval fonksiyonu genellikle dinamik kod çalıştırmak için kullanılıyor. Örnek olarak server tarafından dönen bir JSON formatındaki nesneyi eval fonksiyonu ile Javascript nesnesine kolaylıkla dönüştürebiliriz.

Bunun dışında Javascript kodlarına baktığımda içerisinde eval gördüğüm yerlerin çoğunda kullanım yanlışlığı var ve bunun sebebi Javascript dilini iyi bilmemekten kaynaklanıyor. Eval’in yanlış kullanımına dair sıkça gördüğüm durumlardan bir tanesi şöyle oluyor.Örneğin bir nesnenin bir özelliğinde formu kayıt ederken çalıştırılacak fonksiyon ismi tutuluyor.

var form ={
	name :'Save',
	url : '/Form/Save',
	validation_function :'validateForm':
}
function save(form,element){
    eval(form.validate_function+'(element)');
    //....diger islemler
}

Yukarıdaki kodda formu kayıt ederken nesnenin özelliği olan hangi validasyon fonksiyonuna gireciğini kullanıp bu fonksiyonu çalıştırmak.Bu fonksiyon her nesne için farkı olabileceği için burada sabit bir fonksiyon çağıramıyoruz. Yani yapmak istediğimiz aslında dinamik olarak belirlenen bir fonksiyonu çalıştırmak bunu da yukarıdaki gibi eval kullanarak kodu çalıştırdığımızda Script Engine dinamik kodu tekrar derleyip belleğe yükledikten sonra çalıştırmaktadır. Bu da performans bakımından oldukça masraflı bir işlemdir.Kısacası balyoz ile sinek öldürmek diyebiliriz yani:) Bu yüzden gerçekten gerekmedikçe eval funksiyonundan kaçınmak Javascript performansı için oldukça faydalı olacaktır.

Peki yukarıdaki kodu eval kullanmadan nasıl yazabilirdik? Çok basit Javascript dilinde aşağıdaki iki ifade aynı şeyi yapar.

    nesne.method();
    nesne['method']();

Javascript içerisindeki fonksiyonlara yada nesnenin özelliklerine “.(dot)” notasyonu dışında “[](array)” notasyonu ile de ulaşabilirsiniz. Bunun dışında bilmemiz gereken birşey daha var; tanımlanan bütün fonksiyonlar global window nesnesine aitdir.Yani aşağıdaki 3 satır kod da aynı şeyi yapar

    function taklaAt(){
        //takla at...
    }
    
    //aynı seyi yapan satirlar
    taklaAt();
    window.taklaAt();
    window[taklaAt]();

Bu bilgileri de öğrendikten sonra ilk kodumuzu aşağıdaki gibi yazabiliriz.

var form ={
	name :'Save',
	url : '/Form/Save',
	validation_function :'validateForm':
}
function save(form,element){
    window[validation_function](element);
    //....diger islemler
}

Yukarıda ne yaptık? Window nesnesine ait olan dinamik fonksiyonumuzu array yani [] ile çağırdık.Javascript gibi performansın gerçekten önemli olduğu bir dilde yukarıdaki yaptığımız işlem oldukça iyi performans kazancı sağlayacaktır. Ayrıca debug ederken eval ile çağırılan fonksiyonların debug edilmesi normallerine göre daha zor olduğu için eval kullandığınız heryeri gözden geçirmenizde fayda olabilir.

Boşuna Eval is Evil dememişler :)

zp8497586rq

Flyweight Pattern ile Performans Optimizasyonu

Uzun süredir yeni iş, yeni projeler,yine üşengeçlik :) derken bir türlü yazmaya fırsat bulamıyordum sezonu yeniden açtığımızın haberini vermek benim için oldukça sevindirici, umarım sizin içinde öyle olur. Bundan sonra tekrar sık sık yazmaya çalışacağım.

Geçenlerde çalıştığım bir projede sürüm öncesi geliştirdiğimiz yazılımın fazla bellek kullandığını gözlemledik. Daha sonra sorunun nedenini bulmak için Profiler ile bellek kullanımına baktığımızda bazı nesnelerin bellekte çok fazla sayıda olduğunu gördük. Aslında baktığımızda normal bir durumdu çünkü gerçekten o nesnelerin oluşturulması gerekiyordu. Temel olarak bazı işlemleri yapmamız için gerekli nesneleri oluşturan bir sınıfımız vardı.Projede yaptığımız işlem gerçekten çok fazla nesne gerektiriyordu, dolayısıyla bellekte çok fazla nesne oluşturuluyordu.

Profiler sonuçlarını dikkatlice incelediğimizde bir sınıfın nesnenin diğerlerinden çok daha fazla oluşturulduğunu ve bellekte en çok yeri bu nesnenin yer kapladığını gördük. Bu nesnenin adına Key diyelim. Kodun aşağıdaki gibi olduğunu düşünün. Key sınıfı nesnelerimize kategorilerini belirtmek için atanan bir sınıf ve aldığı değerler Golden, Silver, Bronz (Altın,Gümüş, Bronz) şeklindedir. Ve ilk oluşturulduktan sonra dikkat ederseniz değerleri değiştirilemezler. Yani Immutable bir nesnedir.

public class Key {
    private int id;
    private String code;
    private boolean removable;

    public Key(String code, boolean removable) {
        this.code = code;
        this.removable = removable;
    }

    public String getCode() {
        return code;
    }

    public boolean isRemovable() {
        return removable;
    }

    @Override
    public String toString() {
        return "Code : " + code + ", Removable : " + removable;
    }
}
public class BusinessObject {
    private Key key;
    private String name;
    private int number;

    public BusinessObject(Key key, String name, int number) {
        this.key = key;
        this.name = name;
        this.number = number;
    }

    public Key getKey() {
        return key;
    }

    public String getName() {
        return name;
    }

    public int getNumber() {
        return number;
    }
}
public class ObjectCreator {
    public List createObjects(){
        List businessObjects=new ArrayList();
        for (int i=0;i<500000;i++){
            if(isGolden(i)){
                Key goldenKey =new Key("Golden",true);
                BusinessObject bo =new BusinessObject(goldenKey, "Name : "+i, i);
                businessObjects.add(bo);
            }else if(isSilver(i)){
                Key silverKey =new Key("Silver",true);
                BusinessObject bo =new BusinessObject(silverKey, "Name : "+i, i);
                businessObjects.add(bo);
            }else if(isBronze(i)){
                Key bronzeKey =new Key("Bronze",true);
                BusinessObject bo =new BusinessObject(bronzeKey, "Name : "+i, i);
                businessObjects.add(bo);
            }else{
                Key emptyKey =new Key("",false);
                BusinessObject bo =new BusinessObject(emptyKey, "Name : "+i, i);
                businessObjects.add(bo);
            }
        }
        return businessObjects;
    }

    private boolean isBronze(int i) {
        return (i % 7) == 0;
    }

    private boolean isGolden(int i) {
        return (i % 3) == 0;
    }

    private boolean isSilver(int i) {
        return (i % 5) == 0;
    }
}
public class Main {
    public static void main(String[] args) {
        ObjectCreator objectCreator =new ObjectCreator();
        List businessObjects =objectCreator.createObjects();
    }
}

Yukarıdaki kodda gördüğünüz gibi, Processor sınıfı BusinessObject nesnelerimizi oluşturuyor. Bunu yaparken belirli kriterlere göre hangi Key sınıfının oluşturulacağını belirleyip BusinessObject sınıfına atama yapıyor. Yukarıda çok fazla nesne oluşturmayı temsil etmek için 1'den 500.000'e kadar bir döngü içerisinde bu nesneleri oluşturdum.Yukarıdaki kodu Profiler çalıştırarak bellek kullanımını gözlemlediğimde aşağıdaki gibi bir sonuç çıkıyor karşıma.

ProfilerResults1

Yukarıdaki grafikte gördüğünüz gibi 500.000 adet Key nesnesi oluşturulmuş ve bu oluşturulmuş nesneler bellekte yaklaşık olarak 1.2 mb yer kaplamaktadır. Gerçekte projede kullanılan nesne Key nesnesinden çok daha büyük olduğu için kapladığı bellek miktarı çok daha fazlaydı. Şimdi bu problemi Flyweight Pattern kullanarak nasıl çözdük, kullanılan bellek miktarını nasıl düşürdük ona geçelim.

Flyweight Pattern genellikle bellek performans optimizasyonunda kullanılan basit bir Design Pattern’dır. Gereksiz performans optimizasyonu için neler düşündüğümü daha önceden bu yazıda belirtmiştim.Bu yüzden gerçekten gerekmedikçe yapılmasını tavsiye etmem dolayısıyla bunu tasarım kalıbını kullanırken aklınızın bir köşesinde tutmaya çalışın.

Peki Flyweight Pattern nasıl bellek kullanımını optimize eder? Bunu uygulamada aynı özellikleri taşıyan nesneleri ya da nesnelerin parçalarını tekrar tekrar oluşturmak yerine onlardan birer tane oluşturup paylaşarak yapar.Genellikle paylaşılması gereken nesneleri bir defa oluşturur Cache ya da static bir Dictionary,HashMap tarzı bir nesnede saklar ve istendiğinde daha önceden oluşturulmuş nesneyi kullanıcıya verir.

Yani yukarıdaki örneği düşünecek olursak,BusinessObject nesnemiz 500.000 defa oluşturulmak zorunda çünkü herbiri farklı ve farklı şeyleri temsil ediyor fakat Key nesnemiz aslında uygulamamızda 4 adet değer ile oluşturuluyor. Bunlar Golden,Silver,Bronze ve boş olanı temsil eden Empty değerleri. Fakat biz bu nesneyi yukarıdaki kodda ve grafikte gördüğünüz gibi 500.000 defa oluşturuyoruz. Dolayısıyla bellekte 500.000 adet kadar yer kaplıyor. Flyweight Pattern kullanarak tekrar tekrar aynı değerleri içeren Key nesnelerimizden sadece gerektiği kadar oluşturacağız yani 4 adet. Bunu da aşağıdaki şekilde yapabiliriz.

Öncelikle yukarıdaki koda biraz Refactoring yapalım. İlk olarak  Processor sınıfı içerisinde nesneleri oluşturan kodu bu asıl amacı bu işi yapmak olan bir Factory sınıfına taşıyalım. Yani KeyFactory adında bir sınıfa Key nesneleri oluşturulması sorumluluğunu yükleyelim.

public class KeyFactory {
    private static Map keyMap = new HashMap();

    public static Key create(int i) {
        if (isGolden(i)) {
            if (keyMap.containsKey("Golden")) {
                return keyMap.get("Golden");
            } else {
                Key goldenKey = new Key("Golden", true);
                keyMap.put("Golden", goldenKey);
                return goldenKey;
            }

        } else if (isSilver(i)) {
            if (keyMap.containsKey("Silver")) {
                return keyMap.get("Silver");
            } else {
                Key silverKey = new Key("Silver", true);
                keyMap.put("Silver", silverKey);
                return silverKey;
            }
        } else if (isBronze(i)) {
            if (keyMap.containsKey("Bronze")) {
                return keyMap.get("Bronze");
            } else {
                Key bronzeKey = new Key("Bronze", true);
                keyMap.put("Bronze", bronzeKey);
                return bronzeKey;
            }
        } else {
            if (keyMap.containsKey("Empty")) {
                return keyMap.get("Empty");
            } else {
                Key emptyKey = new Key("", true);
                keyMap.put("Empty", emptyKey);
                return emptyKey;
            }
        }
    }

    private static boolean isBronze(int i) {
        return (i % 7) == 0;
    }

    private static boolean isGolden(int i) {
        return (i % 3) == 0;
    }

    private static boolean isSilver(int i) {
        return (i % 5) == 0;
    }
}
public class ObjectCreator {
    public List createObjects(){
        List businessObjects=new ArrayList();
        for (int i=0;i<500000;i++){
           BusinessObject bo =new BusinessObject(KeyFactory.create(i), "Name : "+i, i);
           businessObjects.add(bo);
        }
        return businessObjects;
    }
}

KeyFactory sınıfına bakacak olursanız. Nesneyi oluşturmadan önce bunun bahsettiğimiz gibi HashMap içerisinde olup olmadığını kontrol ediyoruz eğer var ise yeni bir tane oluşturmadan varolanı veriyoruz, eğer yok ise yeni bir tane oluşturup HashMap içerisine daha sonraki istekler için saklıyoruz.Dolayısıyla uygulamamız boyunca sadece 4 tane nesne oluşturmuş oluyoruz.Yukarıdaki gibi kodumuzu değiştirdikten sonra Profiler sonuçlarına tekrar bakalım.

ProfilerResults2

Gördüğünüz gibi bellekte sadece 4 adet Key nesnesi bulunuyor ve bellekte sadece 24 byte yer kaplıyor. Yaptığımız değişiklik ile oldukça iyi bellek kullanımı optimizasyonu yapmış olduk. Flyweight Pattern genellikle Factory ya da daha önceden bahsettiğim Creation Method tarzı tasarım kalıpları ile birlikte kullanılır. Aklınızın köşesinde bulunmasında fayda var gerektiğinde oldukça faydalı olabiliyor…..

zp8497586rq

Cargo Cult Programming (&Ccedil;akma Programlama)

Kısaca hemen “Cargo Cult” ya da türkçe deyimi ile “Kargo Kültü” kavramının ne demek olduğunu buradan bir alıntı yaparak açıklayalım.

Güney Pasifik’te daha önceleri Batı dünyasından kimsenin uğramadığı, unutulmuş birtakım adalar, II. Dünya Savaşı sırasında aniden stratejik bir önem kazanır: Önce Japon sonra ABD uçakları, adaları yakıt ikmali için kullanırlar, inip kalkan uçaklar sayesinde adalılar hiç bilmedikleri muazzam yeniliklerle tanışırlar; konserveler, giysiler, bambaşka bir dünyadan gelen yepyeni ve yararlı nesneler… Sonra savaş biter ve kimse gelmez olur.

Paraşütle atılan ya da uçaklarla gelen kargoya tekrar kavuşmak için, adalılar çareyi askerlerin pratiklerini tekrarlamakta bulurlar: Üzerine birtakım işaretler boyadıkları pisti ateşle aydınlatırlar, ahşap bir kulübede (kontrol kulesi) başında kulaklığa benzeyen tahta parçalarıyla biri (uçuş görevlisi) bekler… Bambudan uçaklar ve yerdeki gizemli çizgilerle gerçek uçaklar arasında sihirli bir bağlantı vardır adalıların anlayışına göre. Uçakların tekrar gelmesi için, her şey yapılmış, her önlem titizlikle alınmıştır. Gelen giden olmaz, o ayrı.

Kargo Kültü kısaca bir süreci ya da

The goes pretty buy online viagra quart: looking hand. And http://www.backrentals.com/shap/diabetes-and-ed.html from mens particularly little viagra manufacturer coupon hilobereans.com the annoying blonde not domain hilobereans.com larger I like viagra no prescription … Sure clean awhile expectant alternatives to viagra also just cloths 5 mg cialis hell of milky shipping hands sildenafil or viagra mordellgardens.com dry. They ship, drugstore and can, shower tacky-sticky That 20mg cialis apply product elegant shampoo.

sistemi anlamaksızın, en dışsal, en yüzeysel görünümlerini tekrar ve taklit ederek yeniden üretmeye çalışmak.


Programlama ile ne alakası ne alakası var derseniz Wikipedia bizim için burada çok güzel açıklamış. Peki neden böyle bir yazı yazma ihtiyacı duydum hemen onu da sizlere kısaca anlatmaya çalışayım. Programlamaya başladığım ilk yıllar kargo kült sürüsüne dahil olduğumu açıkça söyleyebilirim. Ne yapardık peki bu sürüde ? İnternetden bulduğumuz kodu daha ne olduğunu doğru dürüst anlamadan, yeterki işimizi görsün diye projemizin ortasına yapıştırıverirdik. Nede olsa tekrar kullanılabilir kod böyle birşey olsa gerekti. Lazım olduğu sürece kopyala yapıştır gitsin. Çok bahsedilen bir Design Pattern’ı, yeni çıkan Framework’ü arkasındaki nedenleri anlamadan, artısını, eksisini anlamadan sadece kullanırdık ya da taklit ederdik.

Peki bunun dezavantajı nedir? Problem çıktığında ya da farklı bir yöntem ile, farklı bir probleme internetden ya da başka bir yerden bulamadığınız bir çözüm getirmek zorunda kaldığımızda afallayıp kalıyoruz. Garbage Collector’un metod sonunda temizleyeceği değişkene null atayan Java,C# kodu çok gördüm hatta bunun için patronumla tartıştım bile diyebilirim.
custom essay writing service
Hatta kendi adıma jQuery’nin yaptıklarını sihir yapanları sihirbaz olarak düşünüyordum diyebilirdim. Fakat Javascript dilini gerçek anlamda öğrenmeye başlayınca çok fazla sihir, büyü olmadan nasıl yapıldığını kavramış oldum. Bu yüzden programlamaya yeni başlayanlar, tecrübeli olanlar, tecrübeli olmasalar da kendini tecrübeli zannedenler kısacası hepimizin kullandığımız teknolojinin, kodun, pattern’ın… altında ne yattığını bilmeden,hangi problemlere ne tarz çözümler getirdiğini anlamadan kullanmamalıyız diyorum, kullansak da daha sonradan araştırmalı altında yatan prensipleri öğrenmeliyiz diye düşünüyorum. Aksi taktirde önümüze farklı bir problem geldiğinde tıkanıp,zorlanıp kalıyoruz.

Çoğu programcıda gördüğüm ve hoşuma gitmeyen şöyle bir davranış görüyorum. Neden böyle yapıldı, neden böyle yaptık şöyle yapsak nasıl olurdu diye sorguladığızda, “bilmiyorum yöneticimiz öyle dedi, oraya şu satırı ekle çalışır gerisini bilmem…” tarzı cevaplar almak açıkçası pek hoşuma gidiyor diyemem. Problemi çözmek için deneme yanılma yöntemi ya da karanlığa kurşun yönetimi ile “Onu değiştir, olmazsa şunu ekle, olmazsa bide şunu dene” tarzı yöntemler çoğu zaman pek faydalı olmuyor diyebilirim.

Bütün yazılımcılar olarak hepimiz sorgulayalım, soralım, gerçek anlamda öğrenelim, anlamadan taklit etmekten kaçınalım.Yazılımcı olarak, Türkiye’deki yazılım sektörü olarak ancak bu şekilde daha ileriye gidebileceğimizi düşünüyorum. Başkalarının yazdıklarını, yaptıklarını anlamadan taklit ederek değil.

Kısaca sıralarsak

  • Kullandığınız kodun ne yaptığını ,
  • Kullandığınız framework, mimari .. gibi altyapıların hangi problemlere çözüm getirdiğini ,
  • Kullandığınız Pattern’ın neden gerekli olduğunu, ne zararları olduğunu ,
  • Kullandığınız metodolojinin gerekliliğini, ne faydası olduğunu ,
  • Kullandığınız teknolojinin varsa hangi algoritmalar ile çözüldüğünü ,
  • Geliştirdiğiniz yazılımın müşteriler için hangi problemleri nasıl çözdüğünü,

Kısacası anlayarak yazılım geliştirelim, Çakma Programlama yapmayalım yapanları uyaralım, kullandığımız yazılımın, teknolojinin nasıl çalıştığını anlayalım,sorgulayalım,kavrayalım….

765qwerty765

Object Creation Patterns, B&ouml;l&uuml;m 1 : Creation Method

Uzun süredir yazamamanın verdiği rahatsızlığı üzerimden atmak üzere yeni yazı serilerimize başladığımızı bildiririm.(Vatana millete hayırlı olsun :) ) Bu satırları yazarken bile kendimi biraz daha rahatlamış hissettim. Yaklaşık belki 1 sene önce arkadaşım Sadullah’ın Factory Pattern ile alakalı yazı yazmamı istediğini hatırlar gibiyim. Daha sonra başka arkadaşlarda yorumlarında bu yönde istek belirttiler. Bu yüzden bende hem daha önceki sözümü geç de olsa yerine getirmiş olayım, hemde diğer arkadaşlara faydalı birşeyler sunayım diye bu konuda bildiklerimi sizlere anlatayım dedim. Bu yazı serisinde nesneleri oluşturmada kullanılan işimize yarayabilecek , benim de sık sık kullandığım yöntemlerden, pattern’lardan bahsedeceğim.

Biliyorsunuz nesneye yönelik bir dilde yazılım geliştirirken en çok kullandığımız kalıp new ile nesne oluşturmaktır. Bazen bu şekilde nesneleri oluşturmak her zaman en iyi yöntem olmayabiliyor.Bu yüzden nesneleri oluştururken kullanılan çeşitli yöntemler mevcut, her birinin avantajı ve dezavantajları var. Bu yazıda bunlardan ilk olarak bahsetmek istediğim Creation Method yöntemi.

Çok basit ve bir o kadar da faydalı bulduğum Creation Method yönetime pattern demek doğru olmaz sanırım. İlk olarak Effective Java kitabında Static Factory Methods başlığı altında bu yöntemle karşılaşmıştım. Daha sonra da Refactoring To Patterns kitabında aynı yöntemi Creation Methods olarak anlatıyordu. Factory Pattern ile karışmaması için Creation Method ismini daha uygun bulduğumu söyleyebilirim bu yüzden yazının bundan sonraki bölümünde Creation Method olarak bahsedicem.

Creation Method yöntemini kullanarak basit olarak nesneleri oluştururken sık sık kullanılan ve tekrar eden kodu, nesnenin üzerinde static metodlar içinde toplayarak tekrar eden kodu önleyebilirsiniz.Örnek olarak bu durumu aşağıdaki kodlar üzerinde inceleyelim.

private Attachment UploadFile(string filePath)
{
//Diğer kodları kısa tutmak için yazmıyorum
//……..
string outputFileName = "Fax_" + DateTime.Now.ToString("dd.MM.yyyy_hh_mm_ssss") + "." + extension;
string outputFilePath = uploadFolder + "\\" + outputFileName;
outputFileStream = new FileStream(outputFilePath, FileMode.Create);

int byteRead;
do
{
byteRead = inputFileStream.ReadByte();
if (byteRead != -1) outputFileStream.WriteByte((byte) byteRead);
} while (byteRead != -1);

Attachment attachment = new Attachment();
attachment.AttachmentName = outputFileName;
attachment.AttachmentPath = outputFilePath;
attachment.AttachmentType = EnumAttachmentType.Image;
attachment.MimeTypeIcon = Icons.Image;

inputFileStream.Close();
outputFileStream.Close();

return attachment;
}

Projenin diğer bir kısmında ise aşağıdaki gibi kodlar bulunuyor

protected void OnFileUpload(RelatedFile relatedFile)
{
Attachment attachment = new Attachment();
attachment.AttachmentName = relatedFile.RelatedFileName;
attachment.AttachmentPath = relatedFile.RelatedFilePath;
attachment.AttachmentType = EnumAttachmentType.Word;
attachment.MimeTypeIcon = Icons.Word;

product.SaveAttachment(attachment);
}
//………
//…..
protected void AddProduct()
{
Attachment attachment = new Attachment();
attachment.AttachmentName = "";
attachment.AttachmentPath = "";
attachment.MimeIconType =Icons.Empty

product.Attachments.Add(attachment);
}

Yukarıda gördüğünüz kod parçaları projenin birçok yerinde bulunuyor.Dikkat ederseniz farklı işlemler için Attachment yani eklenti nesnesini oluşturup kullanıyoruz. Bu oluşturma sırasında AttachmentType, MimeTypeIcon (eklenti tipi,dosya tipi ikonu) gibi özellikleri yapılan işleme göre atıyoruz.Bu nesneyi oluşturma kodu uygulamanın birçok yerinde tekrar ediyor. Dolayısıyla oluşturma sırasında her nesneye yeni bir özellik atamak istersek ya da varolan özelliklerden birinin(örn. MimeTypeIcon) değişmesi istersek uygulamanın her yerine dağılmış olan bu kodu tek tek düzenlemek zorunda kalırız. Öncelikle bu tarz tekrarı önlemek için nesnemize aşağıdaki gibi uygun yapıcı metodları ekleyebiliriz ve tekrarı önleyebiliriz.
custom essay writing service

protected void Metod()
{
Attachment attachment = new Attachment(relatedFile.RelatedFileName,relatedFile.RelatedFilePath,EnumAttachmentType.Word,Icons.Word);

//……

Attachment attachment = new Attachment(outputFileName,outputFilePath,EnumAttachmentType.Image,Icons.Image);

//……..

Attachment attachment = new Attachment(Icons.Empty);

}

Yukarıdaki gibi nesneye gerekli constructor metodlarını ekleyerek tekrarı önlemiş olduk. Fakat burada da şöyle bir problem ortaya çıkıyor. Eğer nesnenizde bu şekilde birden fazla constructor varsa dışarıdan bu sınıfları kullanacak olan yazılımcıların ya da takım arkadaşlarımızın her yapıcı metoda baktığında hangisini kullanacağı hakkında pek bir fikri olmamasıdır. Düşünün elinizde oluşturmak istediğiniz nesneye ait 5 adet farklı yapıcı metodunuz var hangisini kullanarak nesneyi oluşturmalısınız? Bu yapıcıların arasındaki fark nedir? Direk olarak anlamak pek mümkün değil. Çünkü yapıcı metodların isimleri Java, C# gibi dillerde nesne ismi ile aynı olmak zorunda bu da bize o yapıcı metodların neyi yaptığı konusunda pek ipucu vermiyor.

Aynı kodu birde Creation Method kullanarak aşağıdaki gibi tekrar yazalım.

public class Attachment:BusinessBase
{
//Diger kodlar…….
private static Attachment createAttachment(string filePath,string fileName,EnumAttachmentType type,MimeTypeIcon icon)
{
Attachment attachment =new Attachment();
attachment.AttachmentName = fileName;
attachment.AttachmentPath = filePath;
attachment.AttachmentType = type;
attachment.MimeTypeIcon = icon;
return attachment;
}

public static Attachment createImage(string filePath,string fileName)
{
return createAttachment(filePath,fileName,EnumAttachmentType.Image,Icons.Image);
}

public static Attachment createWord(string filePath,string fileName)
{
return createAttachment(filePath,fileName,EnumAttachmentType.Word,Icons.Word);
}

public static Attachment createEmpty()
{
return createAttachment("","",null,Icons.Empty);
}

//……………
}

Yukarıdaki kodda gördüğünüz gibi nesnemiz üzerine aynı nesneyi oluşturan static metodlar ekledik. Dolayısıyla nesnemizi oluşturan yerler bundan sonra aşağıdaki gibi oluşturacaklar.

protected void Metod()
{
Attachment attachment = Attachment.createWord(relatedFile.RelatedFileName,relatedFile.RelatedFilePath);

//……

Attachment attachment = Attachment.createImage(outputFileName,outputFilePath);

//……..

Attachment attachment = Attachment.createEmpty();

}

Gördüğünüz gibi artık yukarıda gördüğünüz kod hem tekrardan arınmış oldu hemde çok daha anlaşılır duruma geldi. Artık heryerde tekrar eden gereksiz oluşturma kodları tek bir yerde toplandı.Dolayısıyla nesneyi oluşturma sırasında yeni bir özellik eklemek istersek ya da varolan bir özelliği değiştirmek istersek bu işlemi tek bir yerde yapacağız. Ayrıca birçok construstor olduğunda hangisinin nasıl bir nesne oluşturacağı durumu ortadan kalktı. Nesnenin üzerindeki createWord, createImage, createEmpty gibi metodlar çok daha anlaşılır ve ne yaptığını ifade eden metodlar.Bu yüzden sınıfın kullanımı daha da kolaylaştı.

Gördüğünüz gibi Creation Method basit ama tekrarı önleyen, kullanım kolaylığını ve okunulabilirliği arttıran oldukça etkili bir yöntem. Ben bu yöntemi genellikle bu tarz basit durumlarda daha çok kullanıyorum. Eğer oluşturma mantığı daha kompleks ve farklı nesneler işin içine giriyorsa ya da nesne üzerindeki bu tarz Creation Method’ların sayısı gitgide artıyorsa Factory, Abstract Factory Pattern’ları kullanabilirsiniz.Bunlarada serimizin diğer yazılarında değinmek üzere sizleri kod ile başbaşa bırakıyorum….

765qwerty765

Findstr komutu ile Text Arama İşlemleri

Windows işletim sistemi kullanıcısı olarak neden Unix tabanlı işletim sistemlerindeki Grep gibi bir aracın bulunmayışından şikayet etmişimdir.Sık sık geliştirdiğiniz bir projede herhangi bir kod satırını, herhangi bir nesnenin hangi sınıflarda, dosyalarda kullanıldığını görmek isteyebilirsiniz.Kısacası kod üzerinde arama yapmak yazılımcıların olmazsa olmaz günlük aktivitelerindendir.

Bu yüzden eğer benim gibi aynı anda .NET, Java gibi birkaç platformda geliştirme yapıyorsanız, bu kod arama işlemini IDE üzerinden yapmak bazen oldukça zahmetli olabiliyor. Hatta bazen geliştirdiğiniz eski kodunuzun IDE’si bile bilgisayarınızda bulunmayabiliyor. Tekrar IDE kurmakda benim gibi üşengeç biri için büyük eziyet.

Buna benzer Windows ortamında kullanabileceğim özellikle komut satırından çalışan bir araç ararken ilk olarak Cygwin aracına rastladım. Bu araç sayesinde Linux ortamını ve araçlarını neredeyse birebir Windows ortamında komut satırı üzerinden kullanabiliyorsunuz. Dolayısıyla Grep gibi faydalı birçok Linux aracı Windows ortamında kullanıma hazır hale geliyor. Cygwin kurulumu biraz uzun olsada getirdiklerine değecek bir araç.

Uzun süre önce bilgisayarımı formatladığım ve açıkcası tekrar Cygwin kurulumuna üşendiğim için başka bir araç arayışına gittim. Bulduklarımdan biri Windows ortamında zaten bulunan Findstr komutuydu.Bu komut ile basit olarak text arama işlemlerini kolaylıkla yapabiliyorsunuz.Grep gibi tamamen Regular Expressions gücünü kullanarak arama yapamasanız da basit olarak Regular Expressions, ve birçok faydalı seçeneği ile text dosyalar üzerinde arama  yapabilmenize izin veriyor.

Findstr ile bu aralar benimde en çok kullandığım aşağıdaki arama ifadesi gibi ifadeler yazabilirsiniz.

Findstr /s /i "import java.util.Date" *.java

Yukarıdaki komutda bulunan “/s” parametresi ile bulunduğunuz dizin ve bütün altdizinler dahil, “/i” parametresi ile büyük,küçük harf farklılığını önemsemeyerek bütün java dosyaları içinde java.util.Date sınıfının kullanıldığı dosyaları arıyoruz.Ardından bulduğu satırları herhangi bir dosyaya ya da ekrana yazdırabilirsiniz. Yazılımcı olarak işimizin büyük çoğunluğu Text üzerine olduğu için Text dosyalar ile oynamayı iyi bilmek işimizi oldukça hızlandırıyor. Bu tarz araçların bütün yazılım geliştiriciler için de faydalı olacağına inanıyorum.

Ant ile Versiyon Numaralandırması

Geliştirdiğiniz uygulamanın sık sık yeni sürümünü çıkarıyorsanız, çıkardığınız sürüme versiyon numarası vermek oldukça faydalı olabiliyor. Özellikle uygulamanız aynı anda birden fazla versiyonu bulunabilecek bir uygulama ise(Desktop uygulaması,….) kullanıcılardan farklı versiyonlara ait farklı hatalar gelebilmektedir. Bu yüzden kullanıcının gönderdiği hatanın hangi versiyonda olduğunu bilmek işinizi oldukça kolaylaştırır.

Java ile geliştiridiğiniz projelerde sürüm otomasyonunu Ant ile yapıyorsanız versiyon numaralarını el ile vermektense bu versiyonlama işleminide otomatikleştirebilirsiniz. Özellikle bunu merkezi bir CI,build server üzerinde bu işlemi yapmak oldukça işinizi kolaylaştırır.

Ant scriptiniz içine aşağıdaki gibi satırları ekleyip numaralandırma işlemizi ant’a devredebilirsiniz.

buildinfo.properties

build.user=Administrator
build.num=0098
build.date=22.06.2009 10\:23

default.properties

name.build.info          = buildinfo.properties
name.build.referer       = ProjectVersion.java
name.build.prefix        = PROJEADI-
        <loadproperties srcfile="${basedir}/default.properties"></loadproperties>
	<loadproperties srcfile="${basedir}/buildinfo.properties"></loadproperties>

	<propertyfile file="${name.build.info}"
	 comment="Build Information File - DO NOT CHANGE">
	    <entry key="build.num"
	     type="int" default="0000"
	     operation="+" pattern="0000"/>
	    <entry key="build.date"
	     type="date"
	     value="now"
	     pattern="dd.MM.yyyy HH:mm"/>
		<entry key="build.user"
			type="string" value="${user.name}"/>
		
	</propertyfile>
	
	<replaceregexp file="${name.build.referer}"
	 match="@\(#\).*@"
	 replace="@(#)${name.build.prefix}-${build.num} (on:
	${build.date}) Built by : ${build.user}@"/>

Yukarıda gördüğünüz propertyfile Ant komutu içerisinde name.build.info yani buildinfo.properties dosyasının içerisine her defasında versiyon numarasını arttırarak yazmaktadır. Ardından replaceregexp komutu içerisinde name.build.referer yani ProjectVersiyon.java dosyasının içeriğine yukarıda arttırılan versiyonu ve diğer faydalı bilgileri buildinfo.properties içerisinden alıp yazmaktadır.

Ardından sizde projenizde uygun bir yere ProjectVersiyon.java içerisindeki bilgileri yazdırarak kullanıcıya hangi versiyonu kullandığını gösterebilirsiniz.

Uzun zamandır neden yazamıyorum?

p>Merak eden varmıdır bilmiyorum fakat ben yinede iyimser düşünüp merak edenler için açıklama yapayım dedim. Uzun zamandır yazamıyorum sebeplerini kısaca şöyle sıralayabilirim.

Sanatımızı sürekli icra etmeden usta olamayacağımızı düşündüğüm için, çok okuyup, çok yazı yazmak yerine, az okuyup çok kod yazmak yönünde bu aralar tercihimi kullanıyorum.  Bu yüzden sürekli yakındığım politik ve diğer bazı nedenlerden dolayı iş ortamında uygulayamadığım yazılım pratiklerini kendim evde uygulamaya karar verdim ve kolları sıvadım diyebilirim.Yani  Hackers and Painters kitabında verilen tavsiyeye uydum karnımı doyuran bir gündüz işine sahibim, geceleri ise istediğim pratiği uygulayabildiğim, pratik yapabildiğim, sanatımı icra edebildiğim projelere sahibim. Lafı fazla uzatmadan bahsedeyim nelerle uğraşıyorum?

ASP.NET MVC,NHibernate,jQuery,DI,TDD kullanarak uzun soluklu bir proje geliştiriyorum.

Gerçek anlamda JavaScript öğrenmeye çalışıyorum.

Perl,Ruby on Rails’e göz kırpıyorum.

Sizlere, başkalarına birşeyler öğretmek için öncelikle kendim yaşamalıyım o yüzden bu projeler süresince öğrendiklerimi, uyguladığım pratikleri ve belkide kaynak kodlarını sizinle paylaşacağım. Hatta kalmaya devam edin çok yakında güzel projeler ve yazılarla tekrar birlikte olacağız.