Yeni Javacının Sefaleti ya da Poverty of a Newbie Java Programmer
Yazı dizisi olan yayınlamaya başladığım Java Kodunuzun Nesne-Merkezli Olmadığının 10 İşareti başlıklı yazıların ilkinde aşırı statik metot kullanımını ele almıştım. Bu yazıda bir yerde şöyle dedim:
“… (statik metotların aşırı kullanımı) Programlamada yeni olan ya da tamamen prosedürel dünyaya alışkın programcıların Java kodu yazmaya başladıklarında sıklıkla karşılaştıkları bir durumdur. Problemli olan şey, statik kullanımının bulaşıcı ve yayılma eğiliminde olduğu gerçeğidir. Bir sınıf oluşturup üzerine statik metotlar ve alanlar koymaya başladığınızda kısa sürede kendinizi sadece statik metot yazarken bulacaksınız.”
Evet doğru, bir kere statik kullanmaya başladınız mı, her şeyin artık statik olarak devam etmesini engelleyemezsiniz. Statik kullanmada, bahsettiğim yazıda açıkladığım gibi bir problem yok, doğru yerde kullandığınız müddetçe.
Statik kullanımının nasıl bulaşıcı olduğunu göstermek için genelde Java’ya giriş eğitimlerinde kendi kendime konuşarak bir oyun oynarım, bir monolog yani. Bu oyundaki kişi yeni yetişmekte olan bir Javacıdır. Bu Javacı okulda almış olduğu örneğin “Java ile nesne-merkezli programlamaya giriş” isimli dersin hocasının verdiği program örneğinin benzerini eve gelip, kendisi yapmaya çalışmaktadır. Tek derdi bir değişkene bir değer atayıp sonra da onu ekrana basmaktır. Yani şöyle bir sınıf yazar:
public class MyFirstOOProgram { private int i = 5; public static void main(String[] args) { System.out.println(i); } }
Yukarıda da görüldüğü gibi yeni bir Javacı ya da nesne-merkezli programlamaya yeni başlamış olan arkadaşımızın yapmak istediği şey, bir nesne değişkeni tanımlayıp sonra da main metodunda onu print etmektir. Son derece masum bir istek 🙂 Evet “i”yi nesne değişkeni olarak tanımlıyor ama aslında derdi “nesne değişkeni” tanımlamak değil, çünkü daha nesnenin ne olduğunu bilmiyor, henüz kafasına oturmuş durumda değil. Derdi sadece bir değişken tanımlayıp onu print etmek. Aslında bu değişkeni main metotta tanımladığında problem olmuyor ama main metodunun dışında tanımladığında problem olduğunu görüyor. Derleyici “System.out.println(i);” satırında problem veriyor ve “Can not make a static reference to non-static variable i” gibi bir mesaj veriyor. Tabi sonuçta yeni Javacı için bu mesaj hiç bir anlam ifade etmiyor.
Yeni Javacımız bu problemin üstesinden gelmeye kararlı. Ve programcılığın gereği olarak başlıyor hatayı giderebilmek için programın orasıyla burasıyla oynamaya. Amaç bu “i” 5 olarak basılacak 🙂 Lafı uzatmayalım, pek çok denemeden sonra “i” değiskenini tanımladığı satıra “static” anahtar kelimesini koyduğunda yani satırı “private static int i = 5;” şekline getirdiğinde programı çalışıyor. Yani yeni Javacı olan arkadaşın ilk nesne-merkezli programı basit bir “static” eklemesiyle şu hale geldi ve çalıştı;
public class MyFirstOOProgram { private static int i = 5; public static void main(String[] args) { System.out.println(i); } }
Nesne-merkezli programlamayı bilmeyen, muhtemelen kendisine “Google programcısı” sıfatı daha uygun düşen arkadaşımız, “i” değişkenini instance için tanımlamak yerine class için tanımlar hale gelince problemini çözdü ama o böyle düşünmüyor. Eksik olan şeyin “static” olduğunu düşünüyor. Olması gereken, artık nesne-merkezli programlama yaptığının farkında olup, “i”nin bir nesne içın tanımladığı gerçeğininden hareketle print edilecek ‘i”nin basit bir değişken olmayıp, bir nesnenin parçası olduğunu ifade etmesiydi. Yani “i”yi statik yapmak yerine önce bir nesne tanımlayıp sonra sonra o nesnenin “i” değişkenini print etmeliydi:
public class MyFirstOOProgram { private int i = 5; public static void main(String[] args) { MyFirstOOProgram object = new MyFirstOOProgram(); System.out.println(object.i); } }
Nesne yaratıp o nesnenin üzerinden “i”ye erişmek yerine “i”yi statik yapınca probleminin çözüldüğünü düşündü ve bütün bu maskaralık da burada başladı zaten. Bakın devamında ne oluyor.
Arkadaşımız bir de metot yaratıp, onun içinde “i”yi print etmek ister. Ve bu amaçla programa bir “f()” metodu ekler:
public class MyFirstOOProgram { private static int i = 5; public static void main(String[] args) { System.out.println(i); f(); } public void f() { System.out.println(i); } }
Tabi derleyici bu sefer de main metodundaki “f();” satırında problem verir. Ve, arkadaşımız ne düşünür? “İster misin problem f() metodunun statik olmaması olsun?”. Ve “f()” metodunu da statik yapar:
public class MyFirstOOProgram { private static int i = 5; public static void main(String[] args) { System.out.println(i); f(); } public static void f() { System.out.println(i); } }
Bu kod da
5 5
basar ve görev tamamlanır. Kısa bir denemeden çıkan ana fikir şudur: Java’da her şeyi statik yaparsan her şey yolunda gider. Bir problem varsa bir yerleri statik yaparak çözebilirsin.” 🙂
Yukarıdaki koda artık ne eklerseniz statik olmak zorundadır. Herhangi bir yeni değişken class değişkeni, herhangi bir metot da sınıf metodu olmalıdır. İşte bu yüzden “static” anahtar kelimesi bulaşıcıdır.
Aslolan statik değil nesnedir. O yüzden “nesne-merkezli” programlama diyoruz.
Toplam görüntülenme sayısı: 1548
hakan
28 Mart 2014 @ 09:56
İtiraf etmeliyim ki ilk java öğrenmeye başladığım günlerde aynı sıkıntıları yaşadım. Ve baktığımda bir çok insan aynı sıkıntıları yaşıyor. Daha da kötüsü java .net gibi dilleri bildiğini zanneden bir çok yazılımcı aslında nesne – sınıf ayrımını nesne programlamanın inceliklerini bilmiyorlar. O zaman bu ortak bir sorun oluyor ya öğretme metodlarında sorun var veya oop programcılarının çoğunda bir sorun var 🙂 Bu durumda ne yapılabilir diye düşündüğümde benim düşünebildiğim çözüm daha fazla şekillerle görsel olarak anlatım yapılarak oop.nin öğretilmesi veya olayın alt yapısını kavratmak adına önce daha alt seviyeli dillerin öğretilmesi(okullara)… Daha iyi çözümü olan varsa bilmek isterim 🙂
Akin
28 Mart 2014 @ 10:20
Ben de kendi itirafimi yaptim zaten o yazida.
Bu sikintinin esas sorumlusu, toplum olarak saglikli bir programlama ve onun otesinde yazilim muhendisligi kulturune sahip olmamamiz. BT sektoru bunu kurgulamaya calismiyor, ee iyi pratiklerin olmadigi yerde tecrubeli ama en temel seyleri hala yanlis yapan insanlar uretiyoruz. Universitelerin durumu daha kotu. Gecen JUG’da yaptigim konusmada “uc bes private fielda sahip bir class ve set/get metotlariyla OOP olmaz” demistim. Bir arkadas konusma sonrasinda yanima geldi ve “okulda bize boyel ogretti hcoa” dedi. Ogretmistir, o da yanlis bildigini ogretiyor sonucta.
Cpzum icin dusunmek lazim. Ben egitimlerde ve danismanliklada, konusmalarimda vurguluyorum bu problemi. Ama bakin bizlerin yayazdikalri kitaplara, kitap yazanlarin kac tanesi OOPden ne kadar haberdarlar.
hakan
28 Mart 2014 @ 13:49
Evet kitaplar konusunu hiç düşünmemiştim. Şimdi hatırlıyorum da ilk defa yazılım geliştirmeye adım atmaya çalıştığım yıllarda staj yaptığım yerde bir program talep etmişlerdi ve programı vb ile yazmamı istiyorlardı. Konuyu çok çabuk öğrenip uygulama yazmam gerekiyordu. İnternet Türkiye’de henüz yaygınlaşmadığından orada yoktu. Tek kaynak elimdeki Türkçe kitaptı. 400 sayfalık kitabı okumuştum da neredeyse hiçbir şey öğrenememiştim. Şöyle düşündüğümü hatırlıyorum: “Bir konu hakkında (v.basic programlama) 400 küsür sayfa yazıpta hiçbir şey anlatamamak ayrı bir sanat olsa gerek” 🙂 Şimdi böyle bir kültürün java kitabı yazıp da java öğretmeye çalıştığını siz düşünün sonuç ne olur:)
Akin
28 Mart 2014 @ 14:55
Aynen oyle Hakan beycigim. Siz hani OOPyi gorsel oalrak desteklemek lazim dediniz ya, aklima su gelmisti:) Biizm Java kitaplarimiz o kadar gorsel ki icinde bilgi yok 🙂 Kitaplar sayfalarca Netbeans ya da Eclispe ekran goruntuleriyle dolu. Geri kalan yerlerde de bol miktarda kod var. Derdini anlatacak kisimlar yerine cogunlukla tum ornek kitapta basilmis durumda. Yazar hoca ise bu durumda da Java APIsi Turkce olarak konmus durumda.
hakan
31 Mart 2014 @ 09:26
Aslında ben görsel derken mesela nesneyi anlatırken belleğin içinde nasıl işlemler meydana geldiği temsilen stack ve heap kısımlarını çizecek şekilde görüntülerden bahsediyordum. Ama evet haklısınız Türkçe kitaplarda eclipse veya netbeans görüntülerini bol bol kullanarak safya dolduruyorlar..
Akin
31 Mart 2014 @ 14:03
Hakan hocam anladim, ben espri yaptim. Dediginizde haklisiniz cunku ben ozellikle nesnenin ne oldugunu, her nesnenin kendi memory spaceinde instance variablelara sahip oldugunu ve referanslarla nesneler arasidnaki iliskiyi hep temsili RAM uzerinden gosterir ve alengirli bir programda satir satir ilerledikce RAM’de (hatta Heap bile demem en basta) nasil olustuklarini tahtaya cizerek anlatirim. Bundan doalyi ileriki konualrda cok sikinti cekmem. Ornegin “hocam bir nesneyi bir metoda gecince yeni bir nesne mi yaratilir?” gibisinden sorular pek almam cunku zaten bunu halletmisizdir en baslarda.
Zor olan kitaplarda ya da sunumalrda vs. sekil cizmek, ben kendimden biliyorum.
Tesekkrue derim.
arc
27 Ağustos 2014 @ 09:21
Muhteşem olmuş. Aslında bunu okuyunca ‘kendi kendine öğrenme’ fikrinin yazılım işinde ciddi sorunlara yol açabileceğini düşündürdü. Tabii doğru kaynak kullanımıyla bunu aşmak mümkün.
Akin
27 Ağustos 2014 @ 11:02
Kendi kendine ogrenme fikri, aslidna en temel fikir. Zaten her şeyi isnan kendi kendine ögrenir. Öğrenmenin kendisi, çok ciddi bir içselleştirme, zihinsel sorgulama vb. tamamen objectif faaliyetel;ri gerektirir. Ama sizin dediginiz anliyorum ve katiliyorum da. Eger dis destek almazsaniz, bu dis destek ozellikle de bu isi bilen bir insan olmazsa, ogrenme sureciniz uzar. Ozellikle de isin basindaysaniz. Ileri safhalarda her zaman ogrenecek insan bulamazsiniz bu dogru ama baslarda muhakkak bilen insanla ilerlemek, usta-cirak iliskisini kurgulamak cok zaman kazandirir.
Tesekkur ederim.