Bugün Paul Graham'ın "Hackerlar ve Ressamlar" kitabını düşünüyordum. Daha spesifik olarak, bu iki paragraf :
"Kolejde, bir bilgisayarın yanına bile gitmeden önce bir kağıda tamamen bir program bulması gerektiği öğretildi. Bu şekilde programlamadığımı buldum. Bilgisayarın önünde oturan bir program yapmaktan hoşlandığımı buldum Daha da kötüsü, sabırla tam bir program yazmak ve kendime doğru olduğundan emin olmak yerine, umutsuzca kırılan kodu yayma ve yavaş yavaş şekli yendi. Hata ayıklama, bir tür son geçişti. yazım hataları ve gözetimler yakaladı ... [Bu] programlama hata ayıklama gibi görünüyordu.
... Anlayabildiğim kadarıyla, bana üniversitede programlamayı öğretme biçimleri yanlıştı. Programları yazarlar ve ressamlar ve mimarlar gibi yazarken de anlamalısınız. "
Benim kolejimde bu şekilde öğretiliyor ve diğer kolejlerin çoğundan da eminim. Programınızın ne yapacağını ve sonra nasıl yapılacağını anlarsınız, sonra yazıp hata ayıklarsınız. Bazen temel bir sürüm yapar ve işlevsellik eklersiniz, ancak fikir, düşünüp yazmanızdır.
Feynman'ın "Radyoları Düşünerek Çözer!" Adlı kitabındaki bu bölümü hatırlatıyor! burada telsizin nasıl kırılacağını düşünerek ilerledi ve sonra düzeldi. Bana göre, programlama budur - düşünmek ve sonra bir çözüm bulmak.
Bu kodlamaya yaygın bir yaklaşım mı? Öyleyse, neden daha fazla insan neye benzeyeceğine dair önceden düşünülmüş bir fikre sahip olmadan bir programı hackleyip bir araya getirmiyor?
Düşünme ve türün konuşma ve vurmaya karşı avantaj ve dezavantajları nelerdir?
Bu, dışlanan orta yanlışlığa mükemmel bir örnektir. Evet, gerçek klavyeye dokunmadan önce tüm programı kağıda yazmak kötü bir fikirdir. Ama bu tam tersini yapmaz - hemen kodlamaya atlar ve hacklemeye başlar - iyi bir fikir. Aslında, daha da kötü.
Yazmaya başlamadan önce ne yazmaya çalıştığınızı anlamak çok önemlidir. İş yerinde uygulamak için yeni bir özelliğim olduğunda, başlamadan önce ne yapılması gerektiğini açıklayan bir spesifikasyonum olduğundan emin olurum. Bakıyorum, eğer mantıklı olmayan bir şey varsa, şartnameyi yazan insanlarla konuşuyorum ve anlaşmaya varıncaya kadar konu üzerinde çalışıyorum. Bazen gereksinimleri anlamamıştım ve beni düzeltebilirlerdi; diğer zamanlarda PM millet teknik detayları anlamadılar ve sonuçta özellikleri değiştirdiler.
Bunu yapan herkes, kişisel deneyimlerden, spesifikasyondaki sorunları düzeltmenin, uygulamada kodunuzda bir sorun bulmanın, hepsini kopyalamanın ve başka bir şeyle değiştirmekten çok daha kolay olduğunu söyleyebilir. . Bu yüzden kodu yazmaya başlamadan önce yazdıklarınız için bir plana sahip olmak çok, çok önemlidir.
Michelangelo'nun Sistine Şapeli'nin tepesine tırmandığını ve çizmeye yeni başladığını mı düşünüyorsun? Test çizimleri yapıldı. Papa'dan onay alınması gerekiyordu. İnşa edilecek iskele vardı. Diğer sanatçıların grubuna rehberlik etmek için yapılan şablonlar. Restorasyon daha da karmaşıktı.
Bir uygulama oluşturmak istiyorsam ve başka birinin kafasındaki tasarım tercihlerini göz önünde bulundurmam gerekmiyorsa, sadece kodlamaya başlayabilirim. Yanlış yola girerseniz fikrinizi değiştirin. Zaten bu özelliği istemedim.
Ressamın ya da yazarın bir komitede oturmasına izin verin. "Oh, devam et ve ana karakteri bir kadın yap. Eğer fikrimizi daha sonra değiştirirsek, sana haber vereceğiz. Ve WTF, 30 yerine 20 'uzun yapalım. 50 ile İspanyol Galleon ekleyebilir misin? yarın açılmadan önce benzersiz kürekçiler? "
Sanırım her şey bir denge oluşturmakla ilgilidir. Hepsini yazmadan önce her şeyi düşünmek imkansız, bu yüzden Şelale modeli bu kadar kırılmış. Aynı zamanda, çok az düşünürseniz, ilk birkaç yinelemeyi geçtiğinizde kendiniz için büyük bir karışıklığa neden olabilirsiniz. Sonuçta, tüm kodu şekillendiremezsiniz ve projenin yarısında yeniden yazılması gereken temel bir gereksinimi erken gözden kaçırmış olsaydınız çok talihsiz olurdu.
Şelale'nin baktığı kalkınma sürecinde belirli sayıda yineleme gereklidir (1 mükemmel yineleme varsayılır). Çevik (veya "Agile benzeri" metodolojilerin geniş grubu) bazen her yinelemenin belirli bir ek yüke sahip olduğunu ve her bir yinelemede çok fazla kazanılmadığı takdirde, toplam yinelemelerin sayısı artacağını ve bu ek yükün toplanacağını göz ardı eder. önemli bir maliyete.
Analojinin temeli yanlıştır: birçok yazar yazmaya başlamadan önce ne yazacaklarını ana hatlarıyla çizer veya en azından ne yazacağını düşünür ve birçok ressam ve mimar gerçek "çalışmalarına" başlamadan önce düzinelerce çalışma ve eskiz yaparlar.
Analojinin yanlış olduğu göz önüne alındığında, cevap evet - programcılar yazarlar, ressamlar ve mimarlar gibi çalışmalıdır.
Resim ve web tasarımı yapan çift sanat dalında üniversitede bir oda arkadaşım vardı. O ve ben iş akışlarımızla ilgili notları karşılaştırdık. Resim yaptığında, sadece boyadığı sırada resmi anlamaz. Önceden yapabileceği birkaç şey vardı. Kolaj türü bir resim için bir eskiz çizebilir. Fotogerçekçi bir resim üzerinde ana şekilleri kalemle çizer ve daha sonra detaylarda Boya. Ama önceden ne istediğini tam olarak bilseydi, bu yardımlara ihtiyacı yoktu. Sadece boyadı.
Eminim benzerlikleri görürsünüz. Bir soruna iyi bir çözüm bulmak için farklı yöntemler kullanıyoruz. Teknolojiyi iyi bilmiyorsak, nihai çözümün nasıl görüneceğini anlamak için biraz hackliyoruz. Daha büyük ürünler genellikle büyük resim tasarım oturumundan yararlanır, ayrıntılar daha sonra doldurulur. Ve bazen tam olarak neyin gerekli olduğunu biliyoruz, bu yüzden sadece kodlıyoruz. Tembel olduğumuz için değil, deneyim ve düşünce yoluyla ekstra araçlara ihtiyacımız olmadığı için.
Ön tasarımın bazı avantajları:
Koda atlamanın avantajları:
Bu sorunun cevabı programlamada birçok kişinin cevabı gibidir: Bağlıdır. Projeye bağlı - bir tasarım denetim izine ihtiyacınız var mı, süreç sizin ve diğer geliştiricilerinizin ihtiyacınız olan kararları tam olarak anlamasına yardımcı oluyor mu? Projenin kesinlikle doğru olması kritik mi yoksa bazı kusurlar daha sonra keşfedilip düzeltilebilir mi? Zaman diliminiz nasıl? Soruna ne tür bir deneyim getirebilirsiniz? Ve son olarak, hangi sorunu çözmeniz gerektiğini tam olarak anlıyor musunuz?
Şu anda benim için çalışan kağıt üzerinde büyük bir resim tasarımı yapmak. Bu, uygulamanın büyük bölümlerini ve nasıl iletişim kuracaklarını açıklayacaktır. Genellikle am obje diyagramı ve daha karmaşık bölümler için bazı akış şemaları/psuedocode/real code çiziyorum. Sonra her defasında bir bölüm sağa atlıyorum. Modeldeki bir hata bir soruna neden oluyorsa, her zaman tasarım özelliklerine geri dönebilir ve bu alan için onları revize edebilirim. Ve iyi bir ön tasarımın değiştirilmesi genellikle biraz daha fazlasının değişmesi gerektiği anlamına gelmez.
Bana bir model demiryolu inşa ettiğiniz gibi programlamanız öğretildi.
Bir model demiryolu inşa ederken, bir parça pist döşer ve piste bir motor koyarsınız. Hareket ederse, bir sonraki pist parçasını döşersiniz ve motorun bu piste geçip geçmediğini görürsünüz. Döngüyü tamamlayana ve motor da döngüyü tamamlayana kadar devam edersiniz.
Model bir demiryolu inşa etmenin bu yönteminin avantajı, motor hareket etmeyi durdurursa, sorunun hangi parçanın olduğundan emin olmanızdır. Az önce koyduğun.
Programlama benzerdir. Analiz ve tasarımı yapmanız gerekiyor, ancak bir noktada iz bırakmaya başlamalısınız. İlk yinelemeniz sahte modüllerden başka bir şey olmayabilir. Projenizi hiçbir şey yapmadan yürüttüğü sürece sorun değil.
Bir seferde bir yöntem (ideal olarak) veya yürütülecek bir şey elde etmek için minimum yöntem miktarı eklersiniz. Her seferinde motorun hareket edip etmediğini görürsünüz (proje durmadan çalışır).
Parkuru döşerken ek bir kaplamaya ihtiyacınız olduğunu keşfedebilirsiniz (bazı ek yöntemler). Tasarımı kökten değiştirmediğiniz sürece sorun değil. Tasarımı kökten değiştiriyorsanız, kodlamayı durdurun. Kodlamaya devam etmeden önce tasarımı düşünerek biraz zaman geçirin ve tasarımda değişiklikler yapın.
Son parçayı koyduğunuzda (son yöntemleri tamamladıysanız), projeniz engellemeden yürütülmelidir. Çünkü baştan beri test ediyordun. Tıpkı model demiryolu üreticileri gibi.
Düşüncenin eyleme oranı, sorunun karmaşıklığından alan adına ve nihai hedeflere kadar bir dizi değişkene bağlıdır. Bir programda sadece "korsan" olabileceğiniz zamana karşı ne kadar düşünce ve planlamaya ihtiyacınız olduğunu anlamanız için tek bir boyuta uyan tek bir yaklaşım yoktur.
Karmaşık bir sorununuz varsa veya yaşam veya görev açısından kritik öneme sahip bir şey üzerinde çalışıyorsanız, bunu anlamak ve çözümler ve değiş tokuşlar hakkında düşünmek için zaman harcamanız gerekir. Bir teknolojiyi, kütüphaneyi veya çerçeveyi hızlı bir şekilde öğrenmek istiyorsanız, belki de doğrudan atlamak ve hatalarınızı bir prototip ortamında ortam yapmak en iyisidir. Diğer seçenekler arasında evrimsel prototipleme yer alır - çalışmanızı bitmiş bir ürüne dönüştürebileceğinizden emin olmak için yeterli düşünce ve tasarım, ancak tek bir yolda kısıtlanacağınız kadar değil.
@Thomas'ın belirttiği gibi, tek bedene uyan bir çözüm yoktur. Bu bol bilgi işlem gücü ve bellek çağında, karşı karşıya olduğumuz sorunların çoğu zor değildir, bu nedenle doğru çözüm veren hemen hemen her yaklaşım gerçekleşecektir. Ancak, hemen kod yazarak anında bir çözüm bulmaya çalışırsanız, sefil olarak başarısız olabileceğiniz alanlar var.
Örneğin, üzerinde çalıştığım bir uygulama mobil ağları analiz ediyordu. Süper bilgisayarlarda değil, sadece çift çekirdekli dizüstü bilgisayarlarda çalışması gereken bir düzine farklı ağ katmanı üzerinde birkaç bin düğümden oluşan bir ağı analiz etmek için kod yazmanız gerekiyorsa, daha önce insanlık tarafından bilinen en iyi grafik algoritmalarını bulmanız daha iyi olur herhangi bir kod yazmaya başlayabilirsiniz. Alternatif, yarım yıllık istekli gelişimden sonra, algoritmanızın, 10 düğümlü test ağınız için doğru sonuçlar sağlamasına rağmen, O (n4) böylece kullanıcının dizüstü bilgisayarında iki yıl sonra, şu anda üzerinde çalıştığı gerçek hayat ağ planıyla beslendiğinde sona erer ...
Neden daha fazla insan neye benzeyeceğine dair önceden düşünülmüş bir fikre sahip olmadan bir programı hackleyip bir araya getirmiyor?
Birçok insan kariyerleri boyunca bunu yapar. Bu site sorularıyla dolu. Diğer bağlı kuruluş siteleri, yazdıkları yazılımı kullanmaya çalışan diğer kişilerin sorularıyla doludur.
Kodu koyduğunuzda, sadece kodu söyleyen insanlar genellikle "Kod kendi dokümanlarıdır" gibi bir şey söyleyecektir. Kod değil belgelerdir. Kod, niyetinizin bir gösterimi değildir, niyet olarak hatırladığınız şeyin bir versiyonu, ayrıca yol boyunca ilgilendiğiniz bir grup şey, bazıları kullanışlı olmadığı ortaya çıktı, ancak zamanınız yoktu Kaldırmak. Oh, ve iki gece uykusundan sonra, tüm projede devrim yaratacak olan çok fazla kafeinden sonra sahip olduğunuz bu şaşırtıcı fikir, sadece ne yapması gerektiğini, ya da tam olarak ne yapması gerektiğini bilmediğinizi bile biliyorsunuz. kaldırırsanız ne gibi bir etkisi olacaktır.
Bir tür tasarım belgesi olmadan, asgari düzeyde olsa da, ortak çalışanlarınız (veya halefleriniz) hangi bitlerin genişletileceğini ve hangilerinin düşeceğini nasıl söyler? Bu belgenin başlangıçta yazılması gerekmez, ancak herhangi bir boyutta ve değere sahip bir proje için bir noktada olması gerekir.
Spew-and-refactor, bir noktaya kadar solo projeler için çalışır (ve bu noktanın nerede olduğu konusunda iyi yargıç olan insanlar bilmeye değer). Takımlar için daha az pratiktir; Spesifikasyonlar hakkında minimum bir fikir birliği olmaksızın insanlar nasıl paralel olarak verimli çalışırlar? Çevik metodoloji büyük ölçüde insanların yerel kodlama hevesini öldürmeden bu sorunu çözme girişimidir.
Genel olarak programlama soyutlamada bir alıştırmadır. Bu nedenle, herhangi bir çözümü aşırı gerçekleştirme girişimi, şüphesiz ki çabalarınızın kapsamını yanlış değerlendirmenize yol açacaktır.
Karmaşıklığı yargılamakta o kadar iyi değilsin. Güven bana, sen değilsin.
En iyi kod, neyi başarmak istediğinizin bir taslağı ile başlar ve parçalar halinde tekrarlanarak büyütülür. Ardışık kod kendi üzerine inşa ile. Bir projenin planlama aşamalarında, programınızın ne yapmayacağını listelemek ve listelemek çok daha yararlıdır. Bu şekilde en azından lanet okyanusu kaynatmaya çalışamazsınız.
Bence iş akışı her programcı için çok bireysel. Sizin için en uygun yöntemi kullanın.
Ben, kişisel olarak, genellikle boş bir kağıt ve kalemle (veya eğer varsa çok büyük bir beyaz tahta ile) başlarım. İlk önce sınıf diyagramları ve ilişkiler çiziyorum. Sonra temel bir yapıya sahip olana kadar rafine ediyorum. Bu aşamada devlet makinelerini de yapıyorum. Bu noktada hiçbir kod yazılmadı veya düşünülmedi, sadece sınıflar ve ilişkiler.
Şimdi bu sadece bir kayıp taslağıdır ve derslerimi programlamaya başlarken daha fazla tasarım sorusu ile karşılaşacağım. Daha sonra beyaz tahtama (veya kağıda) geri dönüp yeni sorunları yıkarım, bazen orijinal tasarımın bir kısmını parçalamak anlamına gelir.
Bu aynı zamanda Çevik tasarımın nasıl çalıştığına benzer (not [~ # ~] benzer [~ # ~] bu konuda şikayet edecek herkese). Bu yöntemi kullanarak proje ilerlemesinin nasıl izleneceğine dair tam bir bilim vardır, çünkü yeni görevlerin sayısı başlangıçta hızlanacaktır ve projenin sonuna kadar kaybolmalıdır.
Fikir, kodu ve tasarımı tekrarlamaktır. Bu işlemi eski şirketimde (130 geliştirici ile) kullandık ve harika çalışıyor. Ayrıca koddan sınıf ve ilişki diyagramları üretmek için Doxygen'i kullandık. Bu, aslında kodlanmış tasarıma iyi bir genel bakış elde etmenin, kusurları ve eksik ilişkileri tespit etmenin hızlı bir yoluydu.
Bu senin için işe yarayıp yaramadığını söyleyemem. Sizin için neyin en iyi olduğunu görmeye çalışmalısınız.
İki sentimle de karşılaşacağım.
Başlamadan önce kağıda tam bir program yazmak, Hello World için çalışan bir "CS 101" alıştırmasıdır. Ancak neyi başarmak istediğinizi düşünmek için zaman ayırmadan kodları dağıtmak da zaman kaybıdır.
Bu iki uç arasında, sert Şelale'den (geniş özellik seti, hemen hemen bir çıkış), sürümler ve sürekli "müşteri" diyalogu arasında çok hızlı dönüş sağlayan çevik ("hafif" özellikler) ).
Her durumda, yöntem ne olursa olsun, başlamadan önce ne inşa ettiğinizi bilmeniz gerekir. Bu, programın mimarisini çerçevelemeye yardımcı olacaktır. Şelale, kodlamaya başlamadan önce tüm sistemin mimarisini oluşturmaya vurgu yapacak, böylece neyle sonuçlanacağınızı bileceksiniz. Agile, "bir sonraki iterasyon için elde edilecek minimum işlevselliklere" vurgu yapacak ve sizi sürekli olarak yeniden mimariye hazır hale getirmeye ikna edecektir (uygun test takımları ve benzerleri oluşturarak bu tür işleri gerçekleştirebilirsiniz) ).
HİÇBİR metodolojinin kodlamayı düşünmeden başlatmanızı söyleyeceğini ve gerçekten ne yapmaya çalıştığınız hakkında oldukça iyi bir fikriniz olması gerektiğini unutmayın (Şelale ile ilgili her şey veya Agile ile daha küçük bir alan olsun). Biraz doğaçlama yapıyorsunuz "NASIL" bir şey yapıyorsun, "NE" yapmaya çalışıyorsun değil.
Oyunculuk dersleri alırken öğrendiklerinizle paralellik kurabilirim. Büyük bir kısmı "gelişmedir". Bir doğaçlama başlatırken, olabildiğince az taşla gelmeniz ve birisi sahneyi başka bir yöne götürürse fikrinizi terk etmeye hazır olmanız gerekir. Harika dinleme becerilerine ve başkalarının önerilerini kabul etmelisiniz. Ana şey, bir karakter, bir durum, belki de iletmek istediğiniz bir duygu ve potansiyel olarak sahneyi çekmek istediğiniz bir sonla sahneye çıkmaktır. Ancak fikir sahnede en uzağa, başka bir yere gitme olasılığınız o kadar yüksek olur. Sonuçta, bu çok "Çevik" bir düşünce tarzı.
Şimdi, "kod yazalım" düzeyinde konuşuyorsanız (özellikler, hikayeler veya mevcut her şey), o zaman size kalmış. Bazı insanlar yalancı kod yazıyor, bazıları gerçek koddan önce yorum yazıyor ("boş şekilde doldurun" ve bazıları testler yazarak başlıyor (bkz. Test Odaklı Geliştirme) .Her durumda, amaç fikrinizi çerçevelemektir. kendi yönteminizde yapmak için yola çıktık, bu seviyede, çoğu insan gerçek kodu yazmadan önce biraz düşünüyor ama kağıt üzerinde elden önce kodu yazmak kadar ileri gitmek bana aşırı geldi ...
Bunun cevaplandığını biliyorum, ama Graham'ın üst düzey genel bakışları ya da ön plandaki tasarımları göz ardı etmek istediğine ikna olmadım. Elden önceki problemi düşünüyorum, spesifikasyonları var, ama yine de aynı şekilde çalışırken söylediklerini tamamen anlıyorum.
Bana göre "hackleme" ne yapacağınızı değil, nasıl yapacağınızı gösterir. Okulda sahte kod öğretildi ve gerçek kodu önceden tasarladım. Bana göre, bu aptalca. Üst düzey bir bakış, bir pusula alacağım ve oradan uzaklaşacağım. Ben bir derleyici veya bilgisayar değilim ve tüm kod kağıda ön sonuçları anlayamıyorum çünkü tüm kodu düşünmeye çalışacağım. Teknik özelliklerin veya tasarımın verimsiz veya kırık bir uygulamasını hackleyeceğim ve daha sonra oradan "şekle döverim".
Peki, kimin pg'nin söylediklerine itiraz edeceğim, ama ... Bence en iyi yaklaşım muhtemelen kişiye göre değişir ve bu - bu noktaya nesnel bir gerçek olabileceği ölçüde - gerçek muhtemelen ortada bir yerde yatar . En azından, "önceden planlama yok" ile "her şeyi önceden anlayın" arasında bir ikilik yapmanın yanlış bir ikilik olduğunu düşünüyorum. Benim deneyimime göre bir süreklilik.
Ben şahsen keşif programlama stiline daha çok eğildim ve “ben giderken anladım”, fakat aynı zamanda en sevdiğim programlama araçlarından ikisi bir sanatçı eskiz defteri ve bir dizi renkli kalem. Kesinlikle oturup üst düzey ilişkileri çizmek ve şeylerin birbirine nasıl uyacağını anlamanıza yardımcı olacak şeyleri görselleştirmek için bir zaman ve yer var. Benim için var.
Yine, bunun bireye çok bağlı olduğunu düşünüyorum ... ve aynı zamanda problem alanına ve programın doğal karmaşıklığına da bağlı. Yani, basit bir komut satırı hesaplama programı ("zavallı adamın bc" düşünün) muhtemelen bir 30.000 çalışan şirket için ERP sistemi) daha az ön planlama gerektirir.
Zorunlu Avcı S. Thomson alıntı ama her zaman benim için çalışıyor
Neyi başarmak istediğinize dair net bir fikriniz varsa, kodunuzu nasıl yapılandıracağınızı ve iyi bir kodlayıcı olduğunuzu bilin ve genellikle kodu yazmak daha hızlıdır.