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

“Agile yöntemlerden beklediğimiz faydayı alamıyoruz. Agile yöntemlerden maksimum düzeyde nasıl kazanç sağlarız?”

13-14-15 Mayıs tarihlerinde İstanbul’da, Agile Fluency™ Model ile ilgili oldukça güzel bir workshop var. Scrum Turkey‘in düzenlediği bu workshop ile yukarıdaki sorunun cevabını, en doğru kişiden, Diana Larsen’den alma şansına sahip olacaksınız. Diana Larsen ve Steve Holyer‘ın katılımı ile gerçekleşecek bu 3 dolu gün ile ilgili ayrıntıları bu adresten takip edebilirsiniz. Oldukça profesyonel ve dolu bir içeriğe sahip olacak bu etkinliğin ücreti Nisan ayının başına kadar indirimli. Bu indirimden faydalanmak ve kısıtlı sayıdaki katılımcılardan biri olmak için elinizi çabuk tutun derim… Açıkcası biraz reklam gibi oldu ama konusu itibari ile ve Türkiye’de Agile yöntemlerin yeni yeni anlaşılıyor ve kabul ediliyor olması açısından, oldukça faydalı ve önemli bir workshop olduğunu düşünüyorum. Agile Transformation süreçine giren firmalara şiddetle tavsiye ederim…

 

 

Nisan ayında İstanbul’da oldukça güzel bir etkinlik haberim var. 27 Nisan günü Kadir Has Üniversitesi‘nde paralel oturumlar ile gerçekleşecek Istanbul Tech Talks, içerik olarak oldukça farklı ve zengin bir içeriğe sahip. SoundCloud, Facebook, Coursera gibi firmalardan gelen katılımcılar ile bütün gün sürecek etkinliğin katılım ücreti 15 Mart’a kadar 25$. Etkinliğe katılmak için bu adresten kayıt olabilirsiniz.

Etkinlik sitesi : http://www.istanbultechtalks.com

Istanbul Tech Talks Agenda

“Implicit” ve “Explicit” kelimeleri, C# ile geliştirme yapan herkesin zaman zaman oldukça kullandığı kavramlar. Tipler arası çevrimler için tercih ettiğimiz iki farklı yöntem aslında…”Implicit Conversion” ve “Explicit Conversion”. Hatırlamak adına aşağıdaki kod örneği yeterli olacaktır sanırım. Syntax olarak aralarındaki fark, Explicist Conversion’da “(type)” şeklinde cast operatörünün olması.

Implicit Conversion

            int number = 3;
            double doubleNumber = number;

Explicit Conversion

            double average = 4;
            int avg = (int)average;

Oldukça basit ve tanıdık, değil mi… Bu noktadan itibaren bu cast işlemlerini, operatör overloading’e benzer bir şekilde nasıl kendi objelerimiz için yapabiliriz bundan bahsetmeye çalışacağım. Açıkçası çok tercih edildiğini düşünmüyorum, ama yeri geldiğinde bir kaç problemi çözmede yardımcı olabilir.

Geliştirilmesine müdahale edemediğimiz ve artık geliştirilmeyen kütüphaneler ile geliştirilmiş legacy sistemlere müdahale etmemiz gerektiğini düşünelim. Her yazılımcının rüyası…Daha doğrusu kabusu. Neyse…Bu kütüphanelerdeki tipleri, kendi geliştirdiğimiz yeni tiplere çevirmemiz gerektiğinde, çeşitli Helper sınıfları ve metodları ile “conversion” işlemlerini yapabiliriz. Buna ek olarak, conversion(cast) operatörünü kullanarak da basitçe yapabiliriz.

Aşağıdaki gibi bir birinden bağımsız iki tane sınıfımız olsun. Burada bağımsız derken Dolar sınıfı, XYZ assembly’sinde, TL sınıfı da ABC assembly’sinde olsun…Ve TL sınıfı bizim geliştirdiğimiz yeni bir sınıf olsun. Yani biraz daha kontrolü bizde. Bu şekilde bir senaryo ile çözüm sağladığı nokta daha iyi anlaşılabilir diye düşünüyorum.

    public class Dolar
    {
        public double Value { get; set; }
        public string Sign { get; private set; }

        public Dolar(double v=0)
        {
            Sign = "$";
            Value = v;
        }
    }

    public class TL : Currency
    {
        public double Price { get; set; }
        public string Sign { get { return "₺"; } }
    }

    public abstract class Currency
    { 

    }

Dolar sınıfından yarattığımız bir nesneyi, TL sınıfından bir nesneye çevirmek istediğimizde aşağıdaki gibi bir cast işlemi ile yapabiliriz. Ama tabi ki Dolar sınıfı, TL sınıfından türemediği için hata alırız.

    class Program
    {
        static void Main(string[] args)
        {
            Dolar dolar = new Dolar(250);
            TL test = (TL)dolar;

        }
    }

Burada yapmaya çalıştığımız aslında “Explicit Conversion”. Ama cast operatörü diyebileceğim “(type)” operatörü bu tipler için geçerli olmadığından, “Cannot convert type” hatasını alıyoruz.

cast

Devam…

Geçtiğimiz sene .NET Core adı altında, .NET Framework’ün bir kısmı yeniden düzenlenip açık kaynak olarak yayınlandı. Cloud platformuna daha uygun, scale edilebilecek modüler bir framework olması, farklı platformlarda da çalışabilmesi(Linux, Mac OS X) ve açık kaynak olabilmesi için böyle bir düzenlemeye gidildi. Öncesindeki .NET Framework’ün client-server versiyonları ve PCL(Portable Class Library) yaklaşımları bu amaçlara kısmen hizmet etmeye çalışsa da, “tek” bir kod alt yapısı üzerinde olmuyor olması yönetmeyi zorlaştırıyordu. Kısacası, temel olarak açık kaynak olabilmesi, cloud’da modüler bir şekilde çalışabilmesi, tek bir kod alt yapısı olması ve farklı OS ortamlarında da çalışması için .NET Core oluşturuldu. Burada özellikle belirtmek isterim ki, .NET Core != .NET Framework

Bahsetmiş olduğum ihtiyaçlar, .NET Framework ilk çıktığında ortada olan kavramlar olmadığından dolayı, bu ihtiyaçları mevcut .NET Framework tarafında yapmanın zorlayıcı olacağından böyle bir yaklaşım ortaya çıkıyor. .NET Core’u,  bir nevi .NET Framework’ün refactor edilmiş hali olarak da düşünebiliriz.

.NET Core’dan önce Windows uygulamaları, mobil uygulamalar ve Asp.Net uygulamaları, teoride aynı .NET Framework alt yapısını kullansada pratikte böyle değildi. .NET’in içindeki PCL, Code Contracts gibi kavramlar ile framework içindeki kodlar çeşitli durumlara göre ayrışıyordu. #if Mobile #endif gibi ifadeler ile aynı kod içinde farklı ihtiyaçlara karşılık veriliyordu. Bu da modülerlik problemine yol açıyordu. .NET Core ile beraber bu ortadan kalkıp, tüm uygulamalar için, yukarıdaki bahsettiğim ihtiyaçları da karşılamak adına, BCL(Base Class Library) tarafında da iyileştirmeler ile tek bir ara katman sağlanıyor artık.

bcl

Bütün bunlar tabi .NET Framework’ün artık atıl kalacağı anlamına gelmiyor. .NET Framework hala temel uygulama platformu. Mesela WPF,Windows Forms,WF,WCF gibi kavramlar .NET Framework’ün içerisinde olup, .NET Core tarafında olmayan parçalar.
net2015

.NET Core ve .NET Framework’ün bir diğer önemli farkı da, .NET Core’un, modülerlik ihtiyacından dolayı NuGet paketleri üzerinden yayınlanıyor olması. Bu noktada tek bir paket olmadığını, .NET Core içerisindeki çoğu bileşenlerin ayrı ayrı NuGet paketleri olarak yayınlanacağının da altını çizmek isterim. Yaşasın modülerlik… Ama tabi ayrıca offline installer’lar ile de bu paketlere belli versiyonlar ile ulaşmak mümkün olabilecek.

.NET Core’un en büyük özelliği de cross-platform olayının, bu sayede resmi olarak desteklenmesi. Mono sayesinde, Mac OS X ve Linux platformalarında .NET uygulamalarını çalıştırmak kısmen mümkün olabiliyordu. Ama bunların geleceği net olmadığı için, bu platformlarda .NET teknolojilerine pek yatırım yapılmıyordu. .NET Core’un iyice olgunlaşım bu plaftormlar için Microsoft tarafından resmi olarak destekleniyor olması, uzun vadede bu yatırımları arttıracaktır diye düşünüyorum.

Ve açık kaynak…

.NET Core’un ihtiyaçlara daha çabuk adapte edilebilmesi adına, bu oluşumu direkt olarak açık kaynak bir proje olarak yayınladı Microsoft. Bu sayede, herkes kodlara göz atıp, istediği şekilde düzenlemeler,geliştirmeler yapabiliyor artık. GitHub üzerinden yayınlanan kodlara katkıda bulunmak için tabi, uyulması gereken bazı kurallar ve sonrasında da denetlemeler var.

.NET CoreCLR

.NET Core’un çalışması için de parallelinde CoreCLR diye de bir runtime modeli de oluşturuldu haliyle. .NET Framework’deki Common Language Runtime(CLR)’a benzer olarak düzenlenen CoreCLR, .NET Core ile geliştirilen uygulamaların çalışmasını sağlayan temel bileşen. Ve dün bu bileşen de açık kaynak olarak yine GitHub üzerinden yayınlandı. Açıkcası runtime’ın bu şekilde yayınlanıyor olması çok önemli. Farklı platformlardaki gelişmelerin önünü açacağına inanıyorum. Bekleyip göreceğiz.

2015, .NET tarafında bir çok değişikliğe ev sahipliği yapacak bir yıl olacak. Bakalım bu değişiklikler bize neler getirecek, bizden neler götürecek…

Bu arada tüm bu değişiklikleri aşağıdaki GitHub adreslerinden takip edebilirsiniz.

.NET Core – https://github.com/dotnet/corefx
.NET CoreCLR – https://github.com/dotnet/coreclr

Şu sıralar .NET dünyasının en popüler konularından biri .NET Compiler Platform(a.k.a Roslyn). .NET Compiler’ın API’i olarak dışarı açılan servisleri ile bayaa taklalar atmak mümkün. Bir önceki yazımda küçük bir giriş yapmıştım hatırlarsanız. .NET Compiler Platform‘u olgunlaşana kadar, biraz da temelleri daha iyi anlamak için “Expression Tree” kavramından, çok derinlere inmeden bahsetmeye çalışacağım. Açıkcası biraz merak uyandırmak, arkalarda işler nasıl oluyor bunları araştırmaya teşvik etmek için bu yazıda çok fazla derinlere girmek istemiyorum. İlerleyen yazılarda zaten kaybolup gideceğiz, baştan söyliyim.Neyse…

Expression Tree, bir çok compiler’ın çalışma mantığında geçerli olan bir kavram aslında. Kodun, ağaç gibi dallar(node) ile temsil edildiği bir veri yapısı diyebiliriz Expression Tree için. Zaten adından da anlaşılıyor. Bu dallar, koddaki her bir parçayı temsil eder. Değişken, metod çağrısı, if-then-else bloğu gibi gibi…

Temel olarak kodların çalışması da, bu ağaç yapısının derlenmesinden sonra oluyor. .NET tarafındaki Expression sınıfı da, bu ağaç yapısının oluşturulmasında ve derlenmesinde kullanılması için bize sunulan bir sınıf. Lambda kavramının .NET tarafında oluşturulması, LINQ ve dinamik runtime(DLR) aslında bu “Expression Tree” yaklaşımı sayesinde, yani Expression sınıfı ile oluyor. Yani basitçe de olsa, çalışan kodda dinamik değişiklikler yapmak, dinamik ifadeler oluşturmak .NET’de zaten mümkündü.

Kod görmeden, ben anlamam diyorsanız aşağıdaki kod örneğine bir göz atalım.

Expression<Func<string, bool>> lambdaExpression = name => name == "Arda";
Func<string, bool> quessMyName = lambdaExpression.Compile();

bool result = quessMyName("Arda");

Console.WriteLine("Sonuç: {0}", result.ToString());

Yukarıdaki kod ile run-time sırasında bir metod oluşturuyoruz ve bu metodu çağırıp, sonucunu konsola yazdırıyoruz. Burada önemki olan generic olan, Expression tipindeki obje. Lambda ifadesi ile name değerinin “Arda”‘ya eşitliliği tanımlanıyor. Bu ifadeyi daha sonra Compile() metodu ile derliyor olduğumuzu düşünebiliriz. Ve artık elimizde quessMyName() adında bir metodumuz olmuş oluyor. Oluşturulduğu context’den dolayı, normal bir metod gibi düşünmek çok doğru olmaz tabi ki.

Expression sınıfı, oldukça geniş bir metod yelpazesine sahip. Kodu yazarken kullanabileceğiniz Expression’ları kolaylıkla ifade edebileceğiniz tüm metodlar var. if-then-else bloğu, döngü oluşturmak için loop bloğu, aritmetik operasyonlar, büyük-küçük ifadeleri gibi Expression sınıfı ile oluşturabilirsiniz. Hepsini tek tek anlatmam mümkün değil açıkcası. Ama biraz daha anlaşılır olması için yine aşağıdaki koda göz atabiliriz.

ParameterExpression value = Expression.Parameter(typeof(int), "value");

LabelTarget returnValue = Expression.Label(typeof(bool));

BlockExpression methodBody = Expression.Block(

Expression.IfThenElse(
Expression.Equal(Expression.Modulo(value, Expression.Constant(2)), Expression.Constant(0)),
Expression.Return(returnValue, Expression.Constant(true)),
Expression.Return(returnValue, Expression.Constant(false))),
Expression.Label(returnValue, Expression.Constant(false))
);

Func<int, bool> IsEven = Expression.Lambda<Func<int, bool>>(methodBody, value).Compile();

var result = IsEven(6);

Console.WriteLine("Sonuç: {0}", result.ToString());

Yukarıda, run-time’da yine bir metod oluşturuyoruz. Bu metod ile bir sayının çift mi ya da tek mi olduğunu kontrol ediyoruz. Basit bir aritmetik işlem aslında. { } ifadelerine denk gelen, Block() metodu içinde, teker teker Expression’larımızı oluşturuyoruz. Önce IfThenElse() ile parametre olarak alacağımız sayının %(Module) mod’unu alıp, bunun 0 şeklinde bir sabit değişkenle eşitliğini kontrol ediyoruz. Eğer eşitlik doğru ise, Return() ifadesi ile true dönüyoruz, eğer eşitlik doğru değil ise yine Return() ifadesi ile false dönüyoruz.

Daha sonra IsEven olarak bir değişken belirleyip bu ifadeyi, Compile() metodu ile derliyoruz(!!! yani sayılır). Bu kod bloğunu yazdığımız içerikte artık IsEven() şeklinde bir metodumuz, -ki aslında bir delege, kullanıma hazır oluyor.

Bu kodu çalıştırdığımızda methodBody‘yi Debug yaparak kontrol ettimizde, DebugView özelliğinde aşağıdaki gibi biraz daha tanıdık bir ifade görüyor olacağız.

ExpressionBlockResult

Fark etmiş olduğunuz gibi, Expression sınıfı ile yazdığımız ifadeler, biraz daha aşina olduğumuz bir syntax ile karşımızda.

Expression Tree’leri, .NET Framework’ünü genişletmek amacıyla, dinamik olarak kodda değişiklikler ve eklemeler yapmak için kullanabiliriz. Açıkcası ilk başlarda çok zorlanabilirsiniz. Hem Expression’ları oluşturmak, hem de nasıl çalıştıklarını anlamak ilk başlarda oldukça zorlayacaktır. Ancak kavradıktan ve asıl önemlisi tüm Expression metodlarına hakim olduktan sonra bir çok problemi kolaylıkla çözebilecek duruma geleceksiniz.

Şimdilik bu kadar…Bir ara biraz daha derinlere ineriz.