Arda Çetinkaya Yazılım ve arada kendim ile ilgili karaladıklarım…

Herkesin oldukça iyi bildiğini düşündüğüm bir kavramın, çok fazla kullanılmayan ama yeri geldiğinde çok hayat kurtaran bir C# özelliğinden bahsedicem bu sefer.

Bildiğiniz üzere, C#’da da bir çok yazılım dilinde olan “type visibility” kavramları mevcut. Son kullanıcıya yönelik olan adıyla “Access Modifiers” demem daha doğru olur sanırım. Yarattığımız nesnelerin ve değişkenlerin erişebilirlik seviyelerini ve erişim durumlarını belirten kavramlar. public, private, protected…falan filan…

Falan filan dedim, asıl bahsedeceğimi söylemedim. Eksik olan Internal’ın kullanımı ile ilgili bir kaç ipucu vereceğim. Yazılım geliştirirken, API veya SDK tarzı şeyler geliştirirken, internal kavramının özelliklerini biliyor olmak tasarımda ve kod geliştirmede oldukça işinize yarayacaktır.

Bir çoğunuzun da bildiği üzere, internal olarak tanımladığınız bir sınıf ya da metod, sadece o assembly içerisinde erişilebilmektedir. Dışarıya verdiğiniz kütüphane tarzı yapılarda ya da farklı takımların aynı projede çalışıp ortak assembly’lerde ulaşabilecekleri elemanları kısıtlamak için oldukça kullanılabilecek bir yaklaşım.

Şimdi şöyle bir senaryomuz olsun; X projesi için geliştirdiğimiz FriendAssembly_1.dll‘inin bir sınıfının, bir metodunun sadece FriendAssembly_1.dll‘nin içerisinde kullanılmasını sağlamak adına, metodu internal tanımlamış olalım. Daha sonra aynı X projesinin FriendAssembly_2.dll‘inde çalışan ekibin FriendAssembly_1.dll‘inde ki o metoda erişmesi gereksin. Bu durumda eğer o metodu public yaparsak, herhangi bir başka projede bu FriendAssembly_1.dll‘ini kullanan kişi de o metoda ulaşabilecektir ki, bu da istediğimiz bir şey değil. Peki FriendAssembly_1.dll‘inde ki bir metodun sadece FriendAssembly_2.dll‘inden ulaşılmasını nasıl sağlarız?

Bu durumu engellemek adına .NET Framework’de CLR’da ki “Friend Assembly” kavramını biliyor olmamız lazım.

Bildiğiniz üzere, Visual Studio’da bir proje geliştirirken, proje şablonunda AssemblyInfo.cs diye bir dosya vardır. Bu dosya adındanda anlaşıldığı üzere, geliştirdiğimiz assembly ile ilgili bilgileri içerir. Burada yapacağımız küçük bir ekleme ile yukarıdaki bahsetmiş olduğum senaryo ile ilgili çözüm sağlayabiliriz.

Öncelikle FriendAssembly_1.dll‘i olarak adlandırdığımız projemizin içeriğine bakalım.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace FriendAssembly_1
{
    public class FriendAssembly
    {

        public FriendAssembly()
        {

        }

        //Sadece bu sınıfın olduğu assembly'de kullanılabilir.
        internal void InternalTest()
        {

        }

        public void PublicTest()
        {

        }

        //Sadece bu sınıfın olduğu assembly'de
        //veya bu sınıftan türeyen ama farklı bir assembly'de
        //olan sınıflarda kullanılabilir.
        protected internal void ProtectedInternalTest()
        {

        }
    }
}

Çok standart, herkesin bildiği, bilebileceği bir yapı. Bu FriendAssembly_1.dll‘imizi, başka bir projede(FriendAssembly_2.dll) referans verip, kullanmaya çalıştığımızda, geliştirme ortamımızda InternalTest() metodunu göremediğimizi(?) fark ediyor olacağız doğal olarak.

Öncelikle FriendAssembly_2.dll‘nindeki örnek yapımıza bakalım.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace FriendAssembly_2
{
    public class YourFriend
    {

        //FriendAssembly_1.dll'nindeki FriendAssembly
        //sınıfını kullanıyoruz.
        public YourFriend()
        {
            FriendAssembly_1.FriendAssembly fa = new FriendAssembly_1.FriendAssembly();

        }
    }

    //FriendAssembly_1.dll'ninden gelen,
    //FriendAssembly'den türeyen bir sınıf yaratıyoruz.
    public class MyFriend : FriendAssembly_1.FriendAssembly
    {
        public MyFriend()
        {
            FriendAssembly_1.FriendAssembly fa = new FriendAssembly_1.FriendAssembly();

        }
    }

}

Burada YourFriend sınıfımız FriendAssembly_1.dll‘inden gelen FriendAssembly’i kullanmakta. Ancak fa değişkeninden InternalTest() metoduna ulaşamaz.

internal

Devam…

,

lego.NET Framework ile geliştirdiğiniz uygulamaları genişletebilmek adına, 3.5 yıl önce Microsoft .NET Framework ile geliştirilmiş bir framework sunmuştu hatırlarsanız. Managed Extensibility Framework(MEF) ile uygulamalarımızı artık daha kolay bir şekilde genişletebilir hale gelmiştik. O zamandan bu zamana kadar MEF’in DI(Dependency Injection) ve IoC (Inverse of Control) açısından farkları, eksiklikleri çok tartışılsa da, MEF’in geliştirdiğiniz uygulamaları genişletebilmek adına ciddi anlamda faydalı bir çözüm olduğu sanırım ortak buluşulan nokta. Bu noktada MEF ile çeşitli DI ve IoC yaklaşımlarını uygulayabildiğinizi ama MEF’in bir IoC Container’ı olmadığının altını çizerek bu konuya çok girmeden, asıl konumuza geçiyorum…

.NET Framework 4.5 ile MEF tarafında gelen oldukça faydalı değişikliklerden bahsediyor olacağım. Biraz fazla kod örneği şeklinde olacağı için daha önce MEF ile çalışmamış kişiler için karmaşık olabilir. O yüzden daha önce MEF ile ilgili saçmaladığım şeyleri okumanızı tavsiye ederim.

  1. MEF ile esneklik kazanıyoruz…
  2. MEF’de “Part”lara kendi “metadata” bilgilerimizi nasıl ekleriz acaba?
  3. MEF’i basit bir WPF uygulaması ile daha iyi anlıyoruz…
  4. Managed Extensibility Framework(MEF)’de ki kataloglar…
  5. Asp.Net MVC Framework’de MEF ile Controller eklentileri…

MEF’in genişletilebilirliğini tanımlayan ‘Part’ kavramının kullanımı ile gelen yenilik, en faydalı ve kolaylık sağlayan özellik diyebilirim. Attribute bazlı tanımlar ile yarattığımız Part’ları daha sonra MEF tarafında yöneterek uygulamalarımızın genişletilebilirliğini gerçekleştiriyorduk. .NET Framework 4.5 ile Attribute tanımları yapmadan, Part’larımızı tanımlayabiliyoruz artık.

Biraz daha anlaşılabilir olması adına; belli arayüzlerimizi, uygulamalarımıza RegistrationBuilder ile register edebiliyoruz. Bu yeniliğin en güzel tarafı, mevcut geliştirmiş olduğunuz bileşenleri, bileşenlerde ekstra bir değişiklik yapmadan, MEF ile yeni geliştirdiğiniz uygulamalara dahil edebiliyor olmanız.

.NET Framework 4.5 ile MEF tarafında gelen bir başka özellikde Generic arayüz ve sınıfları artık ‘Export’ edebiliyor olmamız. Yani Generic bir sınıfımız var ise, bunu başka uygulamalarda kullanabilmek adına Part olarak yorumlayabiliyoruz.

Bu iki özelliği kod örnekleri ile biraz daha netleştirmeye çalışacağım. Genişletilebilirliğe de örnek olması adına bir tane müzik grubunu soyutlaştıran konsol uygulaması yapıyor olacağım. Müzisyen, enstürman, grup elemanı ve ünlü bir müzisyen grubumuzun özellikleri olacak. Grubumuza, grubumuzun yapısını bozmadan, her hangi bir enstürmanı çalan grup elemanını katabiliyor olacağız en sonunda. Öncelikle bu kavramları oluşturuyor olacağız. Bu kavramları oluştururken MEF ile ilgili ekstra hiç bir şey yapmıyor olacağımızın altını çizmek isterim.

Başlayalım…

    //Generic bir Interface ile müzisyen tanımızın için bir arayüz oluşturuyoruz.
    //Play() metodu ile müzisyenlerin, bir şeyler çalacağını belirtiyoruz.
    public interface IMusicPlayer<T> where T : class
    {
        void Play();
    }

    //Müzisyenlerin çalacağı enstürmanların base sınıfı olarak
    //MusicalInsturment'ı kullanıyor olacağız.
    //PlayTheInstrument() metodu ile ilgili enstürmanın nasıl çalınacağını tanımlıyoruz.
    public abstract class MusicalInstrument
    {
        public abstract void PlayTheInstrument();
    }

    //Yukarıda oluşturduğumuz IMusicPlayer arayüzü ve MusicalInstrument sınıfından
    //generic bir BandMember<T> sınıfı oluşturuyoruz. Bu sınıf ile tanımlayacağımız
    //enstürmanları çalabilecek grup elemanlarını oluşturuyor olacağız.
    //Genişletebilirliği sağlayacak temel yapı diyebiliriz. Bu sayede herhangi bir
    //MusicalInsturment'e sahip olan BandMember'ımız grubumuz
    //dahilinde müzik yapabilecek.
    public class BandMember<T> : IMusicPlayer<T> where T : MusicalInstrument
    {
        //Generic yapıdan gelen T tipimiz MusicalInstrument tipinde olup,
        //BandMember'ın çalacağı enstürmanı belirtiyor.
        protected T _ensturment;

        public BandMember(T e)
        {
            _ensturment = e;
        }

        //IMusicPlayer arayüzünden gelen Play() metodu ile müzisyenimiz
        //bir şeyler çalmasını tetikliyoruz. (:
        public void Play()
        {
            Console.WriteLine(this.ToString() + " plays " + _ensturment.ToString());
            _ensturment.PlayTheInstrument();
        }
    }

    //Son olarak bir tane de enstürman tanımımızı yapalım.
    //Gitar olsun ilk enstürmanımız.
    public class Guitar : MusicalInstrument
    {
        private string _name = "";
        public Guitar(string name = "Custom Guitar")
        {
            _name = name;
        }

        //Gitara özel bir Solo() metodumuz olsun
        public void Solo()
        {
            Console.WriteLine("Solo with " + _name + " is just amazing");
        }

        public override string ToString()
        {
            return _name;
        }

        //MusicalInstrument'dan türeyen gitar sınıfımız, base sınıfdan gelen
        //PlayTheInstrument() metodunu kendi içinde tanımlıyor. Böylece gitara
        //özel yapıları oluşturabiliriz.
        public override void PlayTheInstrument()
        {
            Console.WriteLine("Guitar is played");
        }
    }

Buraya kadar MEF ile ilgili ekstra hiç bir şey yapmadık. Standart C# yapıları ile grubumuzun nasıl bir oluşum dahilinde oluşabileceğinin tanımlamalarını yaptık.Dikkat ederseniz MEF’in daha önce ki Export kavramına ilişkin herhangi bir geliştirme yapmadım. Şimdi MEF ile bu tanımlamaların nasıl çalışacağını oluşturalım. Bunun için çok komplike bir yapı oluşturmadan, bir konsol uygulaması üstünden gidiyor olacağım.

Devam…

, ,

‘BUG Fix’ kavramı her yazılımcının zaman içerisinde dahil olduğu, bazen lanet okuyup, sövdüğü, bazen içinden hiç çıkamadığı, bazen de problemleri çözüp,iyileştirmenin mutluluğunu yaşadığı bir süreç…Di mi? (:

Ne kadar BUG’sız uygulamalar geliştirmeye çalışsakta, günümüz şartları ve kurtulamadığımız alışkanlıklar yüzünden bu çok mümkün olmuyor. BUG olayını minimuma indirgemek adına TDD tarzı yaklaşımlar ya da unit test’lerin dikkatli yapılması gibi yazılım süreçlerinin farklı dalları için uygulama pratiği eksikliğini eminim herkes yaşıyordur.

Günümüzün getirdiği çeşitli yazılım araçları ya da TDD’ın popüler olması, geliştirme seviyesinde BUG’ları azaltmak için güzel şeyler. Ancak asıl sorun bu tarz nimetlerden bihaber yazılmış, PROD ortamlarında takır takır(?) çalışan uygulamalarda oluşan BUG’lar sanırım.

BUGBelli süredir kullanılan ve belli bir amaça, çat pat hizmet etmiş yazılımlardaki BUG’lar, zaman içerisinde çok daha büyük sorunlara yol açabiliyor. Ne yazık ki bu bir gerçek… En nefret edilen, en korkulan senaryo da sanırım bu…Hele bir de başkasının ya da başkalarının geliştirdiği bir yazılım ise, farklı anlayış ve bakış açıları hakim ise uzak durmayı eminim bir çok kişi tercih edecektir. Bu tercihin doğruluğu ya da yanlışlığını sorgulamıyorum pek, ama BUG’lardan kurtulmak ve yeni BUG’lara yol açmamak adına bu tarz tercihlerde, iyileştirme yapmak, yanlışları görmek, tecrübe kazanmak adına pozitif yaklaşım çok önemli.

Neyse…Uzun bir giriş oldu ama bu yazıda, BUG çözmek ile ilgili bir şeyler yine saçmalıyor olacağım…

Öncelikle hata yapmak çok kötü bir şey değil…Öğrenmek ve tecrübe kazanmak için çok güzel bir yol. Bazı konularda tecrübeliyseniz, karşılaştığınız BUG’lar sizi kızdırabilir… Tecrübesiz biri yazdığı kodun nelere sebep olacağını kestiremeyebilir, tıpkı sizin ilk kod yazmaya başladığınız zamanki gibi. Dolayısıyla BUG çözerken, biraz empati ile yaklaşmak, yapılan hatalardan ders alıp, kulak arkasına atmak öncelikli bir anlayış olmalıdır. Egonuzu bir kenara koyup, soruna odaklanmak daha faydalı olacaktır…Bu ilk kural…Neyse bu kadar sosyal mühendislik yeter 😛

Bir yazılımda oluşan BUG’ları çeşitli kategorilere ayırabiliriz. Ama hepsi özünde iki farklı kategoride ele alınabilir. Sistem ve mantık…

Sistem BUG’ları, yazılımın çalışmasına engel olan, sadece yazılımdan da kaynaklanmayabilecek, kontrolsüz oluşan BUG’lardır. Mavi ekranlara, kilitlenmelere, anlamsız kapanmalara yol açan BUG’ları Sistem BUG’ları şeklinde kategorilendirebiliriz.

Mantıksal BUG‘ları ise sistemin çalışmasında bir sorun teşkil etmeyen ama beklenen ihtiyaçların karşılanamamasına sebep olan BUG’lar şeklinde tanımlayabiliriz. Yazılımın beklenmedik bir davranışı ya da yanlış üretilen bir sonuç bu BUG’ların çıktıları diyebiliriz.

Nasıl çözeriz?

Bu iki kategorideki BUG’ları çözmek farklı yaklaşımları gerektiriyor olsa da, çözmek adına iki kategoride de yapılacak ilk şey BUG’ların oluşma durumlarının tespiti olacaktır. Bunun için ilk şey, BUG’ı tekrar yaratabiliyor seviyesine gelmek olmalıdır. Tekrar yaratıp göremediğiniz bir BUG’ı çözmeye çalışmak çok anlamlı olmayacaktır zaten…

Devam…

Yazının başlığını dikkat çeksin diye biraz popüler yaklaşım ile yazdım, yoksa kesinlikle saçmalık falan değil…Aman diyim…Uzun zamandır irdelediğim, zaman zaman üzerinde çalıştığım, tam olarak farkında olunmadığını düşündüğüm bir konu hakkında yine sesli düşünerek bir şeyler karalıyor olacağım…Evet başlıyoruz…Kurumsal Mimari

Belli bir amaç doğrtulsunda ortaya çıkan her oluşumun, bir vizyonu ve misyonu vardır. Oluşumun büyüklüğüne göre, bu vizyonun ve misyonun, çeşitli yan ve farklı alanlar ile gerçekleştirilebilmesi sağlanır. Oluşum ne kadar büyükse ya da büyür ise bu alanların sorumlulukları ve işleyişi önem kazanıyor ve kurumsal mimarı denen kavram ortaya çıkıyor.

Kurumsal mimari dediğimiz kavram, bir oluşumum en küçük birimden, en büyük birimine kadar, stratejilerinin oluşturulduğu,yönetildiği; oluşum içerisindeki verinin yapısı, saklanma biçiminin tanımlandığı; iş süreçlerinin geliştirildiği ve işletildiği mimari alt yapıdır diyebiliriz. Bütün bu kavramlar yönetim, reklam, insan kaynakları, teknoloji ve bilişim sistemleri alt yapıları gibi alt maddelerde çeşitlilik gösterebilir. Kurumsal mimarinin bu noktada en önemli özelliği tüm bu alt yapılar ve sistemler arasında düzenli bir ilişki ve iletişimi sağlayıp, yönetebilir olmasıdır.

EnterpriseBüyük oluşumlarda(genelde kurumsal şirketler ve büyük ölçekli firmalar mesela) kurumsal mimari kavramı, büyüklüğü yönetebilmek adına çok daha fazla önem taşır. Diğer oluşumlar da, çok farkında olunmasa da, mutlaka oluşturulmaya çalışılan bir mimari vardır. Sadece biraz daha özgür, başı boş ve dağınık olur. Bu noktada önemli olan, böyle bir mimarı anlayışın ve alt yapının gerekliliğinin farkında olup, en uygun mimariyi oluşturmaya çalışmaktır.

Peki neden gerekli?

Oluşumlar meydana gelirken, zaman içerisinde büyümeyle beraber farklı birim ve bireyler ortaya çıkar. Bu birim ve bireylerin, oluşumun vizyonuna hizmet etmesi, misyonu gerçekleştirmesi adına, iletişimleri ve ilişkileri çok önemlidir. Bu ilişkilerin yönetilmesi ve sürdürülebilir olması için mimari bir alt yapı gereklidir. Tamamen yazılım mimarisinde ki yaklaşım ile aynı diyebiliriz aslında.

Mimari alt yapı oluşturulurken, oluşumun amacı ve bu amaç dahilinde ki operasyonları iyi analiz edilmeli ve tasarlanmalıdır. Kurumsal mimari, değişikliklere açık ve yeniliklere de uygunluk sağlayabilmedir. Bu sürdürülebilirliğin en önemli kriteri bence. Bu yüzden mimarinin bu yönden güçlü ve açık olması, kafa yorulması gereken önemli konulardan olmalı.

Büyük oluşumlar, zaman içerisinde sahip oldukları tecrübelerinden dolayı kurumsal bir mimariye sahiptirler aslında; ama çok farkında değillerdir. Belli standartlara uyma çalışmaları ve büyümelerin hızlı olması artık bu mimarilere daha önem vermeyi ve daha sağlam adımlar atmayı gerektiriyor. En azından Türkiye için böyle gibi diyebilirim. Küçük oluşumlar ise bu farkındalığa, günümüzün getirdikleri sayesinde daha önceden sahip olup, adımlarını o yönde atmaya çalışarak büyüme adına daha sağlam adımlar atma şansına sahip. Bu noktada belli tecrübelerin ortaya koyduğu çeşitli kurumsal mimari modeller mevcut.

Bir yazılımcı olarak, kurumsal mimarinin yazılım açısından önemi sanırım asıl ilgilendiğim tarafı. Bu yüzden de, biraz bu açıdan saçmalıyım. Kurumsal mimarinin, yazılım ile ilgili iki tarafı var aslında. Bir tanesi bu mimarinin oluşturulmasında ve sürdürülebilirliğinde kullanılan yazılım araçları, araçların oluşturduğu sistemler; diğer tarafı da yazılım geliştirme süreçlerindeki etkisi. Yazılım araçlarına bu yazıda çok girmiyor olacağım. Ancak ilerleyen zamanlarda, bu yazılım araçlarının oluşmasında ya da neler yapılması gerektiğine dair bir çok şey saçmalıyor olacağım…Şimdilik biraz yazılım geliştirme süreçlerine olan etkisinden bahsetmek istiyorum.

Devam…

JSPY2013Günümüzde modern web teknolojileri dendiğinde ilk olarak akla gelen JavaScript, Python ve Ruby geliştirme dilleri ile ilgili oldukça geniş kapsamlı bir etkinlik,-sanırım ilk defa; 30-31 Mart 2013 tarihinde, İstanbul’da Özyeğin Üniversitesi’nde gerçekleşecek. Yerli ve yabancı yaklaşık 20 konuşmacının yer alacağı bu etkinlikte, anlatımlar dışında çeşitlik workshop’lar ile geliştirme örnekleri ile de bu teknolojileri daha yakından görebileceksiniz.

Web uygulamaları geliştiren ve son teknolojileri takip edenlere tavsiye ederim. Kayıt için bu adrese gitmeniz gerekmektedir. Son olarak etkinlik ücretsiz olup, programını da aşağıda bulabilirsiniz diyip kapatıyorum (:

Program:
30 Mart Cumartesi, Salon 1:
09:30 – 10:00 – Açılış Konuşması
10:00 – 10:45 – Burak Yiğit Kaya, Disqus – Standardized real-time events with EventSource
11:00 – 11:45 – Emrah Ayanoğlu, STM – Python ve Ruby ile Gerçek Zamanlı Web Uygulamaları
12:00 – 12:45 – Kenneth Reitz, Heroku – Python for Humans
12:45 – 13:45 – ÖÐLE ARASI
13:45 – 14:15 – Kadir Pekel, MetGlobal – Python ile Bir Değişim Hikayesi
14:30 – 15:15 – Tim Branyen, Matchbox – The Holy Grail: Client & Server
15:30 – 16:15 – Nathan Rapheld, Zendesk – Single-Page Apps with Ember
16:30 – 17:15 – Özgür Vatansever, Markafoni – Python Optimizasyon ve Performans Tüyoları
30 Mart Cumartesi, Salon 2:
10:00 – 11:30 – Sinan Yaşar, Koding – [N/A]
11:45 – 12:45 – Altan Yılmaz, Yemeksepeti, JavaScript ve PhoneGap ile Mobil Uygulama Geliştirmek (Atölye)
14:00 – 15:30 – Serdar Dalgıç, Markafoni – Deneyimli Programcılar için Django’ya Giriş
16:00 – 17:30 – Taylan Pince, Hipo – Veritabanındaki Koordinatlar: Lokasyon Bazlı Veri Nasıl Saklanır,
Aranır ve Görselleştirilir?

31 Mart Pazar, Salon 1:
10:00 – 10:45 – Fatih Erikli, MetGlobal – Django ORM Optimizasyonu
11:00 – 11:45 – Tayfun Şen, Markafoni – API Design and Implementation Using MongoDB and Tastypie
12:00 – 12:45 – James A. Rosen, Zendesk – JavaScript Tools for Developer Happiness
12:45 – 13:45 – ÖÐLE ARASI
13:45 – 14:15 – Sinan Yaşar, Koding – [N/A]
14:30 – 15:15 – Uğur Özyılmazel, Edfor – Merhaba Sinatra!
15:30 – 16:15 – Charles McCathie Nevile, Yandex – [N/A]
16:30 – 17:15 – Osman Yüksel, Sonsuzdöngü – JavaScript Web Uygulamaları ile Arama Motorlarının Arasındaki Husumeti Gidermek
31 Mart Pazar, Salon 2:
10:00 – 11:30 – Murat Çorlu, Sahibinden – JavaScript Sourcemaps 101
14:00 – 15:30 – Chris Thorn, Koding – [N/A]
16:00 – 16:45 – Kadir Pekel, MetGlobal – Kurtulur muyum bunalımdan, hamakta sallansam

Not: [N/A] yazan konu başlıkları konuşmacılar tarafından onaylandıktan sonra yazılacaktır.
Program sürecinde etkinlik tarihine dek değişiklik olabilir.