• Forum vBulletin altyapısından Xenforo altyapısına geçirildi, bu sebeple eski şifreleriniz ile foruma giriş yapamayacaksınız, parolamı unuttum adımından mailiniz ile şifre sıfırlayarak giriş yapabilirsiniz.

    Üyeliklerinde geçerli bir mail adresi olmadığı için sıfırlama yapamayacak kullanıcılar forum kullanıcı adlarını ve yeni şifrelerini yazarak info@maxigame.org adresine şifre sıfırlamak istediklerine dair bir mail göndersinler şifrelerini sıfırlayıp mail adreslerini güncelleyeceğiz. Şifreniz sıfırlandıktan sonra foruma giriş yapıp tekrar istediğiniz gibi değiştirebilirsiniz.

C Sharp Programlama Rehberi

  • Konuyu başlatan Konuyu başlatan WeWereRock
  • Başlangıç tarihi Başlangıç tarihi

WeWereRock

Giriş

Geçen gece evdeki bilgisayarımda elektronik kitaplarımı karıştırırken rastlantı eseri gözüme takılan ve okuduğumda çok hoşuma giden bir rehber oldu. Rehberde C# ile nesne yönelimli yazılım geliştirirken hem tasarım hem de uygulama aşamasında bizlere çok yradımcı olacak tavsiyeler bulunmaktaydı. Bu altın değerindeki öğütleri tüm yazılımcı arkadaşlarla paylaşmak istedim. Hatta okurken kendi kendime yaptığım yorumları da Çevirmenin Notu şeklinde sizlere aktarmayı uygun gördüm.

Rehberde altmışın üzerinde madde olmakla birlikte bunların yarıya yakını sistem analizi ve tasarımı ile ilgilidir. Diğer kalan ksımı ise sistemin uygulanması(implementasyonu) konusunu kapsamaktadır.

Bu belge Thinking In C# (Larry O’Brien & Bruce Eckel ) kitabının sonundaki EK C’den Türkçe’ye çevrilmiştir.

Bu dökümanda; yazılım geliştirirken alt seviye tasarım ve kod yazma hususunda biz programcılara yardım edecek, rehber olacak, bir takım öneriler bulunmaktadır. Burda yazılanlar birer öneri olup birer kural olarak algılanmamalıdır. Dökümanda bahsedilenler önceki deneyimlere dayanarak ortaya çıkan parlak fikirler olarak da görülebilir.

1. Tasarımdaki zerafet her zaman kazandırır: Herhangi bir yazılım tasarımı sırasında dikkatli ve olabildiği kadar güzel tasarlamanız size ilk bakışta çok zaman kaybetttiğiniz hissini verebilir. Fakat tasarladığınız sistem veya modül çalışmaya başlayınca siz aslında çok şeyleri kazandığınızı farkedeceksiniz. Bunlardan bazılarını sayacak olursak; benzer bir durumda ya tasarımınızı aynen kullanabileceksiniz ya da çok az bir değişiklikle aynı tasarımı kullanmaya imkanınız olacaktır. Bu sayede belki tasarrufunuz saatleri, günleri ve hatta haftaları bulacaktır. İyi bir tasarım sistemi daha hızlı oluşturma ve hata ayıklamanın yannında daha kolay anlaşılmasına ve güncellenmesine de yardımcı olacaktır ki bu da vakit nakittir prensibi ile yakından ilgilidir. Bazen siz zarif bir iş yaparken kimileri sizin çok çalıştığınızı fakat verimli olmadığınız iddaa edebilir ki siz bunlara kulak asmayın. Diğerleri gibi hızlı iş çıkarmaya çalışmak aslında proje(ler)in daha yavaş ilerlesine yolaçacağına emin olabilirsiniz.

2. Önce çalışan sonra hızlı çalışanı yap: Eğer projenizde bir yer sistemin darboğazı ise ilk etapta onun doğru çalışanını yapın. Sistemdeki darboğaz ile ilgili kısmı olabildiği kadar kolay ve anlaşılır biçimde hazırlayın ve çalıştırın. Sonra performans testlerine tabi tutun. Eğer testlerde büyük bir hız sorunu varsa onu düzeltmeye kalkın. Çoğu zaman darboğazın sizin için aslında çok önemli bir problem olmadığını farkedeceksiniz. Sizin için önemli olan zamanını idareli, tasarruflu, kullanmaktır.

Çevirmenin Notu: Donanım güngeçtikçe artan bir hızla ucuzluyor. Ama yazılım projelerinde sizin vaktiniz çok kıymetli ve sınırlıdır. Ondan dolayıdır ki .NET’i ve RAD kullanmak giderek popüler oluyor.

3. “Parçala, böl ve yut” prensibini her zaman akılda tut: Eğer çözmeniz gereken sistem çok karmaşık ise; programda en temel görevi veya işlevi yapan parça nedir onu bulmaya çalışın. Bu temel görevi yapan sınıfı yazdıktan sonra, diğer yan parçaları ya temel parçaya birşeyler ekleyerek (türetme, veya inheritance ile) veya temel parçayı destekleyici parçalar (sınıflar) geliştirerek sistemin tamamını oluşturun.

4. Sınıf tasarımcısı ile sınıf kullanıcısını birbirinden ayırın: Sınıf tasarımcısının hazırladığı sınıfları kullanan programcılar genelde “müşteri” olarak andlandırılır. Müşteri programcılar sınıfların içinde neyin olup bittiğini bilmelerine gerek yoktur. Sınıf tasarımcısı, sınıf oluşturmada tam bir uzman olmalıdır ki en acemi programcı bile onun tasarladığı sınıfları kolaylıkla kullanabilmelidir. Sınıf kütüphanelerinin kullanım kolaylığı direk olarak sınıfın ne kadar taransparan yazıldığına dayanır.

Çevirmenin Notu: Sınıflar kullanırken onların içinde neyin olup bittiğinin bilinmesine ihtiyaç duyulmaması Nesne Yönelimli Programlamanın en temel prensiblerinden biri olan sarmalama (encapsulation) olarak adlandırlır.

5. Sınıfları oluşturuken isimlendirmeleri sınıf elemanlarının amaçlarını açıklaycı bir şekilde yapın: Bu sayede müşteri programcı için sınıf arayüzünün çok kolay anlaşılır olması hedefine ulaşabiliriz. Ayrıca gerekirse aynı işleri yapan farklı parametre alan metodlar içinde, metotlara aşırı yükleme (method overloading) kullanmanız çok uygun olacaktır.

Çevirmenin Notu: Metodlara aşırı yükleme ayın işi yapana fakat farklı parametre alan metodlara aynı isimleri verme kuralına dayanır. Mesela .NET snıf kütüphanesindeki Convert sınıfında tek bir ToInt32() metodu olmasına karşın, bu metota 18 defa, herbiri ayrı parametreler sayesinde, aşırı yüklenmiştir.

6. Sistem analiziniz ve tasarımınız, en az olarak, sistemdeki sınıfları, onların public arayüzlerini ve diğer sınıflarla ilşkilerini, özellikle temel sınıflarla üretmeli: Eğer sizin tasarım yönteminiz bundan daha fazlasını üretiyorsa; kendinize ekstraların programın yaşama süresi boyunca ne kadar değerleri olduğunu bir sorun. Genelde yazılım geliştirme takımındakiler kendilerinin verimliliğne pek bir katkısı olmayan parçaların bakımını yapmaya yanaşmazlar. Ayrıca bu gerçeği bir çok sistem tasarım metodolojisi gözardı ediyor maalesef.

7. Herşeyi otomatikleştirin: Sınıfın kodunu yazmadan önce, sınıfı tüm özellikleri ile test eden metodu yazın ve bunu sınıf içinde barındırın. Test kodunun çalışmasını makefile veya benzeri bir araçla otomatik hale getirin. Bu sayede sınıfın kodu içinde meydana gelen her türlü değişikliğitest kodu ile test edip muhtemel bir çok hatayı kolayca farkedip düzeltme imkanınız olacaktır. Her ne kadar derleyiciler ve yazılım geliştirme araçlarında inanılmayacak kadar çok kontrol özellkileri eklendiyse de ( tip kontrolü, hata ayıklama ve otomatik sözdizimi düzeltimi gibi) bunlar bir yere kadar kodun doğrulunu garanti edebiliyorlar. Eğer sağlam ve güvenilir bir sistem geliştirmek istiyorsak mümkün olduğu kadar dikkatli ve emin adımlarla ilerlemiyiz. Bunu sağlamak için iyi hazırlanmış test kodları ile sınıfın veya programın doğru çalıştığına emin olmalıyız.

Çevirmenin Notu: Window XP projesinde yazılan kodların en az %20 - %’nin test kodları olduğunu söylersem galiba profesyonellik ve başarı açısından test kodlarının sanırım ne kadar önemli olduğunun altını çizmiş olurum.

8. Bir sınıfın kodunu yazmadan önce onun test kodunu yazınız: Bu tür bir yaklaşımla sınıf tasarımınızın tam anlamıyla doğru ve eksiksiz olduğunu doğrulayabiliriz. Ek olarak, test kodunu yazarken sınıfla ilgili gözden kaçan ve gerekli özellikler ve kısıtlamaların da (genelde tasarım ve analizde farkedemediğiniz) gözünüze çarpmasını sağlar. Test kodunun başka bir yararı da, doğal olarak, sınıfın kullanıma ilişkin bir örnek teşkil etmesidir.

9. Tüm yazılım geliştirme problemleri ek bir konseptsel yön değiştirme ile daha da basit bir hale getirelebilir: Bu yazılım geliştirme mühendisliğinin en temel kurallarından biri olup nesne yönelimli programlanın da dayandığını prensiblerden biridir.

10. Yön değiştirme anlamlı olmalı: Burdaki anlamlı biçimde yön değiştirme en basit hali ile çok kullanılan kodları aynı metod içine koymak olacaktır.

11. Sınıfları olabildiğince küçük tasarlayın: Her bir sınıfın tek ve iyi belirlenmiş bir amacı olmalı. Eğer sınıf tasarımınız çok karmaşık ve uzun olduysa onu daha basit parçalara ayırmayı deneyin. Herhangi bir sınıfın ne kadar sade olduğunun göstergesi: onun eleman sayısı( metotler, üye değişkenleri vs.. ) ve üzerinde yapılan değişiklerin çok olmasıdır. Bu tür durumlarda sınıfı bölerken bir kaç ipucu olarak şunları kullanın:

Karmaşık switch yapısı: çok biçimliliği kullamayı deneyin.
Çok sayıda ve değişik türden işleri yapan metotlar: değişik sınıflar oluşturmayı deneyin.
Çok sayıda ve değişik türden sınıf üye değişkenleri: değişik sınıflar oluşturmayı deneyin. 12. Çok sayıda argüman alan metotlara dikkat edin: Metotları çağırmak karmaşık hale geldiği gibi, kod içinde metodu çağıran kısımları da okumak ve bakımını yazmak güçleşecektir. O zaman metoda argüman olarak nesne geçirmeyi deneyiniz.



Çevirmenin Notu: Hatta sırf bu amaçla sınıf veya yapı dahi oluşturabilirsiniz. Böylelikle sadeliği korumuş ve uzun vadede çok değişik kazanımlar elde ettiğinizi gözlemleyeceksiniz.

13. Kendinizi tekrarlamayın: Eğer türeyen sınıflardan bir çoğunda tekrarlanan kod parçası olduğunu gözlemlerseniz; o kod parçasını temel sınıfa koyunuz ve onu temel sınıftan çığırın. Bu sayede sadece kodun daha kısa olmasını sağlamazsınız, ayrıca tekrar eden ksımlardaki değişikler için tek bir örneğini değiştirmeniz yeterli olur. Bazen de böyle bir keşif sizin arayüzünüze değerli bir katkı da sağlacaktır.

Çevirmenin Notu: Bir çok nesne yönelimli programlama anlatan kaynaklarda geçen gemotrik şekillerle ilgili bir sınıf kütüphnesini tasarımından örnek verelim. Diyelim sizin kare, dikdörtgen ve eşkaner dörtgen isimli üç sınıfınız var. Bu üç sınıf için gerekli olan Çiz() metodunu herbirinde tekrar tekrar yazmaktansa, üçünün birlikte türediği dörtgen sınıfında yazmak ile daha az kod yazmış olursunuz. İleride ParaleKenar isimli bir sınıfa ihtiyacanız olunca; bu sınıf için tekrardan Çiz() metodunu yazmaktan kurtulursunuz. Hatta ilk versiyonda tek bir kalem (sabit kalınlık ve renk) ile çizim yaparken ilerki versiyonlarda farklı kalemler( kalınlık ve renk detaylarıyla) ile çizmek gibi özellikler ekleyince tüm dörtgenler için tekbir Çiz() metodu tanımlamanın size kazandıracağı zamanı ve sistemin sadeliğini düşünün bir!

14. switch ve çoklu if-else yapılarını gözlemleyin: Bunlar genelde tip-kontrollü kodlamanın göstergesidir. Yani, siz tip bilgisine göre hangi kodu çalıştıracağınıza karar veriyorsunuz(genelde tip bilgisi belli olmayabilir) demektir. Bu tür durumlarda switch ve ve if-else yapıları yerine kalıtım ve çok biçimliliği kullanın. Çok biçimli bir metot sizin yerinize tip kontrolünü yapar ve argüman tipine göre gerekli işleri yapar veya türeyen sınıflar vasıtası ile yaptırır. Yine kodunuz daha kolay okunabilir ve kolayca genişleyebilir bir hal alır.

Çevirmenin Notu: Yine gemoetrik şekiller ile ilgili sınıf kütüphanemizi düşünelim. Çiz() metodu 3 farklı parametreye bağımlı olarak işini yaptığını varsayalım. Bunlardan birincisi şekil, ikinicisi kalem ve üçüncüsü ise çizgi tipi (kesikli, noktalı, normal veya herhangi başka bir özel şekillerden biri..). Sizin de farkedeceğiniz gibi minumum olarak bizim şekil parametresidir. Diğerleri ise seçimliktir(opsiyonel).

Bu durumda tüm parametre kombinasyonlarında göre ya dört farklı metot yazmalıyız ki bunların isimleri farklı olmalıdır:

a. Çiz_Tam( şekil, kalem, çizgiTipi )
b. Çiz( şekil )
c. Çiz_Kalemli( şekil, kalem )
d. Çiz_Şekilli (şekil, ÇizgiTipi )

Ya da tek bir çiz metoduna kalem ve çizgiTipi nesnelerinin birini veya ikisini null olarak geçirmeli ve biraz karmaşık if-else ifadesi kullanmalıyız. Her iki durumda da tasarmızın karmaşıklığı ve kullanım zorluğu olduğu açıktır. Ama biz çok nesne yönelimli programlamanın en temel özelliklerinden biri olan biçimlilik(polymorphism) ile bu tür sorunları kolayca aşabiliriz. Metot isimleri aynı kalmak şartı ile parametre lsitelerini değiştirince Çiz metodunun 4 farklı hali şunlar olacaktır:

a. Çiz( şekil, kalem, çizgiTipi )
b. Çiz( şekil )
c. Çiz( şekil, kalem )
d. Çizi( şekil, ÇizgiTipi )

15. Tasarım aşamasında, değişebilir ve değişmeyen parçaları ayırmaya çalışın: Sistemde değişebilir elemanların olup olmadığını araştırın. Değişebilirleri ayrı sınıflar olarak tasarlayın ki ilerde bunlardaki değişmeler tüm sistem tasarımını veya önemli bir bölümünü değiştirmeye zorlamasın sizi.

16. Temel fonksiyonelitelikleri genişletmek için sınıf türetmeye başvurmayın: Eğer arayüz elemanlarından biri o sınıf için vazgeçilmez ise, o eleman ana sınıfta bulunmalıdır. Eğer yeni metotlar eklerken kalıtım kullanıyorsanız tasarımınızı bir kere daha gözden geçirmeyi aklınıza getirin.

17. Azar Azar: Herhangi bir sınıf için; olabildiğince az arayüz ile işe başlayın. Sınıfınız hali hazırdaki problemi çözecek kadar yetenekli olursa başarılır. Sınıf ile ilgi şu an ihtiyaç duyulmayan elemanları eklemeye kalkmayın. Sınıfınız kullanıldıkça onu genişletmenin yollarını, ihtiyaca binaen, zaten keşfedeceksiniz. Fakat bir sınıf herhangi başka bir kod tarafında kullanımda iken sınıfın yeteneklerini kısmaya kalkmak ölümcül bir hata olacaktır. Eğer yeni yeteneklere ihityacınız varsa bunları eklemeniz sadece sınıfın kodunu tekrar derlemek gerektirecektir. Eğer yeni ekledikleriniz arayüzde değişiklikler gerektiriyorsa, eski arayüzü genişletin sadece. Eski arayüzü değiştirmek size ciddi anlamda sorunlar yaratabilir. Ayrıca metot(lar)a yeni argüman ekleyeceğiniz durumlarda arayüzün eski halini koruması için çok biçimlilikten faydalanın. Yani metotlara aşırı yükleme yapın.

Çevirmenin Notu: Aynı örneğimize( geometrik şekiller) devam edecek olursak; ilk başta sizin ihtiyacınız olmadığı halde kalem ve çizgiTipi’ni belirteren Çiz() metotlarını yazmayın. Her ne kadar işimizin olabildiğince ince düşünmeye bizi alıştırsa bile? İlk hali ile Çiz( şekil ) olan metodumuzun sonradan Çiz( şekil, kalem ) versiyonuna ihtiyaç duyarsak Çiz( şekil ) metodunu koruyun. Zaten nesne yönelimli programlama yapıyoruz. Onun nimetlerinden biri olan çok biçimlilik bize büyük bir nimet olarak verilmiş.

18. Sınıflarınızın mantıklı olduğuna emin olmak için onları sesli biçimde okuyunuz: Özellikle ana ve türeyen sınıflar arasındaki “is-a” ve sınıf içindeki nesnelerin, sınıf ile olan “has-a“ilişkilerine dikkat ediniz.

Çevirmenin Notu: Kare bir Dikdörtgen sınıfından türemiştir. O zaman kare bir dikdörtgendir denilebilmeli ( “is-a” ilişkisi ). Öte yandan Dörtgen nesnemizin köşelerinin koordinatlarını tutmak için 4 tane noktamızın olduğunu varsayalım. Bu durumda her bir bir nokta nesesi Dörtgen sınıfının birer eleamanıdır( “has-a“ ilişkisi )

20. Kalıtım ve kompozisyon arasında karar vermek durumunda kalırsanız türeyen sınıftan temel sınıfa yukarı tür dönüşümüne ihtiyacınızın olup olmadığını kendinize sorunuz: Eğer böyle bir tür dönüşümüne gerek duymacaksanız kompozisyonu tercih edin. Bu sayede çok sayıda temel sınıf oluşmasını önlemiş olursunuz. Yok eğer kalıtım kullanırsanız; sınıfınızı kullananlar yukarı yönde tür dönüşünü yapmaları gerektiği hissine kapılabilirler.

21. Sınıf içindeki değerlerdeki değişmeler ve temel sınıflardaki metotların üstüne yazılması için üye değişkenlerini kullanarak sınıfınızın farklı işler yapmasını sağlayın: Eğer sınıfınızdaki bir takım metotlar aldıkları parametre veya üye değişkenlerinin değerlerine göre davranışlarını değiştiriyorlarsa; tekrar bir tasarım yaparak daha iyi sonuçlar elde edebilirsiniz. Yeni tasarımızda değişik sınıf davranışları için türeyen sınıflar ve metotların üstüne yazmayı kullanmanız gerekecektir.

22. Metotlara aşırı yüklemeyi kullanın: Bir metot kendisine geçirilen argümanların tiplerine bakarak çalışmasında koşullu ifadelere yer vermemeli. Bunun yerine iki veya daha fazla aşırı yüklenmiş metot hazırlamak daha uygun olacaktır.

23. Bazen basit bir kompozisyon işe yarar: Herhangi bir havayolu şirketindeki “yolcu konforu sistemi” birbirinden bağımsız elemanlar oluşacaktır: koltuk, klima, video vb.. Bunlarda her bir uçak için yüzlerce oluşturmak gerekecektir. Her bir elemanı private üye değişken yapıp, onların her bir işlemi içinde yeni arayüz oluşturmak çok mantıklımıdır? Onun yerine her bir elemanı public üye değişkeni olarak tanımlamak ve bu üye değişkenlerin metot ve özelliklerine ulaşmayı serbest bırakmak daha akılcı ve yeteri kadar güvenli bir çözüm olur. Öte yandan basit kompozisyonun her zaman doğru bir çözmü olmamasına rağmen bu durumda işe yarayacaktır.

Çevirmenin Notu: Sizin de bildiğiniz gibi herhangi bir dörtgeni belirmek için 4 tane noktaya ihtiyacımız olacaktır. Noktalarımızın isimleri n1, n2, n3 ve n4 olsun. Bunlardan herhangi birinin X ve Y koordinatlarını değiştirmek için Dörtgen sınıfımız içinde 4 veya daha fazla metot tanımlamaya ve Dörtgen sınıfının arayüzünü genişletmek ne kadar mantıklı sizce? Eğer biz noktalarımızı public tanımlarsak onların koordinatlarını değiştiren özelliğe veya metoduna Dörtgen nesnemizden kolayca ulaşabiliriz ve sadeliği koruyabiliriz. Örnek olarak:

Dörtgen dörtgenim = new Dörtgen();

dörtgenim.n1.X = 25;
dörtgenim.n1.Y = 43;

kullanımı daha hoş olmazmıydı ?

24. Sizin kodunuzu kullanacak ve bakımını yapacak programcıları düşünün: Sınıfınlarınızı olabildiğince açık, net ve temiz tasarlayın. İlerki muhtemel değişikleri düşünerek olabildiğince kolay değiştirebilir sınıflar tasarlayın.

Çevirmenin Notu: Bilmiyorum siziz başınıza hiç geldi mi? Maalesef çok defa başkasının hızlı ve kötü yazmış olduğu kodu değiştirmek zorunda kaldım. Hele birileri yüzlerce satırlık kodda tek satır yorum yazmadıysa ve değişken isimleri x1, z, t gibiyse çıldırmak elde değil. Aslında kendim bile 3 gün önce yazdığım kodda neler olup bittiğini anlamakta zorluk çekiyordum. Bu durumda bol bol yorum satırı yazmak, değişken, metot ve diğer sınıf üyelerinin isimleri amaçları doğrultusunda yazmak en mantıklısı. Yoksa değil başkası kendi kodunuzun bakımını yaparken bile kendinize hakaret etmemeniz kaçınılmazdır!

25. Çok büyük nesne sendromuna düşmeyin: “Bu ne demek şimdi?” gibi bir soru aklınıza gelecektir. Hemen açıklayalım isterseniz. Bu tür vakalarda genelde uzun süre prosedürel programlama yaptıktan sonra nesne yönelimli programlama yeni geçiş yapmışlarda görülür. Genelde belirtileri ise koca programı bir veya iki nesne ile halletmeye çalışmalarıdır. Programdaki nesneler programın kendisini değil sadece programdaki değişik ve küçük kavramları temsil etmelidir.

Çevirmenin Notu: Bu birazda müslüman mahallesinde salyangoz satmaya benziyor. Bir ipucu: sistem ile ilgili senaryoda isimler nesne olurken fiiller birer metot olurlar.

26. Eğer sınıf içinde herhangi bir şeyi çirkin veya hoş olayana bir şekilde yaptıysanız, en azından bu çirkinliği sınıf içinde belirtiniz.

Çevirmenin Notu: Yani delikanlı programcı ol canımı ye demek isteniyor burda...:-)

27. Nesneleriniz sadece bir takım verileri tutmak için kullanılmamalı: Sınıflarınızın üye değişkenleri gibi iyi tanımlanmış çeşitli davranışları(metotları) da bulunmalıdır. Genelde veri yapıları verileri tutmak için iyi bir yol olmalarına rağmen çok nadiren sadece verileri tutan sınıflar da tanımlamak ve kullanıma açmak zorunda kalabilirsiniz.

28. Önce Kompozisyonu deneyin: Eğer gerçekten gerekiyorsa kalıtımı kullanın. Kompozisyonun sizin ihtiyaçlarınızı karşıladığı durumlarda yine de kalıtım yapmayı seçerseniz gereksiz yere sistemi karmaşıklaştırmış olursunuz.

29. Kalıtım ve metotlara aşırı yükleme ile davranışlardaki çeşitliliği ve alanlar ile durumdaki değişkenlikleri ifade ediniz: En uçtaki örnek olarak değişlik nesnelerin renklerini belirtmek için o nesneleri Renk sınıfından türetme yerine her birinde renk isimli alanları kullanmak verilebilir.

30. Uyuşmazlıklara dikkat edin: Birbirinden farklı gibi duran iki farklı sınıfın aslında aynı temellere sahip olabilirler. Bu durumda birini diğerinden türetmeniz tavsiye edilebilir. Fakat, tam anlamıyla bir ana ve türeyen sınıf ilişkisi göremediyseniz ikisi için tek bir ana sınıf yapın ve bu ana sınıftan iki sınıfınız da türesin. Belki biraz fazla kod yazmış olacaksınız ama; hem kalıtımın faydalarından yararlanacaksınız hem de tasarımızla ilgili çok önemli bir noktayı keşfedeceksiniz.

31. Kalıtım sırasında sınırlandırmalara dikkat edin: En doğru tasarımda kalıtım ile yeni sınıfa bir takım yenilikler eklenir. Diğer taraftan kalıtımla oluşturulan sınıfa yeni bir şeyler eklenmemiş ve ana sınıftaki bazı yetenekler silinmiş veya kısıtlanmışsa bu tasarıma şüpheyle bakılır. Yalnız “kurallar kırılmak için yapılmıştır” düsturu bazı durumlarda geçerlidir. Eğer çok eski bir sınıf kütüphanesi üzerinde çalışıyorsanız ve hali hazırdaki sınıf hiyerarşisi sizin dilediğiniz gibi değilse türeyen bir sınıfı hiyerarşinin bir üst basamağına taşımanız da gerekiyorsa yapacak bir şey yok. Yani türettiğiniz bir sınıfın, temel sınıftan gelen bir takım özelliklerini kısıtlamanız gerekiyor...

32. Analizdeki paralelliklere dikkat edin: Projelerde çoğu zaman herşeyi tam olarak öğrenmeden işe koyulmamız gerekiyor. Bu tür durumlarda olası tüm ihtimalleri düşünüp onlara göre bir çok şey tasarlamak yerine ilerdeki değişmelere göre değişime açık bir sistem tasarlamak daha mantıklı. Ne de olsa neyin nasıl olacağını bilmek için neyin ne olduğunu bilmek gerekir. Nesne yönelimli metodoloji sayesinde ilerde sınıflarınızın değişmesi sistemin bütünlüğüne karşı büyük bir tehlike oluşturmayacaktır.

Çevirmenin Notu: Nesne yönelimli programlanın bu yanını seviyorum. Bir sınıfın arayüzünü değiştirmemek kaydı ile içinde ne yaparsan yap. Kimseyi rahatsız etmediğine de emin olabilirsin. Eğer projenin tamamı hakkında yeteri kadar bilgiye sahip değilsen ve bunu hemen elde etme şansın yoksa bildiğin kısımdan başla ve gerisini sonra yaparsın ama çok dikkatli olmak şartı ile...

33. Eğer güzel bir analiz, tasarım, ve implementasyon yaptığınıza kanaat getiriyorsanız; çalışmanızı adım adım inceleyiniz: İnceleme işlemi için sizin proje grubundan birinin kolundan tutun va masaya oturturun( bunun bir sanışman olmasına gerek yok! ). Onunla birlikte yaptığınız çalışmayı adım adım ve detaylı bir biçimde gözden geçirin. O kişi sizin göremediğiniz bir çok şeyi kolayca görecektir ki bu birlikte çalışmanın size ve patronunuza zaman ve para bakımından epey bir miktar tasarruf ettireceğine emin olabilirsiniz.

Çevirmenin Notu: Açıkcası kendimde bu yöntemi kullanıyorum. Kimse böyle bir yol izle demedi ama işi sağlam yapmaka adına başka bir proje grubundan birini çekiyorum yanıma; kardeş bak bakalım olmuş mu? Eksik gedik veya gereksiz nereleri var sence? İşin kötüsü her defasında kaydeğer değişiklikleri yapmak zorunda kalıyorum :-( . Ama projenin ilerleyen kısımlarında çok rahat ettiğimi de belirtmek isterim...

34. Microsoft’un kod yazarken kullandığı konvensiyoneli takip edin: Bu kodlama tekniğini sadece Microsoft değil sektörde önde gelen bir çok kurum kullanıyor. Eğer inatla kendi kodlama tekniğinizi( nesne isimleri ve değişik alışkanlıklar) kullanırsanız; başka bir C# uzmanının büyük ihitmalle sizin kodlarınızı okumakta zorlanacağının farkında olun. Öte yandan, hangi kodlama konvensiyonunu seçerseniz seçin projenin tamamnında aynı konvensiyonu kullanmaya dikkat edin. Yoksa tutarlılık adına pek başarılı olamazsınız.

35. Kodlama stiliniz ne olursa olsun, proje takımınızda hatta kurumsal çapta standartlarınızı belirleyin ve kullanın: Bu şekilde bir standartlaşmaya giderseniz; herhangi bir arkadaşınızın yazdığı kodu başka bir arkadaşınızın anlaması ve düzeltmesi işi daha adil bir biçimde sağlanır. Standartlaşma ile birlikte, başkasının kodu üzerinde çalışan programcı aşina olduğu stilden dolayı kodu daha kolay anlayacak ve müdahale edebilecektir.

36. Standart Büyük küçük harf kullanım kurllarına uyunuz: Sınıfların, private olmayan metot ve özellikerin ilk harflerini büyük yazınız. Private alanların, özelliklerin ve nesnelerin ilk harflerini küçük yazınız. Tüm alan, özellik, değişken, nesne, metot,arayüz vs. İsimleri arasına alt çizgi koymayın ve ilk kelimeden sonra gelen kelimelerin ilk harfleri büyük olsun. Örnek olarak:

BuBirSınıfIsmi
buBirPrivateMetotVeyaAlanİsmi

37. static final ve temel veritiplerinden olan sabitlerinizin tamamını büyük harfle yazınız: Böylelikle onların derleme zamanı sabitleri oldukları anlaşılsın.

38. private değişkenleriniz için öyle süslü isimler kullanmayın: Genelde değişkenin ilk bir kaç harfi veritipini belirtir. Sonra araya bir alt çizgi en son olarak da değişken ismi kullanılır. Macar notasyonu ( Hungarian ) bu konuda en kötü örnektir. Bu tür bir notasyon kullanmak; kodunuzu kafa karıştırıcı, okunması zor ve bakımını karmaşıklaştırmaktak için çok uygundur! Onun yerine sınıflarınızın ve isim alanlarınızın (namespace) ilgili faaliyet alanını belirlemesine izin verin.

Çevirmenin Notu: Eğer Visual Studio.NET kullanıyorsanız ve kullandığınız/hazırladığınız sınıf kütüphanesi düzgün bir xml dökumantasyonu uygulamışsa böyle karmaşık notasyonlara gerek yoktur.

39. Genel amaçlı metotlar yazıyorsanız tüm standart sınıflarda bulunan bileşenlerini üstüne yazınız: Bunlar temel sınıf olan object’in ToString(), GetHasCode(), Equeals() metotlarıdır. Bu sayede bu metotların sınıfınıza has versiyonları olurki böyle bir alışkanlık endinmek çok zaman işinizi kolaylaştıracaktır.

Çevirmenin Notu: Bu metotların gövdeleri şu şekildedir:
• public override string ToString()
{
}
• public override bool Equals(object obj)
{
}
• public override int GetHashCode()
{
}

40. Bazen bir sınıfın protected üyelerine ulaşmak için onu türetmek ihtiyacı duyabilirsiniz: Bu tür durumlarda çok sayıda ana veri tiplerinin olduğu hissine kapılabiliriz. Eğer türetilen sınıftan ana sınıfa bir tür dönüşümüne ihtiyacımız yoksa, önce ana sınıfa protected erişime izin veren bir sınıf türetin. Sonra bu türeyen sınıfıda türetmek yerine; başka bir sınıf içinde üye değişken olarak kullanın.

41. Eğer iki sınıf arasında bir takım fonksiyonellikler açısından ortaklık(lar) varsa( mesela container ve iterator) birini diğerinin içinde gömün: Bu durum sınıflar arasında ortaklıkları ima ettiği gibi tek bir sınıf ismi (dıştaki sınıf) içinde iki sınıfın da paketlenmesine olanak tanır.

42. İki veya daha fazla sınıfın bir çok özellikleri bakımından ortak olduğunu farkederseiniz onları tamamını birbiri içinde sınıflar olarak yapmaya çalışın: Bu daha az kod yazmanızı ve daha çabuk kodun bakımını yapmanıza olanak tanıyacağı gibi kodunuzun daha uyumlu ve tutarlı olmasını yardımcı olacaktır.

43. Sınıflarınız olgunlaşmadan onları optimize etmenin derdine düşmeyin: Bu biraz da çılgınlık olarak algılanabilir. Öncelikle sistemi oluşturmaya çalışın. Sistemi tam anlamıyla olgunlaştırmadan önce performans peşinde saatlerinizi harcamanızın pek bir anlamı yoktur. Sizin temel amacınız sağlamasını yaptığınız tutarlı bir sistem oluşturmaktır. Eğer gerek olursa kodun üzerinde daha verimli olması için oynayabilirsiniz.

44. Sınıflar içindeki değişkenlerin faaliyet alanlarını olabildiğince kısa tutmaya çalışın: Bu şekilde bir strateji ile hareket etmeniz sizin yanlış yerlerde yanlış nesneleri kullanmanızın ihtimalini düşürmekle birlikte hata ayıklamanızı kolaylaştıracaktır. Mesela, sizin container şeklinde bir nesneniz var ve bunun elemanlarını tektek dolaşan bir takım kodlarınız var diyelim. Metodun ilerleyen kısımlarında yine benzer bir kod parçasına ihtiyaç duydunuz. Üsteki container nesnesini alıp alta direk olarak kullanmanız nesnelerin sınırlarının karışmasından dolayı hataya yolaçabilir.

45. .NET Sınıf kütüphanesinin container(arraylist, stack, queue vs.. ) nesnelerini kullanınız: Bunları kullanmak sizin verimliliğinize büyük katkılar sağlayacaktır.

46. Bir yazılımın sağlam olması için tüm bileşenlerinin sağlam olması gerekir: Kodunuzun tutarlı olması için C#’ın size sunduğu tüm olanakları, erişim kontrolleri, istisnai durum yönetimi, tip kontrolü vs. Kullanın. Ancak bu şekilde projelerinizde emin adımlarla ilerleyebilirsiniz.

47.Derleme zamanı hatalarını çalışma zamanı hatarına tercih ediniz: Bir hatayı yakalarken mümkün olduğu kadar meydana geldiği kısma yakın bir yerde yakalayın. Hataları çözmeye çalışırken oluştukları yerlere yakın kısımlarda arayın. İstisnayi durumları, hata hakkında en çok bilgi verecek yerlerde yakalamaya gayret edin. Eğer hata mesajından bir ipucu yakalayamıyorsanız hatanın içindeki hatalara bakın.

Çevirmenin Notu: InnerExection’lara bakmanızı tavsiye ediyorlar.

48. Şişman metotlara dikkat edin: Metotlar kısa, öz ve anlamlı olmalıdır. Eğer bir metot çok uzun ve karmaşık ise onun bakımını yapmak güç olur ve büyük ihitmalle birden fazla işi tek başına yapıyordur. Bu tür metotların alt metotlara bölünmesi tavsiye edilidiği gibi siz onu ayrı bir sınıf olarak da implemente etmeyi bir düşünün. Ayrıca küçük metotlar sınıf içinde kodun tekrar kullanımına da (code reuse) imkan verecektir. Fakat, bazen uzun metotlar vardır ama onlar yine de tek bir iş yapmakla yükümlü olmalıdırlar.

49. Olabildiğince herşeyi gizli tutmaya çalışın: Bir sınıf kütüphanenizin belirli bir kısmının kodunu başkalarına açmanız tavsiye edilmez. Çünkü bu başkalarının kodunu baştan tasarlamasına ve yazmasına yolaçacaktır. Eğer sadece sınıfların arayüzlerini yayımlarsanız, başkalarının kodunu değiştirmeden kendi sınıflarınızın içsel çalışmasını zamanla geliştirirsiniz. Bu durumda sizin implementasyon değişikliklerinizden başkalarının etkilenmesini minimum derecede etkiler.

50. Hiç çekinmeden bol bol yorum satırları ve Xml yorum söz dizimini kullanınn: Fakat yorum satırlarınız sadece kodun ne yaptığını sözlü anlatan sıkıcı eklentiler olarak kod içinde barınmasınlar. Daha çok neyi yapmak istediğinizi ve önemli noktaları yorum olarak yazınız. Ayrıca sınıfınızın içindeki metotların amaçları .NET sınıf kütüphanesinde sık kullanılan metotlar ile örtüşüyor ise onların isimlerini .NET kütüphanesindeki isimlerden seçiniz.

Çevirmenin Notu: Eğer kendinize has bir container sınıfı geliştiriyorsanız ve eleman sayısını dönderen bir özelliğiniz varsa onun ismini Count seçmeniz. uygun olacaktır. Ya da ayın container nesnenizin içinde bir elemanın olup olmadığı dönderen metot ismini IsExist() yerine Contains() olarak verirseniz;sınıfınız kullananlar kolayca sizin sınıfınıza adapte olabilirler.

51. “Sihirli numaralar” kullanmayınız: Kod içinde bir takım sabit sayılar kullanmak gerekebilir. Kodun bakımını yaparken bunları değiştirmek gerektiğinde neyin ne olduğu açık olarak belirtilmemişse işler karışabilir. Mesela kod içinde geçen bir “100” sayısı ne acaba? Bir dizinin kapasitesi mi? Yoksa bambaşka bir şey mi? Onun yerine ismi açıklayıcı olan sabit(constant) tanımlamak daha mantıklıdır. Çünkü; sabitin ne işe yaradığını anlamak ve dolayısıyla bakımını yapmak çok kolaylaşır.

52. Yapılandırıcıları yazarken istisnai durumları düşünün: En mükemmel senaryoda bir yapılandırıcının istisnai durumlara açık olmaması dolayısıyla hata oluşma ihitimalinin sıfırlanmasıdır. Mükemmel bir senaryoda ise sınıfımızın tutarlı sınıflardan oluşması ve/veya türemesiyle istisnai durumlarda temizleme işlemine gerek kalmamasıdır. Yoksa temizliği yapılandırıcı içindeki finally deyimi kod bloğu içinde yapmak zorunda kalırsınız. En azından herhangi bir yapılandırıcıda istisnai durumda hatayı fırlatmalıyız ki; bu sınıfı oluşturan koda bildirmeliyiz. Öteki türlü sınıfımız oluşturmak için çağıran kod hiç bir şey olmamış gibi yolunda devam etmesin.

53. Eğer sınıfız herhangi bir temizle işlemi gerektiriyorsa, sınıfın bir örneği ile çalışma bitince/ömrü sonlanınca, sınıfınızın IDisposable arayüzünü implement etmelidir.

54. Eğer sabit sayıda nesneler alan bir container’ sahip olacaksanız onu dizi olarak hazırlayın: Özellikle bir metot bu şekilde bir container dönderecekse bu tür bir strateji izleyiniz. Böyle bir yaklaşım size bazı yararlar sağlayacaktır. Bunlardan başında .NET’in dizilerdeki derleme zamanı tip kontrolü ve bu diziyi kullanacak metodun dizinin elemanlarını uygun tür dönüşümüne tabi tutması gelir.

55. Soyut sınıflar( abstract classes )’dan önce arayüzleri(interfaces) kullanmayı düşünün: Eğer herhangi bir sınıf başka sınıflara temel/ana sınıf olabilecekse o sınıfı arayüz olarak implemente etmeye çalışın. Eğer metot tanımlarını ve değişkenlerinizi ilerde değiştirmek zorunda kalacağınıza inanıyorsanız bu sınıfı soyut sınıf olarak geliştirin. Bir arayüz sınıfları kullananlarla iletişim içindedir. İletişimin amacı ise sınıfı kullanan kodun ne yapmak istediğine odaklıdır. Arayüzü kullanan sınıf(lar) ise gerekli işlevlerin nasıl yapılacağı üzerine yoğunlaşırlar.

56. Yapılandırıcılar içinde sadece sınıfın örneğinin( nesnenin ) gerekli duruma getirme işini yapın: Özellikle yapılandırıcı içinde diğer metotları çağırmaktan çekinin. Çünkü sizin sınıfınızı kullanarak türetilen başka bir sınıf içinde sizin ilgili yapılandırıcınıza aşırı yükenilmiş olunabilir. Bu tür durumlar ise istenmeyen sonuçların doğmasına davetiye çıkarabilir. Küçük ve basit yapılandırıcılar istisnai durumların veya başka bir takım sorunların çıkmasını önleyecektir.

57. Yanlışlıkla aşırı yükleme yapılmasına engel olun: Eğer türeyen sınıfta ana sınıfın bir metodunun üstüne yazmaya çalışırken, ana sınıfın sanal metodunun( virtual ) ismini doğru yazmamışsanız, üstüne yazma yerine( override ) yeni bir metot üretmiş olabilirsiniz. Bu durumda kodunuz büyük ihtimal çalışacaktır. Ama doğru çalışmama ihtimali yüksektir!

Çevirmenin Notu: Aşağıdaki örneği bir inceleyiniz:
class YanlisUstuneYazmak
{
public static void Main()
{
YanlisUstuneYazmak yanlis = new YanlisUstuneYazmak();

Console.WriteLine( yanlis.ToString() );
Console.WriteLine( yanlis.ToString( DateTime.Now ) );
}

// Ana sınıfın (object) ToString() metodunun üstüne yazıyoruz:
public override string ToString()
{
return ("Ana sınıfın ToString() metodunun üstüne yazdık... ");
}

// Ana sınıfın (object) ToString() metodunun üstüne yazmak yerine yeni bir metot yazıyoruz:
public string ToString( DateTime zaman )
{
return ("Yanlışlıkla yeni metot yazdık" + zaman.ToString() );
}
}

58. Program kodları yazıldığından çok daha kısa sürede okunduğunu unutmayınız: Temiz bir kodun anlaşılması kolaydır. Fakat yorumlar, detaylı açıklamalar ve hatta örnekler kodunuzu mükemmelleştirir. Bu tür güzellikler size ve başkalarına kodunuz okurken veya anlamaya çalışırken çok yardımcı olacaktır. Eğer bu güzellikler yoksa kodunuzu anlayama çalışanın vay haline!
 
Geri
Üst