Thread overview
sınıflar
Jun 28, 2020
cos00kun
Jun 28, 2020
cos00kun
Jun 28, 2020
cos00kun
Jun 28, 2020
cos00kun
June 28, 2020

Bu aralar yapılar ve sınıflar üzerine biraz çalışmaya başladım. Şimdi belki biraz spesifik olabilecek bir soru sormak istiyorum. Burada mantığı anlamak bence bu konuların olanaklarını anlamaktan daha önemlidir. Diyelimki evdeki televizyon ve kumandası var. Şimdi haydi bunları programlamadaki sınıf veya yapılara geçirelim. Televizyon bileşenlerini kendime göre şu şekilde özetlersem;

Telezizyon, televizyon açma/kapama düğmesi, televizyon içindeki elektronik parçalar, fiş ,televizyon ekranı, elektrk, anten, kumanda, kumanda düğmeleri, kumanda içindeki elektronik parçalar, kumanda pili.

Bu durumda programlama açısından bunların hangilerini yapı,arayüz, sınıf yapmak doğrudur ???

Belki programcı arkadaşlar bir sürü program yazdıkları için sınıf ve yapı gibi olanakları elbette iyice kavramış olabilirler ancak benim gibi hobi olarak uğraşan ve az sayıda kısa programlar yazan birsinin anlaması açısından bu tür bir sorunun yerinde olacağını düşünüyorum.
teşekkürler...


***Ek: ayrıca hangileri işlevdir() demeyi unutmuşum :-p ***

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

June 28, 2020

aslında söylediklerinizi uygulayacak düzeyde olduğumu sanıyorum. İşlevler ve tekrarlı işlevlerden yapı/sınıf ihtiyacını da anlayabilecek düzeyde olduğumu hissediyorum ve bunlarla ilgili onlarca çalışma ve denemeler yapmaktayım hali hazırda. Sadece profesyonel programlamada sorduğum sorudaki örneği baz alırsak; Planlama ve dizayn aşamasında neler düşünülür onu öğrenmek istemiştim. yani televizyonun kumandası bir işlev mi olmalı veya alt sınıf mı veya ne ? gibi.. Veya kumanda düğmelerine işlev mi yüklemek mantıklı sonuçta iş yapacak veya kumanda düğmeleri bir alt sınıf olupta basılınca mı iş yapılacak gibi gibi gibi.. Yani bence bu planlama kısmı önemli gibi geldi bana :-)

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

June 28, 2020

öğrenmek istediklerimi biraz daha açıklayabilmek adına sizin örnekten eklenti yapayım; dediniz ki;

'..ekrandaki görsel pencere ve öğeler..... '

şimdi öğrenmek istediğim şey işte bu noktada devreye giriyor. Ekranı ara yüz yaptık bu tamam.. pencereleri sınıf / yapı yaptık ( ki bir dolu pencere yi tekrar yazmamak için yaptık soyut bir pencere sonra dilediğimiz kadar ürettik ve yeni özelliklerle sunduk arayüzümüze) peki bir pencceredeki menüler veya iconları ne yapmalı ki daha doğru olsun ? başka sınıf mı ? başka alt sınıf mı ? işlev mi ?

aslında biraz daha konuları ilerlettiğimde bu sorunun cevabını kendim bulabileceğimin farkındayım ama önceden bazı tahminleri duymak insana heves veriyor. :-D

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

June 28, 2020

Anladım Ali Hocam. İstediğim cevap konuşmaları üç aşağı beş yukarı bunlardı teşekkürler :-)

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

June 28, 2020

Karmaşık görünse de aslında çok kolay:

  • Öncelikle struct yaz.

class çok nadir durumlarda yararlı olabilir. Örneğin, farklı davranışları olan veya farklı özellikleri olan şeyleri bir araya getirmek istiyoruz. Bunun en güzel örneği, ekrandaki görsel pencereler: Bir sürü görsel öge var bunların hepsini 'ekrandakiler' diye bir topluluğa koymuşuz... Ekranda bir değişiklik olduğunda her birisine gidip 'öge.çiz()' diyoruz ve hepsi kendi işini hallediyor.

Başka bir örnek, diyelim kodu diske kaydetme işini soyutlayacak biçimde yazmışım: 'kaydedici.yazdır(birŞeyler)' diyorum ve o şeylerin diske nasıl kaydedileceklerini 'kaydedici' biliyor. O zaman 'kaydedici' yine bir class'tır ve kendi işini kendisi biliyordur.

Özetle, class'ın gerektiği durumlar nesne yönelimli programlamanın (OOP) yararlı olduğu durumlar. Bu gibi durumlarda da en çok karşılaşılan sıradüzen, en basitidir: İşlemlerin tanımlandığı bir 'interface' ve onu gerçekleştiren bir kaç tane alt sınıf. Klasik hayvan sıradüzeniyle:
'
Hayvan (interface)

Kedi Köpek ... (class)
'

  • Öncelikle serbest işlevler yaz.

Kodu geliştirdikçe eğer bir kaç tane serbest işlevin bir grup halinde aynı yapıyı kullandığını farkedersen o işlevleri o yapının üyeleri haline getir.

Eğer nesnelerin tutarlılığı önemliyse, o işlemleri de yapının üye işlevlerinde hallet. Örneğin, bir Kare yapısının kenar uzunluğu değiştiğinde 'alan' üyesinin değerinin de doğru oranda değişmesi gerektiğinde, bunların üye işlevlerde halledilmeleri kolay olur.

Bir çok kişi, bu gibi tasarım kararlarının sonradan değiştirilmesinin D'de kolay olduğunu düşünüyor. Ben de öyle yapıyorum. Özetle, öncelikle yapı ve serbest işlev; gerektikçe interface, class, ve üye işlev...

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

June 28, 2020

Televizyon kumandası gibi nesneler yapı (veya sınıf) nesneleri oluyor. Onu gerçekleştiren tür de yapı (veya sınıf) türü oluyor. Yani isimler yazdığımız türlerin nesneleri oluyor. Fiiller de işlev: yap(), et(), ekle(), yazdır(), sırala(), vs.

Bu gibi konular, deneyim gerektiriyor olabilir. :)

Yazmakta olduğum programlardan bir örnek vereyim. Doğrudan dosyalarla çalıştığından programda önce File nesneleri we doğrudan 'dosyam.rawWrite(/* ... */)' gibi işlevler kullanmıştım. Programlar karmaşıklaştıkça birim testleri (unittest) konusunda geri kaldığımızı farkettik. Birim testlerinin olabildiğince bağımsız olması istenir. Örneğin, test programının dosyalardan okuması veya dosyalara yazması istenmez. (Bunun nedenleri, testlerin dosya sistemini doldurmasının istenmemesi, veya yazma izni bulunmayan bir dosya sisteminde bile işlemelerinin gerekmesi, vs. düşünülebilir.)

O yüzden, programlarımın içinde File türüyle doğrudan etkileşmek yerine şöyle bir sıradüzen kurdum ve programları File ile değil, Depo ile etkileşecek biçimde değiştirdim:
'
Depo (interface)
/
FileDeposu BellekDeposu (class)
'
Programda File ile ne iş yapıyorsam, Depo arayüzünde de onları tanımladım: tell(), rawWrite(), seek(), vs. FileDeposu'nun bütün işlemleri kendi içinde barındırdığı bir File nesnesine aktarılıyor:

interface Depo {
 // ...
}

class FileDeposu : Depo { // <-- Çok şekillilik (polymorphism)
 File file;    // Gerçekleştirme

 auto seek(/* her ne parametre alıyorsa */) {
   return file.seek(/* parametreleri buraya aynen aktarıyoruz */);
 }
 // ...
}

BellekDeposu ise kendi bayt dizisini bir dosyaymış gibi kullanan çok basit bir sınıf oldu:

class BellekDeposu : Depo {
 ubyte[] baytlar;
 long konum;  // <-- Dosyanın neresinde olduğumuzu belirler

 auto seek(long konum) {
   this.konum = konum;
   // Daha sonraki okuma işlemlerinde örneğin konum'dan okuyacağız.
 }
}

(Basit dedim ama hatasız yazmak kolay olmayabilir. Ben biraz debelenmiştim. :) )

Depolama işini öyle soyutlayınca eskiden şöyle olan işlevim:

auto süperİşYap(File dosya, /* ... */) {
 // ...
}

şimdi şöyle oldu:

auto süperİşYap(Depo depo, /* ... */) {
 // ...
}

Gerçek programda FileDeposu oluşturup kullanıyorum:

 auto depo = new FileDeposu(dosyaİsmi);
 süperİşYap(depo, /* ... */);

birim testlerinde ise BellekDeposu oluşturup kullanıyorum:

 auto depo = new BellekDeposu(dosyaİsmi);
 süperİşYap(depo, /* ... */);

Söylemek istediğim, ben sonuca götüren en basit tasarım ne ise onu kullanıyorum; gerektikçe geliştiriyorum. (Tabii deneyimlerimizden de yararlanıyoruz ve açıkça aptallıklar yapmıyoruz. (Burada, birim testlerini baştan düşünmemiş olmam da hata kabul edilebilir.))

İnsan deneyim kazandıkça asıl önemli olanın sonuca gitmek ve iş bitirmek olduğunu anlıyor. Sonuçta işimiz mühendislik ("hendese" anlamında değil, "iş bitirici; çözüm bulucu" anlamında kullanıyorum.) Programı yazacağız ve işimize yarayacak... OOP'ler, pattern'lar, şu yöntemler, bu yöntemler, vs. işin zanaat yanı ama hiçbirisi mutlak değil. (Eskiden böyle düşünmüyordum; değiştim. :) )

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]