Nesneye Dayalı Dilde Nesneye Yönelik Olmayan Programlama [kapalı]


15

Son zamanlarda, Nesne Odaklı Programlama kullanarak fonksiyon toplama, çıkarma, çarpma, bölme ve güç ile bir hesap makinesi oluşturma görevi verildi . Bu görevi başarıyla tamamladım. Ancak daha sonra tüm programı Nesneye Yönelik teknik / yöntem kullanmadan yeniden programladım .

Kod uzunluğumun oldukça önemli ölçüde azaldığını ve oldukça anlaşılabilir olduğunu fark ettim. Yani burada sorum, Nesneye Dayalı Programlamayı ne zaman kullanmalıyım? Nesneye Dayalı Dilde Nesne Yönlendirmesi olmayan programlar oluşturmak uygun mudur? Lütfen bu konuda bana yardım et.

PS: Burada bana prosedürel programlama üzerinden Nesne Odaklı Programlamanın avantajlarını söylemiyorum.


12
Gerektiğinde farklı teknikler uygulamaktan kaçınmak için kesinlikle hiçbir neden yoktur. Programcı olarak, artıları ve eksileri duruma göre tartmanız gerekecektir. Sıklıkla kişisel stile iner.
ChaosPandion

3
Hiç bir sorun olmadı. Takım ve / veya başka bir mimari göz önüne alındığında, dil neredeyse her zaman reçete edilen bir araçtır.


8
Aynı programı OO teknikleri ile ve OO teknikleri olmadan uygulamak, bir şey öğrenmek için iyi bir egzersizdir, buradaki bazı insanların neden bunu reddettiğini veya sizi aşağıladığını anlayamıyorum. Ancak sorunuzdaki sorun, burada zaten bir kereden fazla, farklı şekillerde sorulmuş olması. İnkar olsak da sen olan prosedürel programlama üzerinde nesne yönelimli programlama esası hakkında sorular soruyorlardı. Ve C ++ bir OO dili değil, melez bir dildir.
Doc Brown

3
Girdiğiniz formülü görüntüleyen bir özellik ekleyin ve ardından bir kare kök işlevi ekleyin (Bunu önce yapmayın, hile olur.) Ve ne düşündüğünüzü bize bildirin.
JeffO

Yanıtlar:


25

C ++ sadece bir OO dili değil, çok paradigmalı bir dildir. Böylece OO programlama için veya ona karşı karar vermenizi ya da her ikisini karıştırmanızı sağlar. OO tekniklerini kullanmak, programınıza belirli bir boyut veya karmaşıklığa ulaştığında yararlanacağınız daha fazla yapı ekler. Bununla birlikte, bu ek yapı, ilave kod satırlarının fiyatı için gelir. Bu nedenle, "küçük" programlar için en iyi yol genellikle ilk önce OO olmayan bir tarzda uygulamak ve daha sonra program yıllar içinde büyümeye başladığında (muhtemelen egzersiz yapmayacak) daha fazla OO tekniği eklemektir. ", ancak birçok işletme programı için tipik bir yaşam döngüsüdür).

Zor kısmı, programınızın karmaşıklığının daha fazla yapı gerektiren boyuta ulaştığı noktayı kaçırmamaktır. Aksi takdirde büyük bir spagetti kodu yığını ile sonuçlanacaksınız.


Basit "egzersiz" programları gelişmeye başlarsa, en iyi yol programı daha sonra yeniden faktörleştirilebilecek şekilde uygulamaktır.
Paylaştığınız

@CarlSmith: kesinlikle. Ama cevabımı yazdığımda asıl sorunun puanlarına ve ölçeğine odaklanmaya çalıştım.
Doc Brown

10

Profesyonel programcılar OOP için olup olmadığına nasıl karar verir? Benim için gerçekten yararlı olurdu.

Benim için iki karar noktası var. İlk olarak, bazen başlangıçta açık olacaktır. Uygulama ayrıntılarında büyük ölçüde farklılık gösteren ortak yöntemleri paylaşan birçok benzer tür olacaktır. Örneğin, bir iş akışı sistemi kuruyordum ve keyfi görevleri yerine getirme yeteneğine ihtiyacım vardı. Görevi çalıştırmak için, her görevin miras aldığı bir temel sınıf, Execute()soyut bir yöntemle uyguladım . Devralma sınıfları uygulamayı sağladı, ancak iş akışı sistemi, ne tür bir görevin yürütülmekte olduğu hakkında hiçbir şey bilmeden yürütmeye başlayabilir.

Çoğu proje bu kadar net değil. İkinci karar noktası, projenin bir alt kümesinin if-then ifadeleri veya anahtar durum ifadeleri arasında büyük bir karışıklığa dönüştüğü ve özellikle if-then ifadelerinin düzgün çalışması için çok sayıda kurulum kodu gerektirdiği zamandır. Kendimi gerçekleştirmeye çalıştığım şeyin mantığını kaybetmeye başladığımı hissediyorum ve kod kırılgan hissetmeye başlıyor. Bu noktada, genellikle kodu belirli uygulamalarla temel sınıflara yeniden düzenleme zamanının bir işaretidir.

İşlevsel bir stilin aksine, nesne yönelimli bir stile geçmenin büyük bir kısmı if-then deyimlerini "bu eylemi çalıştır" deyimlerine dönüştürmektir. Büyük bir if-then deyimi kümesi yerine, kodun eylemini çalıştırmasını söylersiniz. Gerçekte hangi eylemin yürütüldüğü, sağladığınız uygulamaya bağlıdır.

Örneğin, C # tarzı sözde kodundaki işlevsel stil:

if ( action == "email" ) { 
    callEmailFunction(userInfo);
}
else if ( action == "sms" ) { 
    callSmsFunction(userInfo);
}
else if ( action == "web" ) { 
    endpoint = "http://127.0.0.1/confirm";
    confirmWeb(endpoint, userinfo);
} 
...

Ama belki bunu böyle bir şeye yeniden yazabilirsiniz:

interface IConfirmable {
    void Confirm(UserInfo userinfo);
}

public class ConfirmEmail : IConfirmable { 
    public void Confirm(UserInfo userinfo) {
        // do the appropriate thing to confirm via email
    }
}

public class ConfirmSms : IConfirmable { 
    public void Confirm(UserInfo userinfo) {
        // do the appropriate thing to confirm via email
    }
}

public class ConfirmWeb : IConfirmable { 
    // this is a constructor
    public ConfirmWeb(string endpoint) { 
        ...
    }

    public void Confirm(UserInfo userinfo) {
        // do the appropriate thing to confirm via web
    }
} 

Ve sonra kodun kendisi:

// An implementation that decides which implementation of the base class to use
// This replaces the if-then statements in the functional programmming.
IConfirmable confirmer = ConfirmerFactory.GetConfirmer();

// get the userinfo however you get it, 
// which would be the same way you get it in the functional example.
UserInfo userinfo = ...;

// perform the action.
confirmer.Confirm(userinfo);

Şimdi, if-then içinde çok az kod olduğunda, bu fayda elde etmek için çok fazla iş gibi görünüyor. Ve if-then'de çok az kod olduğunda, bu doğrudur: bu kod için anlaşılması daha zor bir iştir.

Ancak, nesneye yönelik stil, Confirm()gerçekleştirilmesi gereken yöntemden daha fazla eyleminiz olduğunda gerçekten parlar . Belki bir başlatma rutininiz, çalıştırılabilecek üç veya daha fazla eylem yönteminiz ve bir Cleanup()yönteminiz vardır. Temel algoritma, ortak bir temel sınıf uygulayan uygun nesnelere çağrı yapması dışında aynıdır. Artık nesneye yönelik stile gerçek bir fayda görmeye başlıyorsunuz: temel algoritmanın okunması, yolun her adımında if-then ifadelerini kontrol edip etmemekten çok daha kolay.


Ayrıntılı analiz için +1. :) Bu konuda birkaç düşüncem var.
FaizanRabbani

1
Bir kenara: Lütfen her cevaba "teşekkürler" yorumları göndermeyi bırakın. Tartışmaya değil, sadece sorulara ve cevaplara odaklanmayı tercih ediyoruz.
Philip Kendall

5
Bu örnek işlevsel olmaktan daha önemlidir.
OrangeDog


1
Sadece bir not, if / else veya switch ifadelerinin bir grubuna yaslandığınızda, her zaman bir tür arama tablosu düşünmek için bir seçenek. Yani yeniden yazmanın başka bir yolu var dict = new Dictionary<string,Action<UserInfo>{ { "email", callEmailFunction }, { "sms", callSmsFunction } }; dict[ action ]( userInfo );( satırlar statik olabilir, hata işleme atlandı)
stijn

3

Evet, projenizin kapsamı iyi biliniyorsa veya sınırlıysa, eski stil kodunu kullanmak tamamen normaldir. Programınızı veya projenizi genişletmeyi planlıyorsanız, OOP gitmenin bir yoludur, çünkü kodunuzu sorunsuz bir şekilde koruyabilir ve genişletebilirsiniz, diğer yandan planladıysanız ve programın genişletilebilirliğini asla planlamayacağınız sonucuna vardınız. OOP olmadan kod yazmanız yeterli olacaktır. OOP olmayan bir yaklaşım kullanırsanız, projenizi asla yükseltemeyeceğiniz anlamına gelmez, ancak o zaman yapmak sıkıcı bir şey olacaktır. OOP, konseptimizi gerçek hayattaki bir organizma gibi görselleştirmemize yardımcı olmaktır, çünkü bunları her şeyden daha iyi anlıyoruz.


1
"Bu, OOP olmayan bir yaklaşım kullanırsanız, projenizi asla yükseltemeyeceğiniz anlamına gelmez, ancak o zaman yapmak sıkıcı bir şey olacaktır.": Çoğu uzantı yeni sınıflar eklemeyi gerektirdiğinde OOP projenizi genişletmeye yardımcı olur (ör. bir GUI). Çoğu uzantı yeni işlemler eklemeyi içerdiğinde, prosedürel bir tasarım daha etkili olabilir.
Giorgio

1
Ne zamandan beri "nesne yönelimli değil" "eski stil" olarak adlandırılıyor?
DanielSank
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.