Bir programı birden çok sınıfa bölmek neden iyidir? [kapalı]


62

Hala lisede öğrenciyim (10. sınıfa giriyorum) ve henüz okulda gerçek bir bilgisayar kursuna katılmamıştım. Şimdiye kadar yaptığım her şey kitaplardan geçiyor. Bu kitaplar bana kalıtım gibi kavramlar öğretti, ancak bir programı birden fazla sınıfa bölmek nasıl yardımcı olur? Kitaplar bana hiç söylemedi.

Bunu temelde yeni bir proje yüzünden soruyorum. Bazılarının söylediği gibi bir Flash oyunu gibi bir arcade video oyunu (bir Flash oyununun ne olduğu hakkında hiçbir fikrim olmasa da). Mesele şu ki, sadece bir sınıf. Sadece bir sınıfla (ancak arada sırada biraz gecikme) mükemmel çalışıyor. Bu yüzden, sadece bunu birden fazla sınıfa bölmenin nasıl yardımcı olacağını soruyorum.

Bu proje Java'daydı ve kayıt için çalışan tek kişi benim.


1
Yazılımın her bir parçasını daha basit hale getirmek için! infoq.com/presentations/Simple-Made-Easy-QCon-London-2012
TehShrike

49
Kitaplarını okurken, bölümlere ve bölümlere ayrıldılar mı? Bir programı işleri düzenlemek için sınıflara ayırırız, tıpkı kitapların metni düzenlemek için bölümlere ayırdığı gibi.
riwalk

12
Romalılar derdi ki: böl ve et.
Giorgio

7
@ Giorgio: ya da İngilizce, çünkü Latince artık kullanılmıyor: Divide And Conquer .
Matthieu M.

40
10. sınıfta olduğunuzu ve zekice bir soru oluşturabildiğinizi ve iyi cevaplar için gerekli tüm detayları sağladığınızı, bağlam sağladığınızı ve göreceli deneyiminizi ve soruyu neden sorduğunuza ilişkin temel bilgileri sağladığınızı düşünün; şu anda birlikte çalıştığım birçok kişiden daha kalifiye ...
CaffGeek

Yanıtlar:


71

En basit cevap, her şeyi bir sınıfa koyarsanız, yeni kod yazarken her şey için endişelenmeniz gerekir. Bu küçük projeler için işe yarayabilir, ancak büyük uygulamalar için (yüz binlerce satırdan bahsediyoruz), bu hızla imkansız hale geliyor.

Bu sorunu çözmek için, işlevsellik parçalarını kendi sınıflarına böldünüz ve tüm mantığı kapsıyorsunuz. O zaman sınıf üzerinde çalışmak istediğinizde, kodda olup bitenler hakkında düşünmeniz gerekmez. Sadece bu küçük kod parçasına odaklanabilirsiniz. Bu verimli çalışmak için paha biçilmezdir, ancak çok büyük uygulamalar üzerinde çalışmadan anlaşılması zordur.

Elbette, kodunuzu daha küçük parçalara bölmenin sayısız başka faydası var: kod daha fazla korunabilir, daha test edilebilir, daha fazla yeniden kullanılabilir, vb. bir anda düşünmek gerek.


7
Programlamadaki birçok kavram / fikir (OO prensipleri, dağıtılmış kaynak kontrolü, kodlama standartları) yalnızca bir takımdaki göreceli olarak büyük projeler üzerinde çalışırken anlamlıdır. Neden böyle projeler üzerinde çalıştığınızı anlayacaksınız.
joshin4colours

40
Bu dikkati çekiyor sadece çoklu sınıflara projeyi kesiliyor / dosyaları çok yardımcı olmuyor. Asıl önemli olan kendi kendine yeten sınıflara sahip olmaktır, bu nedenle bir sınıfı değiştirmek program hakkında başka bir şey bilmeyi gerektirmez (ve sınıfı kullanmak, nasıl uygulandığı hakkında herhangi bir bilgi gerektirmez). Bunu ortaya koyarım çünkü sıklıkla çok fazla sınıf içeren bir kod görüyorum ama gerçek bir kapsülleme yok. Kapsülleme önemli bir parçasıdır - nasıl başardığınız sadece detaylardır.
Monica

2
Bazı anahtar kelimeler "birleştirme" veya "ayrılma", "kapsülleme", "bilgi gizleme" olacaktır.
marktani

@BrendanLong, katılıyorum ve ayrıca kapsüllemenin neredeyse imkansız olduğunu da ekleyeceğim. Elbette ayrı programlar yazmıyorsanız ... AMA birbirlerine bağlı olmayan, ancak yalnızca ortak bağımlılıkları olan birçok bölüm var
Jo So

29

En basit cevap "İşlerin organize edilmesine yardımcı olur" olabilir. Başka bir şey yapmazsanız, onu bir defterdeki bölümlerle karşılaştırabilirsiniz - burada "UI ile ilgili her şeyi" ve "orada oyunla ilgili her şeyi" varsa, basit bir işlemdir.

Daha karmaşık cevap, çalışmayı bölüşmenin sadece uygun değil, aynı zamanda karmaşıklığı yönetmek için çok önemli (ve "karmaşıklığı yönetmek", programlama konusunda oyunun adıdır). Sınıflar veya diğer modül türleri, "endişeleri ayırmanıza" izin verir. Yalnızca "UI ile ilgili şeyleri" nerede arayacağınızı bilmekle kalmazsınız, ancak UI'de bir değişiklik yapmak istiyorsanız, tek bir yerde yapabileceğinizden ve bunu yapmanız gerekmediğinden emin olabilirsiniz. Endişeli "şimdi, yazı tipimi Comic Sans olarak ayarladığım tek yer burası mı?" Ve bir değişiklik yapabilir ve bu değişimin etkisinin yalnızca (küçük) kapsamın ne olduğuna uygun olduğunu bilirsiniz. Her şey tek bir sınıf veya modülde ise, aslında her şey küreseldir,

Bir tür yazılım modülü olarak belirli sınıflar söz konusu olduğunda, bir sınıfla ilişkilendirilen çok sayıda davranış vardır ve nesne yönelimli paradigmadaki çoğu geliştirici, ilgili gruplarla ilişkili anlamlı adlara sahip olmayı çok yararlı bulmaktadır. birlikte çalışır. Yani muhtemelen bir UIsınıfınız olmazdı , muhtemelen bir Buttonsınıfınız olurdu . Nesne yönelimli sınıf tasarımı ile ilgili bir bilgi ve teknik bütünü vardır ve ana akım programlamada büyük sistemleri organize etmenin en yaygın yolu budur.


12

Bu iyi bir soru! Basit ve iyi sordu. Peki ... cevabı, bilgisayar bilimi okuyan ve muhtemelen derin OO'da bilmeyen ve muhtemelen deneyim üzerinde çalışamayan bir öğrencinin anlaması kolay değildir.

Bu yüzden, bir senaryoyu tanımlayarak ve çok sınıflı yazılımın monolitik yazılımdan (sadece bir sınıf tarafından yapılan) nasıl daha iyi olduğunu hayal etmenizi sağlayarak cevap verebilirim:

  • Okunabilirlik : Birkaç küçük ve organize dosyadan çok, 10000 satır içeren bir dosyaya göz atmak ve kod yazmak çok daha zordur.
  • Yeniden kullanılabilirlik : Tek bir sınıf yazarsanız, kod çoğaltmada kayma yapabilirsiniz . Bu, daha fazla kod satırı ve muhtemelen daha fazla hata anlamına gelir (!)
  • Test edilebilirlik : Tek bir işlevselliği test etmeye ne dersiniz? Bir mantık fonksiyonelliğini bir sınıfta ayırırsanız, yaşamınız daha kolay olacaktır.
  • Kod bakımı : Bir hatayı düzeltebilir veya tek bir yerde çoklayıcı sınıflarla işlevselliğini artırabilirsiniz: Güzel küçük sınıflar.
  • Proje yapısı : oooooh, sadece bir kaynak dosya ile çirkin bir projenin ortaya çıkacağını hayal edebiliyor musunuz?

Cevabını beğendim ve sadece bazı değişiklikler yaptım (yine de meslektaşları tarafından gözden geçirilmesi gerekiyor). Kaçırdığım bir nokta, SVN / GIT gibi Yazılım versiyonlama sistemlerinde değişikliklerin daha kolay tespit edilmesidir. Bir proje için paralel olarak birden fazla programlayıcı ile çalışmak daha kolaydır.
Martin Thoma

Endişelerin ayrılmasının, bütünleşmenin ve ayrılmanın OOP disiplininden çok daha yüksek bir kapsamda bir kavram olduğunu söyleyebilirim. Zorunlu, mantıklı ve işlevsel programlayıcıların tümü, yüksek uyum ve düşük bağlantı için gayret gösterir.
sara,

8

Burada çok iyi cevaplar var ve kesinlikle onlarla aynı fikirdeyim, ama daha fazla bahsetmeye değer bir şey olduğunu hissediyorum.

Şu anda dediğiniz gibi, projeniz üzerinde yalnız çalışıyorsunuz. Ancak, gelecekte takım ortamında çalışmanız gereken zamanlar olacaktır. Bu zamanlarda, işi bölüşeceksiniz (büyük olasılıkla proje oldukça büyük olacaktır). Sonuç olarak, birkaç (gerçekten iki ana sanırım ) farklı seçenek var. Bir dosyanın birden fazla kopyasına sahip olabilir ve dosyanın ayrı "parçaları" üzerinde çalışabilir ve daha sonra bunları kopyalayıp yapıştır ile "birleştir" ve sonra parçalarınızın birlikte çalışabilmesi için değiştirebilir veya bu "parçaları" tamamen bölebilirsiniz kolayca farklı sınıflara girip bu dersleri nasıl yazacağınızı tartışın ve bu bilgiyi devam etmek için kullanın.

Ayrı parçaları bir araya getirmek için yine de çalışmaya ihtiyaç duyacaksınız, ancak bakımı çok daha kolay olacak. Çünkü x dosyası y kodu içerir ve değiştirmeniz gereken kod budur. Bu, diğer cevapların çoğunun bahsettiği organizasyon olayına giriyor.

Bir programın başında. Giorgio'dan bağlantı


1
+1: Takım çalışması da önemli! Örneğin bkz paulgraham.com/head.html ve başlıkla paragraf "kod aynı parça düzenleme birden fazla kişi yok mu.".
Giorgio

@Giorgio Ben sadece içinden süzülmüş, ama harika bir kaynak gibi görünüyor! Bunu cevabımı ekleyeceğim, çünkü bazı insanlar yorumlar bölümünde görünmeyebilir. Kesinlikle biraz daha ayrıntılı bir okuma yapacağım.
Sephallia

Bu aynı zamanda revizyon kontrolü için de geçerlidir - ayrı dosyalar üzerinde çalışmak daha az çatışma ve birleşme anlamına gelir.
Monica

7

Aslında yaptığınız şey, yeniden icra usulü programlamadır. Bu şekilde yazılım yazmak oldukça mümkündür ve derleyici muhtemelen umursamaz. Uzun yıllar boyunca, bilgisayarlar daha hızlı hale gelene ve araçlar iyileşene kadar bu işler yapıldı.

Bu, kodunuzu farklı mantıksal birimlere (Sınıflar, modüller vb.) Bölerseniz söylenmesi, kod parçalarını anlamak için çok kısa bir kolaylığa sahip olabileceğinizdir. bu daha sonra korunabilir. Modüllerimin çoğu 20 satır kodundan az. Belirli bir konudaki tüm kodun belirli bir yerde olduğunu biliyorum. Aynı zamanda, eğer bir başkası projeye katılırsa bir şeyleri bulmak için çok daha kolay zaman geçirecekleri anlamına gelir.

Gerald Sussman'ın dediği gibi, programlarımızın önce insanların yazabilmesi için önce, sonra da bilgisayarın çalıştırılabilmesi için yazılması gerekiyor. (Eğer "Bilgisayar Programlarının Yapısı ve Yorumlanması” nı okumuşsanız)


4

Biri çoklu sınıflar kullanır çünkü daha büyük şeylere girdiğinizde, büyük bir kod yığını olduğunda her şeyi takip etmenin bir yolu yoktur.

Sadece onu bölmek ve ele geçirmek için fethetmek zorunda.


3

Nesneye yönelik programlama, programlamada gördüğüm en iyi fikirdir. Ancak bu, her durumda en iyi şey değildir, amacını görmek için biraz programlama deneyimine ihtiyacınız vardır ve birçok insan, olmadıklarında OOP yapmak için hak iddia eder.

"Yapısal programlama" konusunu arayabilirseniz, muhtemelen hemen daha faydalı bir şeyler bulacaksınız. ( Eski yapılandırılmış programlamayı okuduğunuzdan emin olun . Eski terimler genellikle yeni, merak uyandıran anlamlar kazanır ve henüz bir şeye ihtiyacınız yoktur.) Bu, programınızı alt programlara ayırmak için oldukça basit bir kavramdır; nesnelere ayırmak. Ana programın, işi yapmak için alt yordamları (Java'da "yöntemler") çağıran kısa bir yordam olduğu fikri. Her alt yordam, yalnızca parametreleri tarafından ne söylendiğini bilir. (Bu parametrelerden biri bir dosya adı olabilir, bu yüzden biraz hile yapabilirsiniz.) Bu yüzden bir alt yordamın / yöntemin başlığına bakmak size ne yaptığı hakkında hızlı bir fikir verir. neredeyse bir bakışta yok.

Daha sonra, tüm alt yordamlar benzer yöntemlerle, herhangi bir yöntem çağrısı yapmadan birkaç kod satırı çözene kadar benzer şekilde bozulur. Her biri birkaç yöntem çağıran, her biri birkaç yöntem çağıran ana yöntem. Bu şekilde, çok büyük bir programın (veya küçük bir programın) herhangi bir bölümüne bakabilir ve ne yaptığını hızlı bir şekilde anlayabilirsiniz.

Java, Nesne Yönelimli kod yazan insanlar için özellikle tasarlanmıştır. Ancak en yoğun OO programı bile yapılandırılmış bir programlama kullanır ve istediğiniz zaman bir dili altüst edebilirsiniz. (Düz C de OO yaptım.) Java ile SP veya başka bir şey yapabilirsiniz. Sınıfları unutun ve küçük, yönetilebilir olanlara ayrılabilecek büyük yöntemlere odaklanın. SP'nin kodunuzu yeniden kullanmanıza izin veren ve DRY (google, ancak "Kendinizi Tekrar Etme" anlamına gelir) ilkesiyle çok yardımcı olduğunu eklemeliyim.

Umarım neden ve nasıl "sınıf" getirmeden kodunuzu birden fazla bölüme ayırmayı açıkladım. Onlar harika bir fikir ve sadece oyunlar için bir şey ve Java OOP için harika bir dil. Ama yaptığını neden yaptığını bilmek daha iyi. Size mantıklı gelene kadar OOP'u yalnız bırakın.


0

Avantajlardan biri yeniden kullanılabilirliktir. Bir program temelde bir araya getirilmiş bir grup talimattır. Bu talimatların bazılarının diğer programlar için de uygun olduğunu göreceksiniz.

Diyelim ki bir atlama oyunu yapıyorsun. Daha sonra bir top oyunu yapmaya karar verdiğinizde, atlama oyunda kullandığınız fizik hesaplamasının burada kullanışlı olduğunu göreceksiniz.

Bu yüzden tekrar yazmak yerine ya da daha da kötüsü kopyalayıp yeni programa yapıştırarak bir sınıfa koyarsınız. Bir dahaki sefere, oyun mekaniğinin fizik gerektirdiği başka bir oyun yaptığınızda, yeniden kullanabilirsiniz. Elbette bu basitleştirilmiştir ancak umarım mantıklıdır.


0

Her şeyden önce, Java değil, C ++ ve Python olduğumu unutmayın, bu yüzden bunların bir kısmı tamamen geçerli olmayabilir. Java’da sınıfların nasıl çalıştığı hakkında bazı yanlış varsayımlar yaparsam lütfen beni düzeltin.

Sınıflar, başlatıldıklarında öncelikli olarak yararlıdır. Hiçbir örneği yaratılmayan bir sınıf, gerçekten yalnızca yüceltilmiş bir ad alanıdır. Tüm sınıflarınızı bu şekilde kullanırsanız, aslında, şeyleri ad alanından ad alanına taşımanın faydaları önemsiz gibi görünebilir - en fazla, her birinde bazı özel veriler bulundurarak kazanacaksınız ve bu sayede olayları biraz kaplayacaksınız.

Ancak, burası sınıfların parladığı yer değil. StringSınıfı düşünün : chardizileri ve bazı statik işlevleri kullanarak aynı özelliklere sahip olabilirsiniz . Bu noktada, fonksiyonlar size biraz ekstra güvenlik ve sözdizimsel şeker sağlar. Sen yazabilir string.length()yerine length(char_array); Bu çok büyük bir anlaşma değil, ama çoğu insan hala hoşuna gidiyor. Dahası, eğer biri size bir şey verdiyse String, Stringyapıcı ile yaratıldığını ve lengthişlevle çalışması gerektiğini - dizi sürümü bazı karakterleri işleyemiyorsa, oraya yerleştirmenizi engellemenin bir yolu olmadığını biliyorsunuz. .

Yine de öyle değil. Temel nokta, sınıfların üzerinde çalışan ve her ikisini de soyutlayan ve üzerinde çalışan verileri bir araya getirmesidir. void f(Builder b)Bildiğiniz bir yönteminiz olduğunda, bir şey elde Builderedersiniz ve bunun belirli bir davranışı destekleyeceğini bekleyebilirsiniz. Ancak, hiçbir veri veya yürütülen işlev hakkında hiçbir şey bilmiyorsunuz - aslında, her ikisinin tanımları da yazarken ve derlerken yazılmayabilir f.

Anlaması gereken ilk nokta, sınıfların, verilerin kırılmadığından emin olmak için veri dolaşmasını kolaylaştırmasıdır. İkinci nokta, bir nesnenin hem hangi verileri, hem de hangi işlevi (uygulamaları) içerdiği, nesne ile ilgili bir şey olduğudur, sadece türünden anlatabileceğiniz bir şey değildir.


0

Bütün fikir, böl ve yönet fethi adındaki genel bir kurala dayanır .
Bu paradigma hemen hemen her yerde kullanılabilir; Bir problemi daha küçük problemlere böler ve sonra bu küçük, basit ve iyi bilinen problemleri çözersiniz.
Programınızı sınıflara ayırmak, son on yılda yaygınlaşmaya başlayan bölünme türlerinden biridir. Bu programlama paradigmasında problemimizi bazı nesneler ile modelliyoruz ve bu nesneler arasında mesajlar göndererek sorunu çözmeye çalışıyoruz.
Bazı insanlar bu yaklaşımın anlaşılmasının, genişletilmesinin ve hata ayıklamanın daha kolay olduğunu söyleyebilir.
Her ne kadar bazı insanlar katılmıyorum :)


0

Bir programı sınıflara bölmekle değil, uygulamanızı nasıl modellediğinizle, yani uygulamanızın bölümlerini nasıl görselleştirdiğinizle ilgilidir. Şeyleri bölmek, karmaşık şeyleri daha iyi anlamak için kullandığımız bir mekanizmadır. Sadece programlama ile değil. Devre kartını, birbirleriyle dolaşmış birçok telin bulunduğu ve her telin bir yere bağlandığı karmaşık bir yapı oluşturan (spagetti kodu) düşünün. Bağlantıları bulmak için her bir kabloyu sonuna kadar takip etmeniz gerekir. Aksine, işlevlerine göre gruplandırılmış ve renk kodlu teller hayal edin. Bir şeyleri düzeltmek çok daha kolay hale geliyor.

Fikir, uzun bir programla başlamamanız ve daha sonra bunları sınıflara bölmenizdir. Ancak uygulamanızı önce nesneler / sınıflar açısından modelleyin, sonra bunları uygulamalar oluşturmak için bağlayın.

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.