Bu site emekli olmuştur. Arşiv amaçlı olarak BT AKADEMİ sponsorluğunda yayın hayatına devam etmektedir.




C#nedir?com
 
YAZAR HAKKINDA
Oğuz Yağmur
Oğuz Yağmur
http://www.oguzyagmur.com
İletişme geçmek için tıklayın.
26 Makalesi yayınlanmakta.
Yazar hakkında detaylı bilgi için tıklayın.
Yayınlanan diğer makaleleri için tıklayın.
İlgili etiketler: Design Patterns eğitim Entity interface mimari OOP OOP prensipleri Open Closed ORM Tasarım Kalıpları Yazılım Müh. Oğuz Yağmur
 
YAZI HAKKINDA
Türü : Makale
Serbest Köşede C#nedir?com üyelerinin hazırladıkları yazılar yayınlanır. Bu yazılar editör incelemesine girmeden yayınlanır.
Seviyesi : Orta
Kategori : Yazılım Müh.
Yayınlanma Tarihi : 3.9.2009
Okunma Sayısı : 33048
Yorum Sayısı : 7     yorum yaz
Site İçi AramaSİTE İÇİ ARAMA
Üye Girişini AçÜye GİRİŞİ
Üye girişi için tıklayın.
Kullanıcı Adı
Şifre
 
Beni her zaman hatırla
Bir hafta boyunca kullanıcı bilgilerinizi kullanıcı çıkışı yapana kadar hatırlar. (Paylaşılan bilgisayarlarda önerilmez.)
 
Şifremi / Kullanıcı Adımı unuttum.
 
.net TV RSS Serbest KÖŞE (?)
Serbest Köşede C#nedir?com üyelerinin hazırladıkları yazılar yayınlanır. Bu yazılar editör incelemesine girmeden yayınlanır.
emre TAŞ
Silindi
emre TAŞ
yazının devamı >
emre TAŞ
silindi
emre TAŞ
yazının devamı >
emre TAŞ
silindi
emre TAŞ
yazının devamı >
emre TAŞ
silindi
emre TAŞ
yazının devamı >
emre TAŞ
silindi
emre TAŞ
yazının devamı >
Makale Gönder Bende Yazmak İstiyorum
.net TV RSSBlogroll
Burak Selim Şenyurt
Kurumsal Yazılımcının Oyun Geliştirme ile İmtihanı 28.3.2024
Burak Selim Şenyurt
Matematik ve Oyun Programlama - Missile Command - Final 28.3.2024
Turhal Temizer
Conda install environment.yml Package 28.3.2024
Turhal Temizer
Mac OS/X Removing CUDA 28.3.2024
  Diğer Herşey
Sponsorlar
BT Akademi
Medya Portakal
Video Hosting Sponsoru
Csharpnedir.com bir Ineta üyesidir
Uzman Abi
Her Yönüyle C# - Sefer Algan
Kodlama ve Tasarım
 
Kapat
Sayfayı Yazdır Sık Kullanılanlara Ekle Arkadaşıma Gönder MySpace Del.Ico.Us Digg Facebook Google Mixx Reddit StumbleUpon

Görüyoruz ki birçok yazılımcı neyin ne olduğunu, yeni veya eski teknolojilerin nasıl kullanıldığını, büyük yazılım firmalarının ürettiği ürünlerin nasıl ve hangi şartlarda kullanılacağını, hangi problemlere çözüm getirdiğini kısa ya da orta vadeli bir zaman süreci içerisinde öğrenebilme ve kullanabilme becerisi gösterebiliyor ve bu konular ile ilgili Türkçe ya da yabancı kaynaklardan bilgilere kolay bir şekilde erişebiliyor. Edindiği bilgilerle projesinde çözümler geliştirebiliyor. Kimleri butonun altında bu çözümleri uyguluyor veya bir sınıf yazarak bir iki metoda işlemleri bölüştürüp “nesne yönelimli programlama yaparak”! çözüm geliştiriyor. Bir iki veya en kötü ihtimalle üç senelik bir süreç içerisinde yazılım geliştirmeye başlayan bir yazılımcı bu zaman dilimi içerisinde sadece “bu nedir, o metod ne işi yapar, şu sınıfın şu metodunu kullanırsan şunu yapar, yok şu sınıf şu işi kolay yapar, bak hazırı var , aaa X firması yeni bir Y çıkarmış hemen bakayım kim ne yazmış hemen öğreneyim, bak Z veritabanına bağlanmanın yenisi çıkmış! aman ne harika hadi zamanımı buna harcayayım (Yani şu satırları yazarken bile daral geldi, örnek vermeyi kestim)...” gibi yaklaşımlarla kişisel ve kariyer gelişimi için zaman ve emek harcıyor. Zaman içerisinde çöpe attığınız bilgilerin bir hesabını yaptınız mı ? Bence çok geçmeden yapın derim, aslında birçok bilgi için harcadığımız eforun bize kazanımlarını düşünmek gerekiyor. Şöyle küçük bir örnek verecek olursak; zamanında .NET kullanarak connection nesnesi ile veritabanına bağlantı sağlamak, bir command nesnesi ile komut çalıştırmak ve bir reader nesnesi ile gelen sonuçları okumak için ne kadar zaman harcadık, bu nesnelerin detayları ile ilgili ne kadar araştırma yaptık, neler okuduk ve nekadarını kullandık ? Peki ya şimdi ? ortalıkda pek bir connection , commad nesneleri kalmadı gibi sanki ne dersiniz, DataSetler, DataTable’lara ne oldu (Tamam tamam hala kullanan büyük bir çoğunluk var. Onları da çok yakın bir zamanda unutacağız )! Bu nesneler yerlerini ORM ve alt başlıklarına (entitiy vs vs) devretti gidiyor ve birçok kişi bu trende yerini almak için yine zaman ve para harcıyor. Peki bunları normal süreçler olarak düşünüp –ki bunların olmaması gerektiğini söylemiyorum kesinlikle ama yazılımı ve yazılımcılığı da sadece belirli bir altyapı ya da ürünün kitapsal yani ürünün yardım sayfalarından veya ürün sahibinin dökümanlarından rahatlıkla bulunabilecek bilgilerin ezberlenip kullanılması olduğu düşünülmesin ya da yayınlanan içeriklerle düşündürülmesin yanlış olduğunu belirtmek istiyorum. - asıl sorunun ne olduğu üzerinde konuşalım.

Bir uygulama geliştirilecek veya uygulamanın geliştirilme aşamalarında birinde bir özelliğin uygulamaya kazındırılması gerekmekte. Bu aşamada acaba rolümüz ne oluyor ? Ya da durum karşısında yaklaşımlarımız neler oluyor ? Tonlarca bilgimizle hemen çözümleyebiliyor muyuz, yoksa hemen araştırma yapıp aynı eşekden düşen birisi mi arıyoruz, acaba hazır birşeyler sunmuş mu bize umudu ile. Genelde karşılaştığım çözümlere baktığımda da anı kurtarmak adına yazılan kodları ve uygulamanın gelecekte genişleyebileceğini ya da değişebileceğini, en iyi ihtimalle bu kodun ilerde bakıma ihtiyaç duyacağını, ekipeki başka birisinin kodu güncelleyebileceğini, ya da ekipdeki diğer kişilerin bu kodlar hakkında bilgi sahibi olmadan üstüne kendilerine özel birşeyler çıkabileceği ihtimali düşünülmeden yazılan kodların zaman içerisinde uygulamayı bir kod çöplüğüne döndürdüğünü ekipçe görebiliyoruz. Kodda hata çıkması ve bu kodların içerisinde hatanın bulunması senaryosunu geçtim bile. Burda eksik olan ne olabilir, ben senelerce neyin nasıl kullanılacağını online ve offline kaynaklardan çok iyi bir şekilde öğrenmiştim! Hangi metodun çağrılacağını, hangi sınıfın benim işime yarayacağını, hangi parametrelerin verileri daha hızlı okumamı sağladığını ? Eksik olan ne ki uygulamam zaman içerisinde içinden çıkılmaz, okunamaz ve yönetilemez bir hale geliyor ?

Mesleki anlamda belirli bir zaman sonra proje içerisinde bizlerden hangi sınıfın ya da metodun ne işe yaradığını bilmenin yanında – bir defa daha tekrarlamak istiyorum ki bunlar olmasın, bunlarla zaman kaybetmeyelim, bunlar önemsiz demiyorum, yazılım ile ilgili kod yazmak dışında başka bilgilere de ihtiyacımız olduğunu vurgulamak istiyorum – daha önceden görev alınan projelerden edinilen iyi ya da kötü deneyimlerin benzer durumlarda da kullanılarak edinilen öngörülerin yardımı ile çözümün tasarlanması veya tasarımı aşamasında müdahil olmamız beklenecektir. Oysaki ne online içeriklerde ne de kitap vs gibi içeriklerde bu konuların çok fazla incelenmediğine ya da kısmen alınsa dahi geliştiricilerin bu konuların çok ama çok büyük bir kısmı tarafından dikkate alınmadığına şahit oluyoruz. Bunun en büyük nedenlerinin başında da çalışma arkadaşlarımızın, iş verenlerin bu konulara olan uzaklığı ya da öğrenci olanların üniversitede yeteri kadar bu konular ile ilgili bilgi verilmemesi ve de yönlendirilememesinden kaynaklanmaktadır. Proje arkadaşımız nasıl yaptığımız ile , proje yöneticimiz ne kadar kısa sürede yaptığımız ile, iş veren ne kadara fazla mesai ya da ücret karşılığında hangi çalışma koşullarında yaptığımız ile, müşter de çalışıp çalışmadığı ile ilgilendiğinden, öğrenci olanlarımız ise yüksek not alıp bir an önce okuldan kurtulmak, eğitmenlerimiz ise onlarca yıldır kullanılan ama bir öğrencinin dahi memnun olmadığı içerikleri yetiştirmek ve anlatmakla! meşgul olduğundan yazılımda tasarım ve mimari konular her zaman en son düşünülen ya da hiç düşünülmeyen konular olmuşlardır. Oysaki zaman içerisinde kod yazma becerisinin yanında biraz önceki soruduğum soruları da dikkate alarak gerçekte nasıl kod yazılması gerektiğini öğrenilmeli ve araştırılmalıdır. Belirli bir süre sonra da yine uygulamaların her zaman yaşadığını bu süreçte değişime ve genişlemeye uğrayabileceğini de düşünerek, daha önceki proje deneyimlerimizden kazandığımız öngörülerimizle – ya da deneyimli kişilerin yazılarından öğrendiklerimizle -riskleri öngörerek yapacağımız kod tasarımlarını ve soruna yönelik çözümleri baştan planlayarak işe başlanmalıdır.

Tabi ki bu tarz bir “yazılım yapmak” belirli bir zamanın , birikimin ve tecrubenin sonucu olarak ancak hayat bulabilir. Yalnız önemli olan nokta bir teknolojinin, kütüphanenin, ürünün teknik detaylarını öğrenme sürecimizin yanında uygulama tasarımı ve kod tasarımına da ciddi biçimde önem verilmesidir.

Küçük ve basit bir örnek ile yazıma devam etmek istiyorum. Hemen hemen her veritabanı uygulaması geliştiren yazılımcının kısa bir süre içerisinde tanıştığı üç katmanlı mimari kullanarak uygulama geliştirdiğimizi düşünelim. ( Tabi yazımda bahsettiğim gibi eğer biraz daha kurumsal bir proje içerisinde yer aldığımız durumda bu üç katmanın sayısının oldukça artacağına şahit olacağız). Veri erişim katmanını kullanan bir nesnemizin olduğunu düşünüyorum.

class VeriyeErismekIsteyenNesne
{
    SqldenVeriGetirenNesne nesnem = new SqlDenVeriGetirenNesne ();
    Metodum()
    {
        nesnem.VerileriGetir();

    }
}


Şimdi görünürde (çünkü ben üç katmanlı mimariyi biliyorum, ben veritabanına nasıl bağlantı kurulacağını , en hızlı şekilde nasıl okunacağını, hata yönetimini herşeyi sorunsuz bir şekilde okudum öğrendim ve uyuglayabiliyorum) sorunsuz bir kod gibi görünmesine karşın – yönetici, iş veren ve müşteri memnundur - daha öncede belirttiğim gibi ileriki zamanlarda ihtiyaçlarımız değişebilir, ya da uygulamanın genişlemesi sözkonusu olabilir. Örneğin verilerimiz Ms SQL veritabanından gelirken analiz sürecinde var olmayan ya da değişimin düşünülememesinden dolayı dikkate alınmayan bir durumun gerçekleşmesi sonucu artık verilerimiz Oracle veritabanından gelmesi istenedi veya bir webservisinden gelmesi istendi. Şimdi kimse kalkıp da “siz bize bunu baştan söylemediniz ki! Biz de ceza olsun size diyerek bu güncellemeleri yapmıyoruz!” diyemez. İşveren ve müşteri bir an önce gerekli güncellemelerin uygulamaya yansıtılmasını bekleyecektir. Şöyle yazdığımız koda bakarsak sanırım oldukça büyük değişikliklerin yapılması gerektiğini görebiliyoruz. Veri erişim katmanın değişmesi sonucunda tüm SqldenVeriGetirenNesne türünden nesnelerin kullanıldığı yerlerin değiştirilmesi gerekecektir – Bu nesnelerin projenin birçok yerinde kullanıldığını düşünürsek oldukça büyük bir sorunla karşı karşıya olduğumuzu daha net görebiliriz. - Eğer çok fazla sorun olmadığını hemen iki üç yazılımcının kodları bul - değiştir ile kısa bir zaman içerisinde revize edeceğini düşünüyorsanız ve çözümünüz bu şekilde manuel bir yöntem ise ve bunda ısrarcı iseniz bu yazının ilerki kısımları sizin için anlamsız gelecektir.Peki nasıl bir çözüm getirelim ? Daha doğrusu nasıl bir yöntem bulalım ki ilerde benzer durumlarda aynı çözüm yöntemini uygulayarak aynı sorunları aynı şekilde çözelim.
 

Alınan eğitimler, okunan kitaplar ve online içerikler sonucunda temel anlamda sorunsuz bir şekilde nesne yönelimli programlamanın temellerini biliyoruz ve hemen sorunumuza karşın çözümümüzü üretiyoruz : Esnek bağ oluşturalım nesnelerimiz arasında( loose coupling )!!! Gidelim soyut bir sınıfdan ya da arayüzden türetelim veriyi getiren nesnelerimizi (SqldenVeriGetirenNesne), belirli metodlara zorlayalım böylelikle VeriyeErismekIsteyenNesne bu hazırlayacağımız soyut sınıfı ya da arayüzü kullanacağı için veri getiren nesnemiz değişse dahi VeriyeErismekIsteyenNesne içerisindeki kodlarımız değişmeyecektir .Artık hangi oop dili kullanıyorsak dilin verdiği imkanlar ile bu düşüncemizi implimente etmeye başlıyoruz.(Erişim belirleyiciler ile ilgili düşüncelerimizi konu dışına çıkmamak adına es geçiyoruz )

interface IKaynakdanVeriGetirenNesne {
    VerileriGetir();
}

class SqldenVeriGetirenNesne : IKaynakdanVeriGetirenNesne {
    VerileriGetir() { … } 
}

class WebServisindenVeriGetirenNesne : IKaynakdanVeriGetirenNesne {
    VerileriGetir() { … }
}

 

Şimdi de bu kütüphanemizi kullanarak veriler üzerinde işlem yapan nesnemizi modifiye edelim.

class VeriyeErismekIsteyenNesne {
    IKaynakdanVeriGetirenNesne nesnem = ?????// ne yazılacak bu kodun devamına ?
    Metodum() {
        nesnem.VerileriGetir(); 
    }
}

 

 

VeriyeErismekIsteyenNesne'yi tasarlarken yukardaki gibi bir sorun ile karşılaştık.Aslında düşüncemiz çok iyi idi ama implimentasyonunda sorun yaşadık. Peki nasıl çözeceğiz bunu ? Acaba kullanıcıdan mı alsak ? Yani veriye erişmek isteyen nesneyi kullanmak isteyen kişi “ben verilerimi Sql’den alacağım, webservisinden alacağım” mı dedirtsek? Bu durumda acaba bizim kodlarımızı kullanan takım üyesi ile ilk yüzyüze geldiğimizdeki yüz halini eminim ki görmek istemeyiz. Daha da kötüsü takım üyesi aslında verilerin webservisinden gelmesi gerekirken yanlışlıkla veritabanından gelecek şekilde kod yazabilmesini sağlayarak hata oluşturacak bir zemin hazırlamış oluyoruz. Aslında bu durumun çözümü için “veriye erişmek için kullanacağımız nesnelerin VeriyeErismekIsteyenNesne dışında yaratılması gerekiyor” sonucuna varıyoruz. Bir nesne duruma göre farklı nesneleri kullanmak istiyor ama bunun kodlama zamanında değil de çalışma zamanında belirlenmesi gerekiyor. Aslında bu bir problem ve daha önceden kendisini nesne yönelimli programlama prensipleri ve tasarım kalıpları (Design Patterns) konusunda geliştiren bir kimse bu problemin çözümünü hiç düşünmeden factory pattern kullanarak uygulamaya aktaracaktır. Bu konularda kendisini geliştirmeyen bir yazılımcı ise bu problemin çözümü için az ya da çok bir zaman harcayacak belki iyi belki de kötü bir yöntem ile çözüm geliştirecektir.

IKaynakdanVeriGetirenNesne VerigetirenNesneyiOlustur(string tip) {
    if (tip == “sql”) {
        Return new SqldenVeriGetirenNesne (); 
    } else if (....)
          Return new ....
}

Gibi bir metod yazarak nesnenin oluşmasını sağlayacak kodu sınıfdan dışarı alarak nesneler arasındaki bağımlılığı azaltmaya çalıştık. Aslıda yukardaki örneği göz önüne alırsak yeni bir veri kaynağı geldiğinde sadece tek yapmamız gereken VerigetirenNesneyiOlustur metodunu güncellemek. Burda yine akla gelebilecek soru şu : Uygulamam tek bir veri kaynağından çalışıyor olmasına rağmen veri kaynağına erişmek isteyen nesneler her defasında bu metoda hangi veri kaynağından verinin alınacağı bilgisini de vermek zorunda olması doğru bir tasarım mıdır ?. Uygulamamız içerisinde yeni bir veri erişim kaynağına ihtiyaç duyulduğunda ya da uygulama sistemde var olan veri kaynağına erişim nesnelerinden istediğini istediği anda kullanmak istediğinde kodlar üzerinden hiç değişiklik yapmadan bu özellikleri sistemimize kazandırabilmemiz gerekmektedir doğru tasarımı gerçekleştirmek için. Basit bir çözüm için su şekilde ilerleyebiliriz.

Çalışama zamanında uygulamanın ayar dosyasından hangi nesneyi çalışma zamanında oluşturacağımız bilgisini almak ve VerigetirenNesneyiOlustur metodu Reflection tekniğini kullanarak (.net ve java platformlarında bu işlemleri sağlayacak API’ler mevcuttur) nesneyi yaratabilir. Böylelikle bu kodlarımızı kullanan ekibin diğer üyeleri veri kaynağından bağımsız ve veri kaynağının ne olduğunu düşünmeden geliştirmeye devam edebilecekler aynı zamanda da sisteme yeni bir veriye erişen nesne eklenmek ve bunun sistem tarafından kullanılması istendiğinde uygulamanın ayar dosyasının değiştirilmesi olacaktır.
 

IKaynakdanVeriGetirenNesne VerigetirenNesneyiOlustur()
{
    IKaynakdanVeriGetirenNesne nesneş string typename = ConfigurationManager.AppSettings["veriyeerisimnesnesi"];
    try
    {
            nesne = (IKaynakdanVeriGetirenNesne)Activator.CreateInstance(Type.GetType(typename));
    }
    catch
    { 
        throw new Exception("nesne olusturulamadı");
    }
}

 

Uygulamanın ayar dosyası da aşağıdaki gibi olabilir.

<configuration>
    <appsettings>
        <add value="Xuygulaması. WebServisindenVeriGetirenNesne  " key=" veriyeerisimnesnesi "></add> 
    <appsettings>
<configuration>

Görüldüğü gibi ayar dosyasında verinin Webservisinden geleceği belirtilmiş. VerigetirenNesneyiOlustur() metodu da Reflection ile çalışma zamanında string bilgisinden Type bilgisi ve Type bilgisinden de çalışma zamanında veriye erişim nesnesini yaratarak taban sınıf türünden geri dönüş değeri olarak VeriyeErismekIsteyenNesne sınıfına nesneyi vermiştir. Artık bu aşamadan sonra verinin nerden geldiğine bağlı olmaksızın çalışamaya devam edilecektir. VeriyeErismekIsteyenNesne aşağıdaki gibi olacaktır.

class VeriyeErismekIsteyenNesne {
    IKaynakdanVeriGetirenNesne nesnem = VeriyeErisimNesnesiOlusturucu. VerigetirenNesneyiOlustur();
    Metodum() { 
        nesnem.VerileriGetir();
    }
}

 

Görüldüğü üzere sisteme Oracle’dan veri alınmasını sağlayacak yeni bir nesne tasarlanmak istendiğinde aşağıdaki gibi bir genişleme sağlanacak.

class OracledanVeriGetirenNesne : IKaynakdanVeriGetirenNesne {
    VerileriGetir() { … }
}

 

Hazırlanan bu modül sisteme aktarılacak ve sonrasında yapılması gereken tek şey uyuglamanın ayar dosyasının aşağıdaki gibi güncellemesini yapmak olacaktır.

<configuration>
    <appsettings>
        <add value="Xuygulaması. OracledanVeriGetirenNesne" key=" veriyeerisimnesnesi "></add>
    </appsettings>
</configuration>

Bu basit örnekte de görüldüğü üzere uygulamayı kodlamakdan ziyade uygulamanın tasarlanması ve kodlanma safhasında nesneler arasındaki bağların oluşturulmasına önemli derecede dikkat edilmesi gerekliliğidir. Bunlara dikkat edilmemesi durumunda uygulamadaki genişlemeler ve değişikliklerin aşırı derecede zaman ve para kaybına neden olacağı hatta çok daha vahim durumlarda uygulamaların büyük bir kısmının yeniden yazılmasına neden olacağıdır. Buna benzer uygulamanın geliştirilme aşamasında birçok problemle karşılalışabilir. Bu sorunların daha önceden başkaları tarafında tespit edilmesi ve en iyi şekilde çözümlerin üretilmesi sonucu gruplanarak bir araya getirilmiş ve ismine de Tasarım Kalıpları (Design Patterns) denilmiştir. Proje geliştirilirken OOP Prensiplerine ve Tasarım Kalıplarına bağlı kalarak geliştirilme ve tasarım yapıldığında oldukça sağlam,esnek ve yönetilebilir ürünler geliştirilebilmektedir.Uygulama geliştiricilerin de belirli bir sure sonra kütüphane özellikleri ve sınıf tanımları metod parametrelerinin neler yapabildiği, X yerine Y çıkmış hadi ona bakalım, önemli olan kullandığım teknoloji ve kod kütüphanesidir kodu nereye yazarsam yazayım çalışır – ki buton altı ne kadar ideal bir yer değil mi ? – mantığı en kısa sürede bırakıp kişisel gelişimi ve kariyer hedefi için mühendislik konularına da ilgi duyup araştırması gerekmektedir. Yarın kullandığınız platformu çalıştığınız firma bırakabilir, yazılım geliştirmek için kullandığınız ürünün geliştirilmesi durdurulabilir ya da alternatifi çıkabilir(ki bunu son 2 3 yıldır Microsoft tarafında oldukça sık görmekteyiz). Ama sorunlar aynıdır, çözümleri aynıdır, uygulamanın tasarımı nerde olursak olalım ne kullanırsak kullanalım iyi tasarlanmalıdır ve bunun kullanılan platform veya ürünlerle ilgilsi olmadığı için de her projede mutlaka bu bilgilere sahip kişilere ihtiyaç olacaktır.

 

 

Makale:
Kodlama ve Tasarım Yazılım Mühendisliği Oğuz Yağmur
  • Yazılan Yorumlar
  • Yorum Yaz
OCA
27
2010
Güzel bir makale olmuş Teşekkürler
EKİ
10
2009
Bu güzel yazı için bizzat teşekkür ederim Oğuz Hocam. Bu tip olasılıkları bilmek, bize yeni ufuklar açıp yeni çalışma mantıkları kazandıracaktır.
EYL
22
2009
Güzel anlatımdı teşekkürler
EYL
13
2009
Her zaman ki gibi süpersiniz hocam derslerde anlattıklarınızı halen daha devam etmesi ve desing patterns in halen daha geliştirilerek kullanılması bu konunun ne kadar önemli olduğunun da bi göstergesi hele de şuan ki üzerinde çalıştığım proje gerçekten çok ilginç :) (bu sözü hatırlarsınız.ToString());
EYL
10
2009
teşekkürler, mühendisliğin gerektirdiği gibi zamana ve olası problemlere dayanabilecek yazılım geliştirmek için ideal kodlama anlayışı sunduğunuz için
EYL
4
2009
Teşekkür ederiz Hocam ; Farklı bir bakış açısı ile bakmamız gerektiğini hatırlattığınız için
EYL
4
2009
Yazınızda değindiniz durumlar bir çoğunu yaşayan bir kişi olarak teşekkür ederim..
Sayfalar : 1 
Yorum yazabilmek için üye girişi yapmalısınız. Üye girişi için tıklayın.
Üye değilseniz Üyel Ol linkine tıklayarak üyeliğinizi hemen başlatabilirisniz.
 
  • Bu Konuda Son 10
  • Eklenen Son 10
  • Bu Konuda Geçmiş 10
Bu Konuda Yazılmış Yazılmış 10 Makale Yükleniyor
Son Eklenen 10 Makale Yükleniyor
Bu Konuda Yazılmış Geçmiş Makaleler Yükleniyor