OOP vs prosedürel programlama - sayfa 23

 
Maxim Kuznetsov :

bir kağıda uzatılmış :-) holivarları kaçırdıklarını görüyorum, moderatörler alev temalarını sıktı ... ve sonra aniden OOP ve OOP olmayanlar

bu arada, @Peter Konow'un OOP kullandığını %99, sadece o bilmiyor :-) OOP mutlaka "sınıf ve şablon" değildir

ve bunun tersi de bu arada .. programdaki nesnelerin ve sınıfların varlığı OOP'yi göstermez

Bu çok ilginç bir fikir. Belki öyledir, ama şüphelenmiyorum. ))


Ve nasıl öğrenebilirsin?

 
Реter Konow :

Bu çok ilginç bir fikir. Belki öyledir, ama şüphelenmiyorum. ))


Ve nasıl öğrenebilirsin?

örneğin, OO, mesaj gönderme yoluyla (ve sınıf/şablon MQL'de olmayan bazı "güzellikler" ile) oldukça uygulanabilir.

Kodunuza bakmadım ve muhtemelen okuyamıyorum, ancak bir GUI kitaplığınız olduğu için, eminim kendi (en az bir) kuyruğu vardır ve birçok şey çarpıktır. olayların / gönderimlerin / durumların işlenmesi yoluyla. Ve sonunda bu çok "bükülme" sadece kalıtım/polimorfizmdir.

 
Dmitry Fedoseev :

Kirpi hakkında:

Açıklıkta bir kirpi var, poz veriyor, pazısını zorluyor: - Güçlüyüm, cesurum, hünerliyim, güçlüyüm, cesurum, hünerliyim...

Bir ayı geçiyordu - bir kez tekme attığında, kirpi ağacın arkasına uçtu, ayağa kalktı ve kendini silkti:

- Güçlüyüm, cesurum, çevikim... ama kolay...


Çocukluk arkadaşımın dediği gibi kirpi mağrur bir kuştur, tekmelemez, uçmaz))
 
Alexey Volchanskiy :

Georges, bugün bir kızla biraz yürüyüşe çıktım, sohbet ettim, biraz utangaç erkekleri hatırladım. Dürüst olmak gerekirse şaka yapmıyorum, herkesin farklı karakterleri ve farklı yetiştirilme tarzları var.

İçinde ... Ve Lyokha - bablar için ... Ve bu doğru. OOP'den çok daha ilginç.

Yani benim sorunum utangaçlık değil. Övünebileceğim tek şey sadece "iyi asılı bir dil". Benim sorunum yoksullukla vajinosentrizm. Gizliliğe ve sekse çok değer veririm. Yukarıda kendiniz yazmışsınız, "... Güzel kadınlar önümüzde belirirken erkeklerin nasıl saban sürebileceğine ikna olmuştum" diyorlar. İşte onlardan biri benim. Sadece burada kadınlar var - genç, güçlü ve zenginken sana ihtiyaçları var. Ve bir kadının atma fırsatı varsa - kesinlikle er ya da geç atacaktır. Hatta genç, güçlü ve zengin. Ben de evi olmayan zavallı yaşlı bir engelliyim. Yani şansım sıfır... Karımın gitmesine şaşırmadım bile. Sadece boşanmayı umursamıyorsun. Ama eşim gidemezken bu şartları oluşturamadığım için son derece üzgünüm.

 

OOP'ye gelince...

Peter Konow'unki gibi bir hafızam olsaydı - belki de OOP'nin gerekli olmadığını kabul ederdim, tüm bu arayüzleri, sınıfları, nesneleri, kalıtım sistemini ve sanal işlevleri çitle çevirmenin amacı nedir ...

Aleksey doğru bir şekilde söyledi - işlemci herhangi bir nesne hakkında hiçbir şey bilmiyor ... Hatta fonksiyonlar hakkında hiçbir şey bilmiyor. Bu, herhangi bir görevin yalnızca OOP olmadan değil, herhangi bir işlev olmadan bile, yalnızca dönüş adreslerini hatırlayarak ve IP kaydı (veya modern işlemcilerde herhangi bir talimat işaretçisi) aracılığıyla kontrol aktarımı gerçekleştirerek çözülebileceğini kanıtlar.

Kodunu gösterene kadar Peter Konow'un pozisyonunu anlamadım. Şimdi - her şey açık ve eğer tüm bunları hafızada tutmayı başarırsanız ve uzun süre zahmet olmazsa - onunla hemfikir olabilirim - o zaman onun yazdığı şekilde yazmanın daha mantıklı olduğundan şüpheleniyorum. Ayrıca - Bu durumda OOP, gerçekten de "arabadaki beşinci tekerlek" olur.

Ama kişisel olarak, işin karmaşıklığının çoğunun hafızamdan uçup gitmesi gibi bir sorunum var. Diyelim ki G_CORE çok boyutlu dizisindeki her bir dizinin neden sorumlu olduğunu unutup duruyorum; yukarıdaki snippet'teki her koşulda - her seferinde ciddi olarak düşüneceğim - neyi tanımlıyor. Uzun koşulları ayrıştırmak - benim için de stresli olacak.

Ayrıca, bazen kendim anlamak zor olan böyle bir kod yazarım. İşte aynı şekilde boğulacağım " yanlış " kodumun bir parçası (yukarıda alıntıladım):

 virtual bool IsTPCInUnloss() const { if (GetTPCStopLoss() <= 0 || GetTPCStopLoss() == EMPTY_VALUE ) return ( false ); if (GetTPCType() == POSITION_TYPE_BUY ) { if (GetTPCStopLoss() >= GetTPCOpenPrice()) return ( true ); } else { if (GetTPCStopLoss() <= GetTPCOpenPrice()) return ( true ); }; return ( false ); };

Bu, verilen bileşenin başabaş olup olmadığını belirleyen ticaret bileşeni arabirimi CTradePosComponentI'nin bir işlevidir.

Bu kodun "yanlışlığı", okunabilirliğin kompaktlık ve görünürlük için feda edilmesidir. Fonksiyon arayüze dahil olduğu için, mümkünse tüm arayüzün tek bir ekranda görünür ve görünür olması benim için gerekliydi. Sadece hangi fırsatları sağladığını hatırlamamak için, tüm bu fırsatlar hemen görünür olsun. Her şeyi hatırlasaydım, işlevi bir dizgeye "çekmek" gerekli olmazdı. Eh, fonksiyon bir düzine çizgiye yayılmıştı - tamam... Ancak benim için önemli olan tüm fonksiyonların arayüze yan yana oturması ve herkesin görünür olmasıydı. Böylece arayüze bir bakış, sağladığı işlevler kümesinin hemen anlaşılmasını sağlar. Bu nedenle - işlevi uzun bir satırda yazmak gerekliydi. Ancak, bunu anlamak tamamen gerçekçi değildir.

Başlangıçta kodu yazarken - bu işlevi ilk önce tamamen farklı bir şekilde yazdım. Açıkça ve yorumlarla. Anlayabilmek için.

Bunun gibi:

 virtual bool IsTPCInUnloss() const 
{ 
     // Отсеем вариант, когда СЛ отсутствует
     if (GetTPCStopLoss() <= 0 || GetTPCStopLoss() == EMPTY_VALUE )
         return ( false );

     //  Проверим тип торговой компоненты
     if (GetTPCType() == POSITION_TYPE_BUY )
        { 
         // Торговая компонента - лонг
         if (GetTPCStopLoss() >= GetTPCOpenPrice())
             return ( true );
        }
     else
        { 
         // Торговая компонента - шорт
         if (GetTPCStopLoss() <= GetTPCOpenPrice())
             return ( true ); 
        }; 

     return ( false ); 
};

Ve ancak tüm bunlar kontrol edilip hata ayıklandıktan sonra - kod yorumlardan temizlendi ve "bir satıra uzatıldı".

Ama bu bir istisna. Bunu çok nadiren, burada, "görünürlüğün" önemli olduğu özel durumlarda yapıyorum. Diğer tüm durumlarda, kodu hem "geniş olarak" hem de girintilerle ve "orada ne var" sorusuyla en ufak bir aksamanın ortaya çıkabileceği herhangi bir yerde yorumlarla yazarım.

Sadece farklı - nerede, neye ve neye hizmet ettiğini çok çabuk unutuyorum

 
Maxim Kuznetsov :

örneğin, OO, mesaj gönderme yoluyla (ve sınıf/şablon MQL'de olmayan bazı "güzellikler" ile) oldukça uygulanabilir.

Kodunuza bakmadım ve muhtemelen okuyamıyorum, ancak bir GUI kitaplığınız olduğu için, eminim kendi (en az bir) kuyruğu vardır ve birçok şey çarpıktır. olayların / gönderimlerin / durumların işlenmesi yoluyla. Ve sonunda bu çok "bükülme" sadece kalıtım/polimorfizmdir.

Madem "A" dedim, o zaman "B" demem gerekiyor.) Teknolojimi daha spesifik olarak anlatacağım.

Belirli bir problem tipini çözmeye yarayan işlevselliği büyük bloklarda birleştirerek, fonksiyonlar arasında kurulması gereken ilişkilerin sayısını azaltıyorum. Bunun artıları ve eksileri var.

İlk önce profesyoneller hakkında:

OOP'de, çok sayıda fonksiyona bölünmüş bir mekanizma, sınıflar ve yapılar arasında iletişim için birçok nesnenin oluşturulmasını gerektirir. Aynı zamanda, her fonksiyonun prototipi, fonksiyonun çevreleyen kodla ilişkilendirildiği çok sayıda resmi parametre ile büyümüştür. Bu mekanizmanın geliştirme sürecinde mekanizmanın parçaları arasındaki bağlantıların artması nedeniyle kodun iç yapısı tam olarak daha karmaşık hale gelir.

Benim teknolojimde, fonksiyonlar ve bloklar arasındaki iletişim, her yere yerleştirilen global değişkenlerin kullanımıyla tamamen basitleştirilmiştir. Fonksiyonların parametre geçmesine gerek yoktur, çünkü onları global seviyede hemen görürler.

Global değişkenlerin değerleri , imleci "takip eden" "Nesne Odağı" bloğu tarafından belirlenir. İmlecin mevcut koordinatlarına göre blok, farenin hangi nesne üzerinde olduğunu belirler ve tüm elemanların, nesnelerin ve pencerelerin tüm özelliklerinin kaydedildiği çekirdeğe (G_CORE) erişir. Çekirdekten, blok, imlecin altındaki nesnenin tüm ana özelliklerinin mevcut değerlerini alır ve bunları global değişkenlere yerleştirir. İmleç nesnelerin üzerinde hareket ederse, global değişkenler bu blokta yeniden tanımlanır ve her zaman odağı olan nesneye karşılık gelir.

Ardından, OnChartEvent() işlevi, imlecin altındaki öğenin durumlarını değiştirmesi gereken grafik olaylarını yakalar. Bu olaylarda, durum kontrol bloğu (OnChartEvent()'in kendisine entegre edilmiştir) hangi pencerenin, öğenin ve nesnenin odakta olduğunu ve hangi özelliklere sahip olduğunu hemen görür. Bu bloğa herhangi bir şey iletmenize gerek yok, çünkü ihtiyacınız olan her şey global değişkenlerde zaten odakta. Görevi, G_CORE çekirdeğindeki nesne özelliklerinin değerlerini değiştirmek ve öğeyi yeniden çizmektir. Değerleri değiştirir ve Draw bloğunu çağırır.

Çizim bloğuna sadece üç parametrenin iletilmesi gerekir - pencere, tuval ve eleman. Öğeyi yeniden çizerek mevcut duruma uygun bir görünüm verir. Tüm çizim bloğu yardımcı işlevleri, odakta global değişkenleri de kullanır. Örneğin, yukarıdaki "Detail Color()" işlevi "PENCERE", "OBJECT", "OBJECT_CATEGORY" vb. kullanır... Bütün bunlar çok uygundur.


Şimdi eksileri için:

Kuşkusuz büyük bloklar ve nesne odağı, kodun bölümleri arasında iletişim kurmayı kolaylaştırır, ancak tam olarak blokların büyük olması nedeniyle çalışmak zorlaşır. Burada Rus dili ve sözdiziminin tamamen basitleştirilmesi bana yardımcı oluyor çünkü OOP kullanmıyorum.

Zamanla, bloklar artık değiştirilmeleri gerekmeyecek duruma gelir ve büyümeyi durdurur. Yavaş yavaş, yapıları tamamen ezberlenir ve onlarla çalışmak maksimuma basitleştirilir.

Tabii ki, blokların taşlanması oldukça uzun ve kasvetli bir şeydir, ancak bu herhangi bir mekanizmanın hata ayıklamasıdır.

 
George Merts :

OOP'ye gelince...

Peter Konow'unki gibi bir hafızam olsaydı - belki de OOP'nin gerekli olmadığını kabul ederdim, tüm bu arayüzleri, sınıfları, nesneleri, kalıtım sistemini ve sanal işlevleri çitle çevirmenin amacı nedir ...

Aleksey doğru bir şekilde söyledi - işlemci herhangi bir nesne hakkında hiçbir şey bilmiyor ... Hatta fonksiyonlar hakkında hiçbir şey bilmiyor. Bu, herhangi bir görevin yalnızca OOP olmadan değil, herhangi bir işlev olmadan bile, yalnızca dönüş adreslerini hatırlayarak ve IP kaydı (veya modern işlemcilerde herhangi bir talimat işaretçisi) aracılığıyla kontrol aktarımı gerçekleştirerek çözülebileceğini kanıtlar.

Kodunu gösterene kadar Peter Konow'un pozisyonunu anlamadım. Şimdi - her şey açık ve eğer tüm bunları hafızada tutmayı başarırsanız ve uzun süre zahmet olmazsa - onunla hemfikir olabilirim - o zaman onun yazdığı şekilde yazmanın daha mantıklı olduğundan şüpheleniyorum. Ayrıca - Bu durumda OOP, gerçekten de "arabadaki beşinci tekerlek" olur.

Ama kişisel olarak, işin karmaşıklığının çoğunun hafızamdan uçup gitmesi gibi bir sorunum var. Diyelim ki G_CORE çok boyutlu dizisindeki her bir dizinin neden sorumlu olduğunu unutup duruyorum; Yukarıdaki parçadaki her koşulda - her seferinde ciddi olarak düşüneceğim - neyi belirlediğini. Uzun koşulları ayrıştırmak - benim için de stresli olacak.

Ayrıca, bazen kendim anlaması zor olan böyle bir kod yazarım. İşte aynı şekilde boğulacağım " yanlış " kodumun bir parçası (yukarıda alıntıladım):

Bu, verilen bileşenin başabaş olup olmadığını belirleyen ticaret bileşeni arabirimi CTradePosComponentI'nin bir işlevidir.

Bu kodun "yanlışlığı", burada kompaktlık ve görünürlük için okunabilirliğin feda edilmesidir. Fonksiyon arayüze dahil olduğu için, mümkünse tüm arayüzün tek bir ekranda görünür ve görünür olması benim için gerekliydi. Sadece hangi fırsatları sağladığını hatırlamamak için, tüm bu fırsatlar hemen görünür olsun. Her şeyi hatırlasaydım, işlevi bir dizgeye "çekmek" gerekli olmazdı. Eh, fonksiyon bir düzine çizgiye yayılmıştı - tamam... Ancak benim için önemli olan tüm fonksiyonların arayüze yan yana oturması ve herkesin görünür olmasıydı. Böylece arayüze bir bakış, sağladığı işlevler kümesinin hemen anlaşılmasını sağlar. Bu nedenle - işlevi uzun bir satırda yazmak gerekliydi. Ancak, bunu anlamak tamamen gerçekçi değildir.

Başlangıçta kodu yazarken - bu işlevi ilk önce tamamen farklı bir şekilde yazdım. Açıkça ve yorumlarla. Anlayabilmek için.

Bunun gibi:

Ve ancak tüm bunlar kontrol edilip hata ayıklandıktan sonra - kod yorumlardan temizlendi ve "bir satıra uzatıldı".

Ama bu bir istisna. Bunu çok nadiren, burada, "görünürlüğün" önemli olduğu özel durumlarda yapıyorum. Diğer tüm durumlarda, kodu hem "geniş olarak" hem de girintilerle ve "orada ne var" sorusuyla en ufak bir aksamanın ortaya çıkabileceği herhangi bir yerde yorumlarla yazarım.

Sadece farklı - nerede, neye ve neye hizmet ettiğini çok çabuk unutuyorum

Görevlerimiz çok farklı, bu yüzden kararlarınız hakkında bir şey söylemek benim için zor. Bu sadece benim anım mı emin değilim, belki başka bir şey vardır. Kendi kodunuzun anlamlılığı şüphesiz onun ezberlenmesini geliştirir. Kodunuzun daha az anlamlı olduğunu söylemiyorum. Sorunlarınızı çözmeye nasıl yaklaşacağımı bilmiyorum. Belki de yaklaşımınız doğrudur. Yargılamayı düşünmüyorum. Şahsen, bu kod tarzını kabul etmek benim için çok zor.

Muhtemelen bir alışkanlık meselesi.))

 
Реter Konow :

Görevlerimiz çok farklı, bu yüzden kararlarınız hakkında bir şey söylemek benim için zor. Bu sadece benim anım mı emin değilim, belki başka bir şey vardır. Kendi kodunuzun anlamlılığı şüphesiz onun ezberlenmesini geliştirir. Kodunuzun daha az anlamlı olduğunu söylemiyorum. Sorunlarınızı çözmeye nasıl yaklaşacağımı bilmiyorum. Belki de yaklaşımınız doğrudur. Yargılamayı düşünmüyorum. Şahsen, bu kod tarzını kabul etmek benim için çok zor.

Muhtemelen bir alışkanlık meselesidir.


Tamamen anlamsız konuşma: Kodu "iyi" veya "kötü" olarak sınıflandırmak için bir kriter yoktur . Bu yüzden OOP hakkında net değil.

Benim için böyle bir kriter, kodun GÖRÜNÜRLÜĞÜ'dür; bu, yazarın veya üçüncü şahıs bir kişinin oldukça uzun bir süre sonra kodu okuyabileceği ve değişiklik için kullanabileceği, arayacağı gerçeğinde kendini gösterir. hatalar .....


Yukarıda, Fedoseev OOP anahtarını değiştirdi. Benim için başarısız olabilecek bu özel örnek, OOP'nin kısırlığının kanıtıdır: 100 konumlu bir anahtarla açıklayıcı bir kod bir satırla değiştirilir. Bu çizgiyi anlamak için bir yere tırmanmanız gerekiyor. Benim için bu kabul edilebilir bir şey değil.

George Merts'in üstündeki ikinci örnek

Hata ayıklamadan sonra açıklayıcı kod açıklayıcı olmayan kodla değiştirildiğinde. Ölçütüme göre, yüksek kaliteli kod (okunması kolay) benim için geçersiz bir kodla değiştirildi.


Bu nedenle, tüm OOP destekçilerine bir sorum var: OOP kullanıldığında program daha görsel hale geliyor mu ve Fedoseev'in anahtar üzerinde verdiği örnek başarısız mı yoksa tam tersi, Fedoseev'in örneği OOP ve OOP'yi çok doğru bir şekilde karakterize ediyor ve OOP neredeyse her zaman yol açıyor görünürlük kaybı?

 
СанСаныч Фоменко :

1. Tamamen anlamsız konuşma: Kodu "iyi" veya "kötü" olarak sınıflandırmanın bir kriteri yoktur . Bu yüzden OOP hakkında net değil.

Benim için böyle bir kriter, kodun GÖRÜNÜRLÜĞÜ'dür; bu, yazarın veya üçüncü şahıs bir kişinin oldukça uzun bir süre sonra kodu okuyabileceği ve değişiklik için kullanabileceği, arayacağı gerçeğinde kendini gösterir. hatalar .....


2. Yukarıda, Fedoseev OOP anahtarını değiştirdi. Benim için başarısız olabilecek bu özel örnek, OOP'nin kötülüğünün kanıtıdır: 100 konumlu bir anahtarla açıklayıcı bir kod bir satırla değiştirilir. Bu çizgiyi anlamak için bir yere tırmanmanız gerekiyor. Benim için bu kabul edilebilir bir şey değil.

George Merts'in üstündeki ikinci örnek

Hata ayıklamadan sonra açıklayıcı kod açıklayıcı olmayan kodla değiştirildiğinde. Ölçütüme göre, yüksek kaliteli kod (okunması kolay) benim için geçersiz bir kodla değiştirildi.


3. Bu nedenle, tüm OOP destekçilerine bir sorum var: OOP kullanıldığında program daha görsel hale geliyor mu ve Fedoseev'in anahtar üzerinde verdiği örnek başarısız mı yoksa tam tersi, Fedoseev'in örneği OOP ve OOP'yi neredeyse her zaman çok doğru bir şekilde karakterize ediyor görüş kaybına yol açar mı?


1. Bir kriter var. Ana kriter işin hızıdır.

Kodun görselleştirilmesi yanlış kriterdir. Kod ona bakmak için değil, çalışmasını sağlamak için yazılmıştır.

2. Açıkçası, bazılarının henüz kodu işlevlerle yapılandırmaya başlamadığı ortaya çıktı. Yani konunuza girmediniz, “bir sayfanın koduna karşı işlevlerle yapılandırılmış kod” konusuna girmeniz gerekiyor.

Ayrıca örnek, yapılandırma ve görünürlük/görünmezlik ile ilgili değil, balast kodu bölümlerinin ortadan kaldırılması ile ilgiliydi.

3. Bunu yapabilir misin ... mühendislik grafikleri? Veya tanımlayıcı geometri. Orada her şey açık.

 
Dmitry Fedoseev :

Kodun görselleştirilmesi yanlış kriterdir. Kod, ona bakmak için değil, çalışmasını sağlamak için yazılmıştır.

Ben katılmıyorum.

Görsel kod çok önemli bir şeydir çünkü görsel kodun bakımı ve değiştirilmesi çok daha kolaydır.

Her şey doğru söyleniyor - düzgün bir işlev yazdım ve sonra aslında onu "karıştırdım", onu sevgilim ve anlaşılmaz hale getirdim. Zorunlu bir karardı. Bu durumda, tüm sınıfın görünürlüğü benim için daha önemliydi. Bir, oldukça önemsiz işlevin görünürlüğü - feda ettim. Elbette bu fonksiyonun gövdesini bir .mq5 dosyasına taşımak mümkün olabilir ama bence arayüzler iki dosyaya bölünmemeli, .mqh başlık dosyasında tam olarak açıklanmalıdır.

Hız da akılda tutulması gereken bir şey ama "ne pahasına olursa olsun hız"ın hedeflenmesi gerektiğini düşünmüyorum. Makul yeterlilik olmalıdır.