Oct 05 2009

Cargo Cult Programming (Çakma Programlama)

Tag: GenelM. Cihat Altuntaş @ 6:03 pm

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 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.

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….


Aug 25 2009

Object Creation Patterns, Bölüm 1 : Creation Method

Tag: Patterns,PrinciplesM. Cihat Altuntaş @ 6:08 pm

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.

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….


Jun 29 2009

Findstr komutu ile Text Arama İşlemleri

Tag: ToolsM. Cihat Altuntaş @ 7:55 am

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.


Jun 25 2009

Ant ile Versiyon Numaralandırması

Tag: Build AutomationM. Cihat Altuntaş @ 4:50 am

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.


May 05 2009

Uzun zamandır neden yazamıyorum?

Tag: GenelM. Cihat Altuntaş @ 3:24 pm

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.


Apr 01 2009

Yazılım Mühendisi Maaş Anketi

Tag: GenelM. Cihat Altuntaş @ 4:53 pm

Daha önceden yazdığım Yazılım Mühendisi Maaşı yazısından en çok okunan yazılardan biri oldu. Ayrıca birçok kişi tarafından yorum yapıldı ve kaç YTL maaş alındığı konusunda sorular soruldu. Bu yüzden daha önceden belirtmediğimiz rakam olarak maaş konusunu açıklığa kavuşturalım istedim. Hemde sektöre girenler, girecekler.. için bir klavuz olsun.

Maaş Anketi

View Results

Loading ... Loading ...

Maaş ücretleri için yukarıda gördüğünüz anketi hazırladım. Fakat yazılım sektöründe maaş konusu tecrübe, uzmanlık, çalıştığınız il,okul.. gibi birçok parametreye göre değiştiği için anketten ziyade bu yazının sonuna yorum olarak isminizi vermeden

  • Mezun olduğunuz okul
  • Mezun olduğunuz bölüm
  • Çalıştığınız İl
  • Çalıştığınız uzmanlık alanınız
  • Sene olarak tecrübeniz
  • Aldığınız brüt ya da Net Maaşınız

Yazarsanız bu konuda oldukça meraklı olan arkadaşları oldukça sevindirirsiniz. Mühendis, programcı, başka alandan mezun olup yazılım alanında çalışan kısacası Yazılım Uzmanı olan herkesin anketi doldurmasını temenni ediyorum.  Yorumların arasına bende kendi maaşımı ekleyeceğim ama isimsiz tabi :)


Apr 01 2009

Basit Bir Abstraction Örneği

Tag: Code Smells,Yazılım MühendisliğiM. Cihat Altuntaş @ 4:29 pm

Object Oriented tasarım ve programlamada soyutlamanın her zaman önemini vurgulamışımdır. Yazılım geliştirirken soyutlamalar sayesinde yazılımı daha yönetilebilir parçalara, modüllere ayırıp daha esnek yazılımlar geliştirebiliyoruz. Buna geliştirdiğim yazılımdan küçük bir örnek vermek istedim.

Geçenlerde Hibernate Log dosyalarını parse eden bir program yazdığımı burada belirtmiştim.  Program belirli bir dizideki .log uzantılı dosyaları parse edip içlerinden SQL cümlelerini çıkarıyordu. Ekranda bulunan bir butonun altında yazılan kodda seçilen log dizininin altındaki log dosyalarını alıp Parser sınıfına işlemesi için gönderiyordu. Kodun ilk yazılan şekli aşağıdaki gibiydi.

private void openFileActionPerformed(java.awt.event.ActionEvent evt) {
    try {
       //log dosyalarını seçili dizinden alıyoruz

       File directory =fc.getSelectedFile();
       FilenameFilter filter = new FilenameFilter() {
            public boolean accept(File dir, String name) {
                return name.endsWith(".log");
            }
        };
        File[] files =directory.listFiles(filter);

        //*****************

        for (File file : files) {
            Parser parser = new Parser(file);
            sqlLogs = parser.parse();
            for (SqlLog sqlLog : sqlLogs) {
                listModel.addElement(sqlLog);
            }
        }

    } catch (Exception ex) {
        showMessage(ex.getMessage());
    }
}

Yukarıdaki basit bir işlem fakat metodun iki işi bir arada yaptığını fark ettiniz umarım. Log dosyalarını listeleme ve bu dosyaları parse etme. Ayrıca uygulamamı düşündüğümde şöyle bir ihtiyacım olduğunu anlıyorum.Uygulamam “Log dizinindeki dosyaları parse etme” işlemini yapıyor. Bu yüzden basit ama kodu ve yönetimi arttıran yeni bir sınıf ekliyorum. Aslında kısacası soyutlama yapıyorum. Uygulamam da daha önceden geçen “Log Dizini” dediğim kavram için bir sınıf oluşturuyorum. Kodu aşağıdaki gibi değiştirdim.

public class LogDirectory {
    private File directory;

    public LogDirectory(File directory) {
        this.directory = directory;
    }

    public File[] getLogFiles() {
        FilenameFilter filter = new FilenameFilter() {
            public boolean accept(File dir, String name) {
                return name.endsWith(".log");
            }
        };
        return directory.listFiles(filter);
    }
}

Yukarıdaki kodda basit bir soyutlama yaptım. Log dizinindeki dosyaları getiren işi ayrı bir sınıf olarak uygulamaya ekledim.Metod aşağıdaki hale geldi.

private void openFileActionPerformed(java.awt.event.ActionEvent evt) {
    try {
        LogDirectory logDirectory =new LogDirectory(fc.getSelectedFile());
        File[] files = logDirectory.getLogFiles();

        for (File file : files) {
            Parser parser = new Parser(file);
            sqlLogs = parser.parse();
            for (SqlLog sqlLog : sqlLogs) {
                listModel.addElement(sqlLog);
            }
        }

    } catch (Exception ex) {
        showMessage(ex.getMessage());
    }
}

Küçükde olsa bu tarz soyutlamanın uygulama için oldukça önemli olduğunu düşünüyorum.


Apr 01 2009

Fırat Üniversitesi Seminer Notları

Tag: GenelM. Cihat Altuntaş @ 6:27 am

Mart ayının son haftasında Ceturk davetlisi olarak Elazığ Fırat Üniversitesi etkinliğinde Design Patterns konusunda konuşmacı olarak bulundum. Özcan Acar,Mehmet Aca ve Gökay Okutucu ile tanışmak güzeldi.

Seminer notlarını ancak şimdi yazabiliyorum.Notları derken “seminerde şunu yaptım,bunu yaptım, şuraları gezdim” gibi cümlelerden ziyade bildiklerimi öğretmek için gittiğim seminerden neler öğrendim ondan bahsetmek istiyorum.

  • Bilen öğretir, bilmeyen yönetir. (Ramazan hocaya sonsuz teşekkürler.)
  • İstekler sonsuz, kaynaklar sınırlı.(Özellikle zaman)
  • Kendimi sunum konularında geliştirmeliyim :)

Mar 20 2009

Yazılım Mimarisi Tasarım Günü

Tag: GenelM. Cihat Altuntaş @ 9:39 am

Tasarım Günü

Tası tarağı topladık Elazığ yollarına düştük. Yarın Ceturk’ün davetlisi olarak Fırsat Üniversitesinde Design Patterns üzerine bir sunum yapacağım sizleride beklerim…


Mar 17 2009

Yazılım Mimarı Kod yazmalı mı?

Tag: GenelM. Cihat Altuntaş @ 8:34 am

Orjinal adıyla “Should architects write code?” olan meşhur soruya kendi kişisel cevabımı burada vereyim. Soru belki binlerce kez cevaplandı, herkes kendince fikirlerini belirtti fakat yinede birkaç ayda bir bu sorununun yazılım dünyasındakilere hatırlatılması gerektiğini düşünüyorum.Peki neden?

Yazılım mimarı ünvanı adı altında,ya da projede yazılımın tasarımında,mimarisinde rol alan insanların genelde şöyle bir eğilimi olduğunu sık sık görüyorum. Yazılım mimarı arkadaş gereksinimlere göre Visio, Enterprise Architect,Rational Rose…gibi araçlarda güzel güzel UML diyagramlarını çizmiştir.Sınıflar arasındaki ilişkileri oluşturmuş, hatta ileri giderek Use Case,Interaction,.. diyagramları çizmiştir.Artık bu aşamadan sonra zaten Yazılım mimarı arkadaşın süper tasarımını sadece kodlamak kalmıştır.”Ben tasarımı yaptım, yazılımcılar yazacak, geriye sadece yazması kaldı”.

Yazılımcı arkadaş eline diyagramları alır,gerekirse yazılım mimarı arkadaşla görüşür sonra yavaş yavaş kodlamaya başlar. Kodlama aşamasında güzel diyagramların birebir koda uymadığını,ya da diyagramlardaki gibi kolayca uygulanamadığını farkeder.Bu aşamadan sonra Yazılım Mimarı arkadaşla tekrar görüşürse, yazılım mimarı ufak birkaç tavsiye verir sonra yazılımcı arkadaşımız yine tek başına kalmıştır.Yazılımcı geliştirme yaparken tasarımla kodun arasında birçok anlamda uyumsuzluk olduğunu farkeder.Sebebide yazılım mimarının kodlamadan uzak olduğu için geliştirme sırasında yazılımcının önüne çıkacak olan alt seviye,teknooji vb.. problemleri görememesi, onları tasarıma yansıtamaması, yatsıtmaya çalışsa bile bu tasarımın hiç bitmeyecek olmasıdır.

Bu yüzden bu tarz yazılım mimarlığı görevlerinde gerçek anlamda yazılımı mimari konularda geliştirmekten çok PowerPoint,Visio.. gibi araçlarda çizim yeteneklerini geliştirmeye yarıyor.Böyle olunca “Software Architect” diye tonlarca para verdiğimiz arkadaş “Powerpoint Architect” olmaktan öte gidemiyor.

Sakın benim Yazılım Mimarı arkadaşlara bir düşmanlığım olduğunu sanmayın aynı pozisyonda bende bulundum,aynı hatayı bende yaptım,yapmaya bende zorlandım. Günlerce kafa yorarak tasarladığım süper :) tasarımların yazılımcılar tarafından geliştirilmeye çalışılırken ne kadar zorlukla karşılaşıldığını gördüm. Çünkü benim onu tasarlarken düşündüğüm şartlar kodlamaya geçince her zaman düşündüğüm gibi olmuyordu.

Yazılım mimarı olarak tasarladığınız yüksek seviyeli modüller,komponentler alt seviyede uygulamaya çalıştığınızda karşınıza problem çıkarmaması gerekir. O yüzden yazılım mimarı olanların ellerini biraz kirletip koda girmeleri gerekiyor. Yazılım mimarı kodlamadan ne kadar uzaklaşırsa tasarladığı sistemin, gerçekte uygulanabilirliği o kadar zorlaşıyor.Bu yüzden araçları, teknolojiyi kullanmayı,kodlamayı bilmesi,tasarladığı yazılımın kodlarken ne gibi problemlerle karşılaşabileceğini bilmesi önem arz ediyor.

Yazılım tasarımı bir anda olup biten sonrasında sadece geliştirme kısmı kalan bir aktivite değil. Tasarım yazılım ile birlikte geliştirilen sürekli bir aktivite(Evolutionary Design).Yazılım tasarımınızında sürekli iyileştirilmesi ve geliştirilmesi gerekiyor yoksa belirli bir süre sonra yazılımınız güncel ihtiyaçları karşılayamayacak hale gelebiliyor.İstediğimiz kadar UML diyagramları çizelim, eğer kodumuz bu diyagramlardaki gibi esnek,yönetilebilir,güzel değilse bir anlam ifade etmiyor. Source Code Is Design yani
Geliştirdiğiniz yazılımın tasarımının göstergesi UML diyagramları değil kodlardır.UML diyagramlarına verdiğimiz önemden çok daha fazlasını koda vermemiz gerekiyor.Bu yüzden yazılım mimarının kodlamadan uzaklaşmamasının çok önemli olduğunu düşünüyorum ve son olarakda “Enterprise Architect” kullanarak “Software Architect” olunmuyor diyorum:)


« Previous PageNext Page »