December 11

Algılarımız ve Varlığımız

Geçenlerde bitirdiğim kitabın adı, Obstacle Is The Way, bu konumuzun içeriğini oluşturuyor aslında. İnsanın başına gelenlere karşı alması gereken tavırları, hayatlarında nasıl hep ileriye gidebileceklerini, ve duygularının esaretinden gerçeklerin özgürlüğüne nasıl çıkabileceklerini Stoicism çercevesinden anlatıyor.  Bu aslında bir düşünce ve yaşama akımı olarak çıkıyor karşımıza. Milattan sonra 3. yüzyılda bir yunan felsefesi ve insanın başına gelenlere şikayet etmeden katlanması gerektiğini öğretirken, yaşadığımız yıkıcı duygusal değişimlerin meydana geliş sebeplerini kendi iç dünyamızda vermiş olduğumuz yanlış kararlar olduğunu söyler. Bu açıdan kendi iç dünyalarını ve duygularını kontrol altına almış insaların yada başka bir tabir ile ahlaki ve akıl olarak mükemmelliğe ermiş olan bilgelerin bu şekilde meydana gelen duygusal sıkıntılara maruz kalmayacağını söyler. Çünkü belkide sebepler perdesi altına gizlenmiş olan hikmetleri görebiliyorlardır.

Hayat bizim algıladığımız gibidir. Kendinizi 4 duvarı camdan meydana gelmiş bir odada düşünün ve dış dünya ile alakanız bu odada  görebildiğiniz kadardır. Hatta bir de bu odayı cam değilde aynalar ile donatın o zaman ise aslında birbiri içinde sonsuzluğa uzanan bir odada yaşıyormuş hissine kapılırsınız ta ki kafanızı biraz yürüpte bu aynalara çarpana kadar. Bu kısımları Risale-i Nur kitaplarında buna benzer bir şekilde anlatılmaktadır. Sizin bu aynalara siyah boya sürmeniz odanın rengini siyah değil sadece sizin bakışlarınızı siyah yapacaktır. Burada aslında anlatılırken cam yerine ayna seçilmesi daha manidar. Çünkü insanlar geçmişin akılda kalan izleri ve geleceğin daha gelmemiş olan hayalleri ile içinde bulundukları zamanı yada anı sonsuzluğa doğru esnetirler. Halbuki sahip olduğumuz tek şey içinde bulunduğumuz ve devamlı yenilenen ama yenilenmesi garanti olmayan bir zaman dilimi olan ‘An’dır sadece.

Kitap 3 kısma ayrılmış. Birinci kısım ki bence en önemli olan kısmı idi ”Perception” yani ”Algı” denilen kısım idi. Dünyayı ve olayları nasıl algıladığımızdan bahsediyor. İkincisi kısım ”Action” ve yani harekete geçmek ve son olarak 3. kısmı ise ”Will” yada ”İrade” dediğimiz bize verilen en değerli yeteneklerden birisi.

Ben aslında bugün daha çok algı mefhumu üzerine durmak istiyorum. Diğer konularada yeri gelince değinebilirim. Yukarıda görüldüğü gibi algılarımız bizi dünyada rezil yada vezir edebilecek kadar önemli bir yere sahip. Olayların yanlış anlaşılması çok yanlış sonuçların ortaya çıkmasına sebep oluyor. Shakespeare iyi yada çirkinin olmadığını yalnız bizim onları nasıl görmek istediğimiz olduğunu söyler. Bu bize aklın güzel gördüğü ve aklın çirkin gördüğü terimlerini hatırlatıyor. Ben aslında herşeyin güzel olduğunu çünkü varlık yaratılışından dolayı güzel olduğunu ama bunu her aklın idrak edemeyeceği kanaatindeyim. Bunun için aklın çok sağlam bir terbiyeden geçmiş olmasının yanı sıra varlığın sırlı perdesi altında Yaratıcı ve yaratılışı hakiki manada idrak etmesi lazım gerektiğine inanıyorum.

Bizler varlığa bakarken uzun yıllar sosyal çevremizin algılarımızın üzerinde yapmış olduğu formasyonla bakarız. Halbuki varlık algılarımızın esiri olacak kadar basit değildir. O matematiğin dehası, atomların en güzel dansı, kimya, fizik ve biyolojinin akıl almaz uyumudur. Ne eksik ne fazladır. Hayalleri heyecanlandıran bir ilmin varlık sahasıdır. Kocaman kainatın bir tozuna muhtaç olacak kadar girift ama ondan ayrı duracak kadar da basitlik içindedir. Başımıza gelenleri bu açıdan bakınca tesadüfler ile açıklamak sadece acizlik ve miyopluktan meydana gelmektedir. Herşey gibi meydana gelen olaylarda planı ve programı yapılmış olmalıdır ve öyledir de. Onun için varlığın perde altında bu kadar güzellik saklayan, olayların perde arkasında ise nice hikmetler saklamıştır. İşte başımıza gelecek olaylara sabretmemizi ve sesimizi dahi çıkarmayacak kıvama gelmemizi sağlayacak öğretinin ilk adımı algılarımızın bize çirkin gösterdiği herşeyde aslında bir hikmetin bulunduğuna karşı olması gereken inancımızdır.

Hikmet inancı bizim ruhen değişmemize ve başımıza gelen olaylarda daha halim selim davranmamızı ve sinirlerimizi kontrol etmemizi sağlayacaktır. Hz. Peygamberin dediği gibi sabır başımıza kötü bir olay geldiğinde ilk gösterilendir. Yoksa bağırıp çağırdıktan sonra tamam şimdi sabredeyim demek aynı şey olmuyor. Ama sabır gösterebilmek için varlığın perde arkasına bir göz atmak gerekiyor. Sabır zamanında Obstacle Is The Way kitabında verilen tavsiyelerden bir taneside bulunulan An’a zihnen geri dönmek vardı. Bu şu demek: İnsan bir anda başına gelen olayda geçmişe bakıp benzer olayları görmeye yada geleceği düşünüp daha kötü şeylerinde başına geleceği korkusuna kapılır. İşte bunlar zararlıdır. Aslında Hz. Bediuzzaman bunu çok güzel bir örnekle açıklar ve geçmiş düşmanlardan korkup sola ve gelecek düşmanlardan korkup sağa asker yığan bir kumandan şu anki düşmanlara karşı ortaya asker yığmaz ise mağlup olur. Evet bize bahşedilmiş olunan sabır kuvveti bize o anda meydana gelen olaylara karşı savaşacak kadar güç verir. Geçmişin ve geleceğin zararsız korkularına karşı kullanıldığında bulunan anın içinde mağlup olunur.

Sinirlerini ve duygularının yatıştıran insan için artık daha bir objective bakabilme şansı doğmuş demektir. Yani olaylardan ”ben” lafı çıkarılmış ve o şekilde bir incelemeye tabi tutmak demektir objective olmak. İnsan belkide olaylara kötü yada iyi şeklinde değil bir sonra ki adımını atarken karar vermek için kullanacağı bir bilgi şeklinde bakmalıdır. İnsanın 100% denilecek kadar kontrol edebildiği tek şey kendi dünyaya bakışıdır ve mutluluk bir seçimdir denilirken bahsedilende aslında budur.

İnsan olarak çok yüksek kabiliyetler ile yaratılmışız. Hayalimizle kainatı geziyor, yaklaşılması en korkunç olan kara deliklerin yanına kadar gidebiliyoruz, bir akşam dünyamızı yukarıdan dönerken izliyor, yeri geliyor geçmişimizin o sırlı odalarında dolaşıyor ve daha meydana gelmemiş zamanların karanlık odalarına ışık tutuyoruz. Biz insanız ve kainat içinde yaratılmışların en üstünüyüz. O kadar üstünüz ki istersek yaratılmışların en aşağısına bile düşebiliyoruz yada en yukarısına çıkabiliyoruz. Ama maalesef bize bahşedilen nice fakültelerimiz kullanılmadığı için zamanla kapanıp gidiyor. Bu zaviyeden bakınca aslında şunu demekte önemli ki bizler geçmişe takılmayacak kadar, geleceğin korkusunda boğulmayacak kadar güçlü yaratılmışız. Ama bu gücümüzün açığa çıkması için kullanılması gereken iki sırlı anahtar var. Bunlar acizlik ve fakirlik anahtarları ki bizi Yaratanın kapılarını bizlere açıyor. Bunlar dünyanın en kaliteli bilgisayarının çalışması için ihtiyaç duyduğu elektrik ve soğutucu iki çihaz gibi. Bu yeteneklere sahip olmamız için bunları bize bahşedene sığınmak ve bu yeteneklerin çalışmasını sağlayacak gerekli irfan ve manevi enerjilerin ondan gelmesini istemek lazım. Objective olmak bize farklı sırlı kapılar açabilir bu açıdan bakınca. Çünkü artık varlığı kendi iç dünyamızın kiri toprağı ile değil Yaradanın varlık üzerinde ki hakimiyeti ve muradı üzerinden bakmamızı sağlayacak bir cihaz sunuyor bizlere.

Paylaş herkes duysun!Share on Google+Share on LinkedInTweet about this on TwitterShare on Facebook
November 22

Interface ve Abstract sınıf arasında ki farka farklı bir bakış

Yazılımcıların en çok karşılarına çıkan mülakat sorularından bir tanesidir bu Interface ve Abstract arasında ki fark nedir sorusu. Genelde verdiğimiz cevap ise gayet basittir: İkiside instantiate edilemez (yani kendilerinden bir nesne oluşturulamaz), kalıtım alınmaları zorunludur ama abstract sınıflar implementasyon içerebilirlerken, interface’ler sadece declaration içerir. Hem Türkçe ve hemde İngilizce arasında gelip giden doğru ama anlatım bakımından biraz anlamsız bir açıklama oldu, ama aslında değinmek istediğim mesele zaten bu değil. Eminim çoğumuz bu kısımları biliyoruzdur.

Gelmek istediğim konuya gelmeden önce de bir kaç bir şeye değinmek istiyorum:

  1. Eğer Java kullanıyorsanız, interface’ler C#’dan farklı olarak method implementasyoları içerebilir ve bunlara default methods denir. Yani sadece abstract sınıflar bu lükse sahip olmayabilir. Yukarıda ki tanımlama hangi dili kullandığınıza bağlı olarak ufak bir değişiklik isteyebilir.
  2. Interface yada Abstract Sınıflar bilindiğinin aksine konseptlerdir. Bu konseptleri bazı diller mesela Java ve C# gibi dil yapısı olarak kullanma şansı verirken ve kurallar şeklinde tanımlarlarken, Python yada buna benzer dynamic diller için bu daha çok programcıya bırakılmış bir durumdur. Yani her dilde interface keyword’u göremeyebilirsiniz. Bunu ifade sadedinde Code Complete 2 kitabında gördüğüm şu kuralı hatırlamakta fayda var ”Don’t program in a language but program into the language.” yani programlama dilinin sahip oldukları ile kısıtlı kalmayın, bildiğiniz konseptleri programlama dilini kullanarak siz oluşturun. Mesela dil içinde interface diye bir kavram yoksa siz kendiniz interface olarak kabul ettiğiniz yapıları oluşturabilirsiniz. Yada mesela private keyword yok ve siz private field oluşturamıyorsanız o zaman private olmasını istediğiniz tüm field isimlerinin başına __ koyarak bu isteğinizi tanımlayabilirsiniz.

Şimdi kendi konumuza gelelim. Bu tarz karşılaştırmalı sorularda şahsen benim beklediğim cevap daha farklı olurdu. Yukarıda verdiğimiz interface ve abstract arasında ki tanım daha çok bu konseptlerin dil yapısı içinde ki yansıması. Ama daha önemli olan cevap ise bu iki konseptin kullanımlarının projenizde doğuracakları farklılıklar. Genelde interface’leri abstract sınıflara tercih edin diye bir öğüt vardır. Beraber incelemeye çalışalım:

  • Interface’ler abstract sınıflara göre daha esnektirler ve hiyerarşi içinde her yerde kullanabilirler. Abstract sınıflar ise birden fazla sınıftan kalıtım alınmadığı dillerde daha sınırlıdırlar. Eğer daha çok önceden yazdığınız sınıflara interface  apply etmek istiyorsanız rahatça yapabilirsiniz. Ama eğer sınıflarınız bir hiyerarşi içinde ise ve başka sınıftan kalıtım alıyorsa başka bir sınıftan da kalıtım almak istiyorsanız o zaman bu hiyerarşi içinde en tepedeki sınıfa gidip ona kalıtım vermeniz gerekir. Bu da interface’ın esnekliğinin abstract sınıflarda olmadığını gösteriyor.
  • Eğer bir library tasarlıyor iseniz o zaman abstract sınıfları başka package’lerin kullanacağı şekilde public yapmak çoğu zaman sıkıntı oluşturur çünkü implementation detail kısımlarının açığa çıkma ihtimali vardır. Encapsulation sadece sınıfınızı başka sınıflardan korumak değil aynı zamanda evlatlarınnda da korumak şeklinde tezahür eder. Eğer siz abstract sınıfınızı kütüphanenizi kullacak developler’ın doğru düzgün anlayacakları şekilde dökümante etmez iseniz o zaman daha büyük sorunlar baş gösterecek demektir. Çünkü onlar kendi bildikleri şekilde extend ettikleri bu abstract sınıflarda method’ları override edecek ve belkide abstract sınıf içinde ki implementation yapısını bozacaklar. Eğer siz buna göre bir tasarımda bulunmadıysanız o zaman hatalar meydana gelecektir. Haklısınız abstract sınıflar kalıtım alınsın diye kullanırlarlar ama düzgün tasarlanmadıklarında ise faydalarından daha çok zarar verirler. Interface’ler için böyle bir sıkıntı söz konusu değil. Onlar zaten implementation detail expose etmediklerinden dolayı daha korunaklıdırlar. Bu kısım hakkında daha çok şey yazılabilir ama o zaman blog post olmaktan daha ziyade kitap olmaya başlar.
  • Interface’ler sadece bir hiyerarşi manasını taşımazlar. Yani sizin bir sınıfta ISerializable  şeklinde bir interface implement etmeniz dil yapısı açısından sizin sınıfınız belki bu interface’in bir çocuğu olmuş gibi dursada aslında burada ki mantığınız ata-torun münasebetinden daha çok sınıfınıza farklı bir kabiliyet ve fonsiyon verme münasebetidir. Böyle olunca mesela sizin sınıfınız ISerializable , IComparable , vs. şeklinde yeni kabiliyetler tanımlayabilir. Bu sayede bu kabiliyetlere bakan başka sınıflar sizin sıfınızın sadece bu kısımları ile ilgilenirler. Ama abstract sınıflar için bu tam böyle değildir. Abstract sınıflarda inheritance daha çok bir hierarşi beklentisi oluşturur. Yani Hayvan – Kedi, yada İnsan – İşçi şeklinde bir tanımlama.
  • Abstract sınıflar API tasarladığınızda sizi daha çok sınırlandıracak sorunlar ile çıkarlar karşınıza. Mesela abstract sınıf içinde protected  yada public  dediğiniz member’lar bir kez dış dünyaya çıktımı artık bundan sonra yapacağınız her versiyonda onları da göz önünde bulundurmanız gerekmektedir. Aksi halde nice code’un kırılmasına sebeb olursunuz. Daha somut bir örnek vermek gerekirse mesela bir tane MyList tipinde bir abstract sınıf tanımladınız ve içinde bir ton farklı method yanında birde add(int sayı)  and addRange(Integer[] sayilar)  şeklinde methodlar koydunuz. Bir developer’dan her yeni bir eleman eklendiğinde sayacını bir artıran bir class yazmak istedi ve sizin MyList sınıfınızı kalıtım olarak aldı. Şimdi sizin bu iki methodunuzu override etti ve içine sayaç kodunu koydu. Ama ne zaman addRange  methodunu 3 tane eleman içeren bir array ile çağırsa sayaç hep çifter çifter sayıyor gördü ve baktı ki sayaç 6 diyor. Birinci sorun işte burada. Çünkü siz addRange methodu içinde array içinde bulunan her bir eleman için add  methodunu çağırıyorsunuz ama bunu düzgün dökümante etmemişsiniz ve yazılımcı onun için sayaç kodunu gitti her iki method içine koydu. Şimdi peki diyelim ki bunu dökümante ettiniz ve yazılımcı bundan dolayı sayaç kodunu sadece add  method’u içine koydu. Ama API yazarken siz yeni versiyonda addRange  methodunu değiştirmek istiyorsunuz çünkü çok daha verimli çalışan bir kod geliştirdiniz ama bu yeni kod içinde  add  methodunu addRange  methodu içinde çağırmak istemiyorsunuz. Çünkü bu yeni algoritmanız sadece array’ler üzerinde bu kadar verimli çalışıyor. Peki bu durumda ne yapacaksınız? Görüyorsunuz ki addRange methodunun içeriğini değiştirmek sizin kodunuza bağlı daha nice başka kodların bozulmasına sebep olacak.

Yazıyı daha fazla uzatmadan burada kesmek istiyorum ama daha başka farklılıklar olabilir, onlarıda yorum köşesinde sizden almak isterim. Herkese kolay gelsin.

Paylaş herkes duysun!Share on Google+Share on LinkedInTweet about this on TwitterShare on Facebook
November 19

Maymun İştahlı bir Yazılımcı Olmak

Yani her yeni çıkan teknolojiyi öğrenmeye çalışmak. Kötü birşey mi? Kişiye ve şartlara göre değişir. Eğer üstün hafızalı bir insan iseniz ve okuduğunuz hiç bir şeyi unutmuyorsanız yada zaman ve kaynaklarınız sınırsız da herşeyi öğrenebilecek kadar para ve zamanınız varsa, yada hayatta teknolojiden başka zaman ayırmak zorunda olduğunuz insanlar yoksa, yada çalıştığınız şirket size sınırsız zaman tanıyorsa, vs. tamam o zaman çokta kötü olmayabilir.

Eğer yukarıda saydıklarım sizin için geçerli değilse bazı şeyleri tam olarak anlamam için yıllarımı verdiğim tecrübeleri gelin beraber okuyalım. Çok kısaca kendimi anlatayım sonra konumuza devam edelim. Bu arada ben bu yazıda örnekler verirken genelde programlama dillerini kullandım ama siz aynı mantığı istediğiniz herhangi başka bir konuya uygulayabilirsiniz. Ben yıllardır yazılımcı olarak çalışıyorum ve teknoloji hususunda her gün yeri gelir saatlerimi harcayıp yeni şeyler öğrenmeye çalışan bir insanım. Yukarı saydığım çoğu şey benim içinde geçerli değil ama ben şimdiye kadar bu iştahımı başka zamanlardan fedakarlık yaparak tatmin etmeye çalıştım diyebilirim.

Peki neden şimdi böyle bir yazı yazıyorum? Çünkü kendime bazı sorular sormam gerektiğini hissetmeye başladım. Zamanım eksisi kadar çok değil, unutup gideceğim yada kullanmayacağım şeyler üzerinde zaman harcamak istemiyorum, ama öğrenmeyide asla bırakmam. Teknoloji çok hızlı, özelliklede yazılım. Her gün neredeyse bir library yada bir framework, bazende bir dil yada yeni versiyonlar gelip duruyor. Yetişmek imkansız olmaya başladı. Hoş önceden de yetişemiyordum ya.

Şöyle bir endişeye sahip olabilirsiniz: ”Ama öğrenmez isem iş başvurularında işime yararsa?”. Bir işe başvurmak zaten başvurdum çıktı şeklinde olmamalı. Başvurulacak işte istenilen neler varsa onlara bir süre önceden çalışılmalı ve hazırlık yapılıp gidilmeli. Zaten genelde bu hazırlık aşaması kendi alanınızdan farklı bir yere başvuruyorsanız geçerli. Aktif olarak kullandığınız teknolojileri kullanan bir şirkete başvuruyorsanız zaten çok sorun olmayacaktır.

Genelde en etkili öğrenme pratik yapmak ve onun hayatın bir parçası haline getirmek şeklinde gerçekleşir. Bir kaç günlük hadi şimdi bunu da öğreneyim şeklinde bir merakla başlanan heyecanlar genelde uzun soluklu olmayacağından büyük bir ihtimal herhangi bir projeninde içinde yer almayacak. Kendisini kullanmadığınız bu zaman diliminde ise size en nankör yüzünü gösterecek ve çok değil kısa bir zaman içinde öğrenmek için günlerinizi harcadığınız o bilgiler zihninizden kaybolup gidecek. Şöyle bir oturup düşünün hani o heyecanla ne güzel bir programlama dili diyerek günlerinizi verdiğiniz ve sonradan ne iş hayatınızda nede kişisel hayatınızda projelerinizde kullanmadığınız o programlama dilini şimdi ne kadar hatırlıyorsunuz? Python hakkında çok gaza gelip öğrendim. Sonra unuttum sonra yine gaza geldim ve en baştan günlerce zaman harcayarak yeniden öğrendim ve sonra çok kullanmadığımdan yeninde unuttum. Belki herhangi bir durumda yeniden öğrenmek zorunda kalsam daha hızlı öğreneceğim ama ne zaman ihtiyaç haline geleceği belli olmayan bir heyecan için bunca harcanan zaman israf değil midir? Bence evet!

Diğer bir durum ise düşüncelerinde ki bir projeyi yapmak istediğinde bence önce var olan bilgilerin ile bunu başarıp başaramayacağını sormak. Başaramıyorsan, güzel o zaman başarabileceğin araçları öğrenmeye başlayabilirsin. Bizler yazılımcıyız ama müşteriler için hangi dili kullandığının yada hani design pattern’ı nasıl uyguladığının hiç bir önemi yok. Dünyanın en kaliteli kodunu yazmış olsanda eğer ticari bir değeri yoksa emeğin boşuna diyerek tüm keyfimizi kaçırmak istemem ama hadi şöyle diyelim: bir sonraki projen için güzel bir tecrübe olacaktır. Var olan bilgilerin daha az zamanda daha hızlı şeyler başarmanı sağlayabilir. Yani demek istediğim şu projeyide şu dille yada şu farklı teknoloji ile yapayım derken hedefinin ciddi bir hedef olması daha güzel olabilir. Tabi burada tercihler duruma göre değişiyor.

Devamlı kullandığın programlama dilleri frameworklar vs. üzerine kendini geliştirmen daha mantıklı olabilir. Zaten (Burası çok önemli) var olan bilgilerinin üzerine aynı alt yapıya sahip başka bilgileri koymak çok daha kolaydır. Çünkü yeni öğrendiğin bilgilerin nereden geldiğine ve neyi hedef aldığı hakkında daha önceden bir temele sahipsindir. Bahsedileni daha iyi anlayabilir ve daha mantıklı çıkarımlarda bulunabilirsin. Hakkında çok az şeye sahip olduğun bir şey hakkında sıfırdan birşey öğrenmek bazen emelemek hızında olabilir ve belki senin bu kadar zaman lüksün olmayabilir.

Bunların dışında belki az bilinen bir şey ama genelde özgeçmişlerde bir ton dil, framework, vs. yazmak şunları biliyorum şöyle biliyorum böyle biliyorum demek zannedildiğinin aksine size zarar veriyor olabilir. Çünkü genelde onları okuyanların üzerinde kötü bir imaj bırakırlar. Bu kadar çok şey bildiğini iddia eden adam büyük bir ihtimal hepsinden azar azar biliyor demektir. Çünkü her bir teknoloji üzerine binlerce sayfa kitap yazılabilir ve sizin hepsini biliyorum demeniz kabul edelim inandırıcı değil. Yada hepsinden azar azar biliyorsunuzdur ve bu güzel bir şey değil. Çünkü bir şey üzerinden çok iyi olmak genelde daha tercih edilir. Çünkü o geliştirme ortamında karşınızda çıkan sorunları rahatlıkla aşabilmeniz gerekir. Ama herşeyden azcık bilen birisi için bu daha zor olsa gerek.

Çok uzatmadan gelmek istediğim noktaya geleyim. Yani ”Neyi ne kadar öğrenmek gerekli” sorusuna yani. Yeni çıkan teknolojileri öğrenmek çok güzel ve desteklediğim bir şey ama ne kadar ileriye gitmek gerekir?

Bu sorulardan önce şunu söylemekte yarar var. Konsept olarak karşınıza çıkan şeyleri güzelce öğrenmenizi tavsiye ederim. Mesela Nesneye Dayalı Programlama konseptini. Kalıtım, polymorphism, functional programming, vs. ama olay implementasyona gelince seçici davranmak daha mantıklı. Yani Java, C#, PHP daha nice diller işte Nesneye Dayalı Programlamanın implement edilmiş yada vücut bulmuş halleri. Böyle durumlarda Just-In-Time-Learning yani tam zamanında öğrenme yapın. Bu şu demek mesela Java öğrenmek istediğiniz zaman Java ile bir proje yapacaksanız o zaman öğrenin. Yada Java ile ciddi başka işler düşünüyorsanız o zaman Javayı ciddi manada öğrenin ve zaten o zaman derinlemesine öğrenebilirsiniz ki, en kaliteli öğrenme genelde öğrendiğiniz materyalleri kullandığınızda gerçekleşiyor. Hal böyle olunca hem öğrenecek hem geliştirecek ve geliştirirkende öğrenmeye devam edeceksiniz.

Peki yukarıda örnekten devamla eğer hayatımda genelde C# kullanıyorsam ve Java ile ilgili bir projeye yapmayacaksam hiç mi Java (yada bilmediğiniz herhangi başka bir dil yada konuyu) öğrenmeyeyim, ? Tabikide öğrenenin ama nankörleşmeyecek bilgi kadarını öğrenin.  Mesela Java öğrenirken kendinize sorun ”Acaba bu öğrendiğim kısım ileride aklımda kalır mı?” yada ”Bu öğrendiğim kısım günlük hayatımda bana faydası olur mu?” ve cevabınız hayır ise o zaman orada bırakın. Aksi taktirde kullanmadığınız bilgi nankör yüzünü gösterecek ve unutulacaktır. Genel olarak bir bilginiz olması gayet doğal ve güzel ama Java hakkında çok detay şeyleri öğrenmek dediğim gibi kullanmayı düşünmüyorsanız o zaman kaybı olması muhtemel.

Aslında yukarıda ki anlattıklarım sorduğumuz neyi ve ne kadar sorularına cevap vermiş oldu. Neyi: Öğrenmek istediğiniz herşeyi. Ne kadar: Kullanmadığınızda size nankörlük etmeyecek kadar. Herhalde bundan sonrasını bu tanıma neyin uyup uymadığını düşünmek ve bulmak ve ona göre davranmak bize kalıyor.

Uzun bir yazı oldu, vesselam…

Paylaş herkes duysun!Share on Google+Share on LinkedInTweet about this on TwitterShare on Facebook
October 27

Uzaklar Hiç Yakın Olmadı Bu Kadar

Düzen içinde yaşıyoruz. Kainatın her bir zerresi kocaman bir yapbozun birer parçası hükmünde. Bütünün güzelliği kendisini oluşturan bu küçük parçaların bir araya gelmesiyle görülebiliyor… Hayır! Vazgeçtim. Bu laf bile anlatmıyor hayran bırakan bu yapıyı. Her bir parça kendi içinde ayrı bir mükemmellik ve bütünlük içeriyor. Kısacası herşey kendisini oluşturan parçalarının güzelliklerini gösterdiği gibi kendisinin içinde olduğu ayrı bir bütünlüğünde güzelliğini ve muhteşemliğini haykırıyor aleme. Belki şimdi biraz daha fazla yaklaşmış olabiliriz anlatılamayana. Her bir zerre öyle özenle konmuşturki hem kral olmuştur hemde köle bu düzende.Hayran edici hesaplamaların bir parçasıyız ve insanın hayret edip iç aleminin buna kayıtsız kalması için ruhunu ve zihnini saran gaflet perdelerinin ummanlar kadar olması lazım. Sebeplerin acziyet dünyasında hayatta hiç görmeyeceğimiz milyar ışık yılı ötede bir yıldızın en ufak bir tozu “Ben yoksam sizde yoksunuz!” diye haykırıyor ötelerden. Bu sesi duyanların ruhlarında varlığa hayat üfleyen o kutsi Nefes beliriyor tüm ihtişamı ile. Hal dilleri daha bir gür bağırıyor susmak bilmeyen ağızlardan çıkan nidalardan.

Bu kadar grift herşey herşeyin içinde. Sadece varlıklar değil parçası bu kocaman yapbozun. Davranışlarda var. Yaptıklarımızın etrafında tavaf ediyor kainat tüm azameti ile. Birde bu acz içinde kainatı tavaf ettiren bir Halık-ı Mutlak kapıyor benlik kokan çeneleri. Bunca bulmacalar içinde insan soruyor kendine: Kainatta yaptığım ufak bir şey ya nice infiallere sebep olduysa?

Paylaş herkes duysun!Share on Google+Share on LinkedInTweet about this on TwitterShare on Facebook
October 25

S.O.L.I.D Üzerine Düşünceler (Part 2)

Daha önceden başladığım SOLID üzerine düşünceler ilgili serimin ikinci kısmına geldik. Eğer 1. kısmı okumadıysanız o zaman önce onu okumanızı tavsiye ederim. Bu makalede ise Open Closed Principle’i üzerinden devam edeceğiz. İdeal dünyada yazmış olduğumuz kodu asla değiştirmek zorunda kalmamış olmamız gerekiyor. Tabi böyle bir dünya yok ama en azından buna benzer bir dünyayı oluşturmak için bir prensip var ve buda Open Closed Principle. Kısacası öyle bir kod yazmalıyım ki daha önce yazdığım kodu değiştirmeden onun daha iyileştirebilmeliyim şeklinde tanımlayabiliriz. Daha resmi tabiri ile bir sınıf değişiklik için kapalı ama genişletilmek için açık olmalıdır. Tamam bu resmi olan tanımlama çok da bir mana ifade etmiyor gibi eğer daha önce Open/Closed Prensibi hakkında bir çalışmada bulunmadıysanız. Başka bir açıdan bakınca da yazmış olduğunuz sınıf yani classı asla değiştirmememilisiniz. Bir kere yazılınca artık o sınıf için değişim bitmiştir. Onun yerine o class’ı başka bir şekilde extend etmeniz yani genişletmeniz gerekiyor eğer gereksinimler değişirse. Open/Closed Prensibini uygulayabilmek için birden fazla yöntem var:

  1. Basit kalıtım. Yani bildiğimiz basit bir sınıfı kalıtım alarak onun methodlarını override etmek yada yeni methodlar eklemek şeklinde yapılan bir genişletme.
  2. abstract yada interface kullanarak kalıtım. Bu biraz daha göze ve mantığa hoş duran bir yaklaşım. Polymorphism burada çok yardımcı oluyor.
  3. Tasarım Desenleri yani Design Patterns kullanmak. Bunu çok yerde duymamış olabilirsiniz. Ama üzerinde düşününce OCP için gayet uygun patternlar var mesela Strategy Pattern, Decorator gibi. Bunlar var olan sınıfların içine dokunmadan yeni özellikler eklenmesini sağlıyorlar. Şahsen bunları diğer ikisine tercih ederdim. Çünkü compositon, inheritancedan daha güzel bir concept. Daha çok kod kullanabilirliği sağlıyor. Ama konumuz inheritance ve composition arasında ki farklar olmadığında es geçiyorum.

Şimdi basit bir koda bakalım:

Ben bu kodu C# ile yazdım ama prensip olarak başka dillerde kullanabilirsiniz. Şimdi PersonProcessor diye bir sınıfım var. Bu sınıfımın ne yaptığını açıklamay gerek yok ama bu sınıfı bir kez yazdıktan sonra artık bununla işim bitmiştir. GetAge method’u şuan database’den person nesnesini alıyor ama diyelim ki yeni bir gereksinim geldi ve bu sefer başka bir web server’dan person nesnesini almamız gerekti. Şimdi akla şu fikir gelebilir. Hemen GetAge method’unun içeriğini değiştiririm ve database’den almasını siler onun yerine web service’dan almasını sağlarım. Eğer böyle yaparsanız Open Closed Principle’ını (OCP) ihlal etmiş olursunuz. Bu arada bundan sonra kısaltması olan OCP’yi kullanacağım. Bu sorunu aşağıda tanımladığımz yöntemler ile aşmak mümkün.

Basit Kalıtım Yöntemi ile OCP

Başka bir sınıf oluşturursunuz ve bunun PersonProcessor ‘i extend etmesini sağlayabilir ve GetAge methodunu override edersiniz. Aşağıda ki kod buna bir örnektir:

Yukarıda görülen kod örneğini için çok açıklama yapmaya gerek yok diyerek geçiyorum. Burada değinmek istediğim iki şey var. Diyebilirsiniz ki MyClass içinde ki GetAge methodunu değiştirdin aslında. virtual eklemişsin ona. Doğru ve yaptığım normalde OCP ye göre yanlış. Ama dediğim gibi ben bu prensipleri önemli görsemde dogmatik olmak isteyen bir insan değilim. Pragmatik olarak yaklaşmak lazım. Eğer virtual kullanmasam override edemeyecektim ve virtual kullanmak bana zarar vermiyor ve hatta işime yarıyorsada kullanırım. Java gibi değil maalesef. Javada tüm methodlar default olarak virtual olduklarından dolayı virtual keyword’u kullanmaya gerek kalmadan override edebilirsiniz. Ama yok illada dogmatik yaklaşmak yani prensip içinde tanımlanan adımların ve kuralların dışına çıkmak istemiyorum diyorsanız o zaman da MyClass sınıfını tanımlarken hangi method’u virtual hangisini de sealed yapmak istediğinize karar vermek zorundasınız burası ayrı. Diğer bir mesele ise şimdi rahatlıkla MyClass sınıfını bozmadan onun yerine WebServerMyClass tipini kullanacak olmam. Ama açıkcası kabul edelim bu yöntem çok da güzel durmuyor. Zaten Meyer yöntemi deniyor yukarıda kullandığım kalıtım şekline. Meyer şahsın soy adı ve herhalde onun olduğu zamanlarda diller çok gelişmediğindenmidir nedir daha ilkel bir çözüm gibi duruyor. Ama prensip olarak bakarsak güzel bir prensip.

Abstract ve Interface Kullanarak Kalıtım

Şimdi başka yöntemlerde var bunu başarmak için. Burada dikkat edilmesi gereken şey prensibinin kendisi. Siz daha farklı kod yapıları ile bu prensibe uyuyorsanız illada yukarıda ki kod yapısını takip etmek zorunda değilsiniz. Mesela abstract bir sınıf kullanabilirsiniz, yada bir interface ve bunların kalıtım alınmalarını zorunlu hale getirebilirsiniz. Öyle olunca eğer sınıfınız istediğinizi karşılamaz ise hemen başka bir sınıf oluşturup yolunuza devam edebilirsiniz. Basit bir kod örneği olması açısında yukarıda ki örnekleri biraz değiştirdim:

Böyle olunca WebserverClass ‘ı değiştirmek yerine IMyClass ‘dan hemen inherit alıp başka bir sınıf oluşturabilir ve artık onu kullanabilirsiniz.

Tasarım Desenleri ile OCP

Hatta eğer yukarıda ki örneklerden farklı şekilde tasarım desenleri yani Design Pattern’ları da kullanabilirsiniz. Mesela Strategy ve Decorator vs. gibi pattern’lar var olan sınıfların içeriklerini değiştirmeden onları üzerinde bir genişletme yapmanızı sağlıyorlar. Bence bunlar daha mantıklı olabilir çoğu durum için. Aşağıda ki örnek kendisini açık bir şekilde açıklıyor onun için ben açıklamasına girmeyeceğim ama Strategy Pattern nasıl çalışıyor diye bakmak isterseniz eğer:

Yukarıda ki kod örneğini http://www.dofactory.com/net/strategy-design-pattern adresinden aldım. Bu pattern’i daha iyi anlamak istiyorsanız o adrese bakabilirsiniz.

Faydaları

Şimdi bunca bilgiden sonra OCP’nin ne yararı var diye sorabilirsiniz. Kısaca açıklarsak OCP ile var olan kodları değiştirirek başka bug’lara sebep olmayı önlemek istenmiş. En azından bu prensibin kurucu Bertrand Meyer bu şekilde düşünmüş. Tabi her hali ile mükemmel bir prensib mi bu tartışılabilinir ama sonuçta ortaya çıkış amacında faydalı bir hedefi var ve mümkün mertebe kullanılmasında bence gayet faydalı olacaktır. Ama şimdi Unit Test denilen testing framework’ları var. Yani test yazdıktan sonra var olan sınıflarınızı değiştirseniz bile bu testler sayesinde yeni bir hataya meydan verip vermediğiniz daha hızlı bir şekilde anlaşılabilinir çoğu zaman. Ama risk her zaman vardır unit test kullanıyor olsanız bile. Onun için prensib biraz daha eğer çalışıyorsa dokunma! mantığı üzerine kurulu.

Bu prensiblerin başka bir faydasıda insanı tembel bir programcı olmaktan kurtarıyor olmaları. Yazdıkları kod üzerinde düşünen bir programcı olmanız için bu tarz prensibler size yol gösterecektir. Çok uzun bir makale oldu şimdiden herkesten özür dilerim.

Bu arada makalede yanlışlıklar olmuş olabilir yada eksikler. Ara sıra gözüme çarpınca düzeltmeye çalışıyorum.

 

 

Paylaş herkes duysun!Share on Google+Share on LinkedInTweet about this on TwitterShare on Facebook