Hangi popüler “en iyi uygulamalar” her zaman en iyi değildir ve neden? [kapalı]


100

“En iyi uygulamalar” endüstrimizin her yerinde. "En iyi uygulamaları kodlama" konulu bir Google araması yaklaşık 1,5 milyon sonuç ortaya koyuyor. Fikir birçok kişiye rahatlık getiriyor gibi görünüyor; Sadece talimatları takip et, her şey yoluna girecek.

En iyi uygulamaları okuduğumda - örneğin, son zamanlarda Clean Code'da birkaç tane okudum - sinirleniyorum. Bu her zaman bu uygulamayı kullanmam gerektiği anlamına mı geliyor ? Ekli koşullar var mı? O olabilir durumlar vardır değil iyi bir uygulama olacak? Sorun hakkında daha fazla şey öğrenene kadar nasıl emin olabilirim?

Clean Code'da belirtilen uygulamaların birçoğu benimle tam oturmadı, ama bunun potansiyel olarak kötü olmalarından mı, yoksa sadece kişisel önyargımın konuşmasından mı kaynaklandığından emin değilim. Teknoloji endüstrisindeki önde gelen birçok insanın en iyi uygulamaların olmadığını düşünüyor gibi göründüğünü biliyorum , bu yüzden en azından dırdırcı şüphelerim beni iyi bir şirkete sokuyor.

Okuduğum en iyi uygulamaların sayısı burada listelenmek veya bireysel sorular sormak için çok fazla, bu yüzden bunu genel bir soru olarak ifade etmek istiyorum:

Popüler olarak "en iyi uygulamalar" olarak etiketlenen hangi kodlama uygulamaları belirli koşullar altında en uygun ve hatta zararlı olabilir? Bu koşullar nelerdir ve uygulamayı neden fakir hale getiriyorlar?

Özel örnekler ve deneyimler hakkında duymayı tercih ederim.


8
Hangi uygulamalara katılmıyorsunuz? Sadece merak ediyorum.
Sergio Acosta

Herkes bir kitap yazabilir ve benim de buna katılmam gerekmiyor - bu kadar basit.
İş

Steve McConnell'in "Kod Tamamlandı" kitabından hoşlandığım şeylerden biri, tüm ipuçlarını sert kanıtlarla ve araştırmalarla desteklemesi. Sadece söylüyorum
JW01

5
@Walter: Bu aylardır açık, kesinlikle yapıcı, neden yakın?
Orbling

2
Burada ismimin nasıl ifade edildiğini görünce, içeri girmeliyim: Buradaki cevapların değerli olduğuna inanıyorum, ancak soru, cevapların hiçbirini geçersiz kılmadan, kesinlikle daha az anket benzeri bir soruya cevap verilebileceğini düşünüyorum. Örnek başlık: "Hangi popüler 'en iyi uygulamalar' bazen zararlı olabilir ve ne zaman / neden?"
Aaron, 19:11

Yanıtlar:


125

Bence bu ifadeyle başındaki tırnağa çarptın.

İşleri yüz değerinden almaktan ve eleştirel düşünmekten nefret ederim.

Niçin var olduğuna dair bir açıklama gelmediğinde hemen hemen tüm En İyi Uygulamalarını görmezden geliyorum.

Raymond Chen, bu makalede en iyisini söylediğinde

İyi bir tavsiye gerekçeyle birlikte gelir, böylece ne zaman kötü bir öneri haline geldiğini anlayabilirsiniz. Neden bir şeyler yapılması gerektiğini anlamıyorsanız, kargo kültü programlamanın tuzağına düştünüz ve artık gerekli olmadığında veya zararlı hale geldiğinde bile bunu yapmaya devam edeceksiniz.


4
Harika teklif.
David Thornley

Raymond Chen alıntılarının bir sonraki paragrafı muhtemelen Macar gösterimini anlatıyor! Çoğu şirketi kullandığını açıklayabilecekleri gerçek bir sebep olmadan görüyorum.
Craig

3
Umarım insanlar bunu, en iyi uygulamaların arkasındaki mantığa bakmamayı bahane olarak görmezler. ;) Ne yazık ki, bu tavırla geliştiriciler gördüm.
Vetle

3
Gerekçe iyidir. Araştırma daha iyi.
Jon Purdy

7
Kesinlikle doğru ve daha önce de aynısını söyledim. Belki de herhangi bir "Standartlar" belgesindeki ilk standart, "Bilgi paylaşımı ve daha sonraki zamanlarda standartları iptal etmek için gerekli bilginin sağlanması amacıyla, tüm standartlar, varlıklarının nedenlerini içerecektir" şeklinde yazmalıdır.
Scott Whitlock,

95

Bunu çembere atmak da mümkün olabilir:

Premature optimization is the root of all evil.

Hayır değil.

Tam teklif:

“Küçük etkinlikleri unutmalıyız, zamanın yaklaşık% 97'sini söyleyelim: erken optimizasyon tüm kötülüklerin köküdür. Ancak bu kritik% 3'teki fırsatlarımızı kaçırmamalıyız.”

Bu , tasarım süreciniz boyunca spesifik, stratejik performans geliştirmelerinden yararlanabileceğiniz anlamına gelir . Bu, performans hedefleriyle tutarlı veri yapıları ve algoritmaları kullandığınız anlamına gelir. Bu, performansı etkileyen tasarım hususlarından haberdar olduğunuz anlamına gelir. Fakat aynı zamanda bunu yaparken yanlış bir şekilde optimize etmediğiniz anlamına gelir, böylece bakım masrafları karşılığında size küçük kazançlar sağlar.

Uygulamaların iyi yapılandırılmış olmaları gerekir, böylece üzerlerine küçük bir yük uyguladığınızda sonunda düşmemeleri ve sonra onları yeniden yazmaya başlayabilirsiniz. Kısaltılmış alıntı ile tehlike, çoğu zaman, geliştiricilerin, hakkında bir şey yapmak için çok geç olduğu zaman, performansı sonuna kadar düşünmemek için bir bahane olarak kullanmasıdır. Minutia'ya odaklanmamanız şartıyla, en baştan iyi bir performans elde etmek daha iyidir.

Diyelim ki gömülü bir sistemde gerçek zamanlı bir uygulama oluşturduğunuzu varsayalım. Python'u programlama dili olarak seçtiniz, çünkü "Erken optimizasyon tüm kötülüklerin kökenidir." Şimdi Python karşı bir şey var, ama olan bir dil. Eğer işlem gücü kısıtlıysa ve belirli bir miktarda işin gerçek zamanlı veya gerçek zamanlı olarak yapılması gerekiyorsa ve iş için sahip olduğunuzdan daha fazla işlem gücü gerektiren bir dil seçtiyseniz, kraliyetten mahrumsunuz, çünkü şimdi yetenekli bir dille baştan başlamak zorunda.


4
Güçlü için +1 Hayır, değil.
Stephen

21
Ancak, belirli bir optimizasyonun bu kritik% 3 dahilinde olduğunu zaten fark ettiyseniz, optimizasyonda erken misiniz?
John

7
@Robert: Öyleyse "Erken optimizasyon tüm kötülüğün köküdür" ifadesiyle uyuşmazlık noktası nedir?
John

8
Dil seçimi gibi üst düzey tasarım ve teknik kararları optimize etmek asla erken değildir. Bununla birlikte, çoğu zaman, sadece verimsizliklerinin belirginleştiği bir tasarımı tamamladıktan sonra olur, bu yüzden Fred Brooks çoğu takımın istemek olsun olmasın atılan bir versiyon yazdığını söyledi. Prototipleme için başka bir argüman.
Dominique McDonnell

8
@Robert, Knuth teklifi erken

94

İşlev / yöntem başına bir dönüş.


7
Bunu koyacaktım. Bazı erken dönüş beyanlarını seviyorum.
Carson Myers,

4
Kesinlikle! İnsanlar erken returnaçıklama yapmaktan kaçınmak için oldukça ilginç bir program akışı sağlarlar . Derinden iç içe geçmiş kontrol yapıları veya sürekli kontroller. Bu, bir if returnsorunu gerçekten basitleştirebildiğinde bir yöntemi gerçekten şişirebilir .
snmcdonald

4
Bir fonksiyonda birden fazla geri dönüşe ihtiyacınız varsa (korumaların dışında) fonksiyonunuz muhtemelen çok uzundur.
EricSchaefer,

18
Birden fazla yerde görünmesi amaçlanmadıkça bir return anahtar kelimesine sahip olmanın anlamı yoktur. Erken dön, sık sık dön. Sadece kodunuzu daha da basitleştirmek için hizmet verecek. İnsanlar ara ver / devam et ifadelerinin nasıl çalıştığını anlayabiliyorsa, neden geri dönüşle mücadele ediyorlar?
Evan Plaice

7
Bence bu çok eski bir en iyi uygulama. Modern bir en iyi uygulama olduğunu sanmıyorum.
Skilldrick

87

Tekerleği yeniden icat etmeyin , yaygın olarak kullanılan bir dogmadır. Buradaki fikir, uygun bir çözüm varsa, kendinizinkini oluşturmak yerine kullanın; Tasarruf çabalarına ek olarak, mevcut çözüm muhtemelen başlangıçta elde edeceğinizden daha iyi bir şekilde uygulandı (hatasız, verimli, test edildi). Çok uzak çok iyi.

Sorun,% 100 uygun bir çözümün nadiren mevcut olmasıdır. % 80 uygun bir çözelti mevcut olabilir ve kullanılması muhtemelen iyi olabilir. Peki ya% 60 uygun? % 40? Çizgiyi nereye çekiyorsun? Çizgiyi çizmezseniz, projenize şişirilmiş bir kütüphane ekleyerek bitebilirsiniz, çünkü özelliklerinin% 10'unu kullanıyorsunuz - sadece "tekerleği yeniden icat etmekten kaçınmak istediğinizden".

Tekerleği yeniden icat edersen, istediğini elde edersin. Ayrıca tekerlek yapmayı da öğreneceksiniz. Yaparak öğrenme hafife alınmamalıdır. Ve sonunda, özel bir tekerlek kullanıma hazır genel tekerleklerden daha iyi olabilir.


3
Bunun tersi oldu. Kendi ajax grid bileşenimi oluşturdum çünkü o zamanlar istediğimi yapan hiçbir şey yoktu, fakat daha sonraları Ext JS ızgaraları ile değiştirdi. Ekran katmanının değiştirileceği başından beri varsayımda bulundum.
Joeri Sebrechts

20
Kabul. Hiç kimse tekerleği yeniden icat etmediyse, arabalarımızı tahta lastiklerle sürüyor olurduk.
Dr. Wily's Çırağı

6
Bir C ++ projesine Boost eklediğimde her zaman% 10 örneğiniz gibi hissediyorum. Her zaman doğrudan% 10'undan daha azına ihtiyacım var, ama elbette ki ihtiyacım olan işlevler diğer modülleri ithal eden diğer modülleri ithal
ediyorlar

3
+1: Sadece bu hafta tekerleği yeniden icat ettim (örneğin, ihtiyaçlarımıza henüz modüler olan bir şey tarafından kullandığımız şişirilmiş ama popüler jquery eklentisini değiştirdim) ve çok büyük performans artışı sağladı. Ayrıca, tekerleği yeniden icat etmek için işi gerçek olan insanlar var: örneğin Michelin'i ele al, lastik geliştirmek için AR-GE yapıyorlar.
yabani kuşlar

2
@Dr. Wily, bu tekerlekler yeniden icat edilmedi, yeniden düzenlendi!

78

"Birim Her Şeyi Test Et."

Sıklıkla bütün kodun birim testlerine girmesi gerektiğini, duymadığım bir nokta olduğunu söylediğini duydum. Bir yöntem için test yaptırdığınızda, bu yöntemin çıktısında veya yapısında herhangi bir değişiklik iki kez yapılmalıdır (bir kez kodda, bir kez testte).

Bu nedenle, birim testleri bence kodun yapısal kararlılığı ile orantılı olmalıdır. Aşağıdan yukarıya katmanlı bir sistem yazıyorsam, veri erişim katmanım wazoo'yu test edecek; iş mantığı katmanım oldukça iyi bir şekilde test edilecek, sunum katmanımın bazı testleri olacak ve görüşlerimin çok az veya hiç testi olmayacak.


7
"Ünite Testi Her Şey" in "erken optimizasyon" alıntı gibi bir klişe haline geldiğinden şüpheleniyorum. Genelde oranlarınızla aynı fikirdeyim ve uygulama katmanı nesnesini alay etmek için anıtsal çaba harcayan birçok geliştirici örneği gördüm, kabul testi yapmak için daha iyi harcanan çaba.
Robert Harvey

36
Bir yöntemin yapısındaki değişiklik, testlerinizde bir değişikliğe neden olursa, yanlış test yapıyor olabilirsiniz. Ünite testleri, uygulamayı doğrulamamalı, sadece sonucu sağlamalıdır.
Adam Lear

7
@ Anna Lear: Sanırım tasarım / yapısal değişiklikler yapmaktan (refactoring) bahsetti. Tasarım yeterince olgun olmadığından, bunu yapmanın daha iyi bir yolunu bulduğunuzda, bu şekilde çok fazla test yapmanız gerekebilir. Daha yetenekli bir test uzmanı olduğunuzda, testin nerede kötü bir fikir olacağını kolayca fark edebileceğinizi kabul edersiniz (bu sebepten ötürü ve diğerleri), ancak tasarım gerçekten olgun değilse, hala büyük olasılıkla bazı testler yapacaksınız. yol.
n1ckp

13
Bunun da "ilk önce testi yap" fikrinin işe yaramadığını da düşünüyorum. Önce testleri yapmak için tasarım hakkına sahip olmalısınız. Ancak tasarım hakkına sahip olmak, bir şeyler denemenizi ve nasıl çalıştığını görmenizi gerektirir; Bu yüzden, tasarıma sahip olmadan önce testleri gerçekten yapamazsınız ve tasarımın doğru yapılması, nasıl çalıştığını kodlamanızı ve görmenizi gerektirir. Gerçekten bir usta-mimarınız yoksa, bu fikrin nasıl işe yarayacağını gerçekten göremiyorum.
n1ckp

13
@ n1ck TDD aslında bir tasarım alıştırması kadar bir deneme çalışması değildir. Buradaki fikir, tasarımlarınızı mevcut bir tasarıma (kötü / yetersiz olabilir) uydurmak yerine testler yoluyla (hızlı bir şekilde işiniz için makul bir API ortaya çıkardığı için) geliştirmenizdir. Yani hayır, önce testleri yapmak için tasarıma sahip olmanız gerekmez.
Adam Lear

57

Her zaman arayüzlere programlayın.

Bazen sadece bir uygulama olacaktır. Arabirim çıkarma işlemini, gereksinim duyduğumuz zamana kadar geciktirirsek, genellikle gerekmediğini görürüz.


4
Kabul edildi, bir arabirime ihtiyaç duyduğunuzda (yani çalışacak kararlı bir API) bir arabirime programlayın.
Robert Harvey

45
Okuduğumda bu kural dil yapıları gibi arayüzlerle ilgili değil. Bu, yöntemlerini çağırırken bir sınıfın iç çalışmaları hakkında herhangi bir varsayımda bulunmamanız gerektiği ve yalnızca API sözleşmelerine dayanmanız gerektiği anlamına gelir.
Zsolt Török

2
Tamam ilginç bir soru - Ben öncelikle bir .NET geliştiricisi olduğum için arayüzlerim IBusinessManager veya IServiceContract gibi gözüküyor. Benim için bu gezinmek son derece kolaydır (ve genellikle arayüzlerimi başka bir ad alanında [veya başka bir projede] tutarım). Java'yı kullandığımda, aslında bu kafa karıştırıcı buldum (genellikle gördüğüm arayüz uygulamaları .impl ile sonlandırılmıştır ve arayüzlerin tanımı yoktur). Öyleyse bu bir kod standartları sorunu olabilir mi? Tabii ki, java'daki arayüzler kodun darmadağın görünmesini sağlar - ilk bakışta normal sınıflarla tamamen aynı gözükürler.
Watson

5
@Watson: Bir maliyet, Eclipse'deki bir yöntem çağrısında F3'e ('bildirgeye atla') her bastığımda, tek bir uygulamaya değil, arabirime atlarım. Daha sonra kontrol-T, aşağı-ok, uygulamaya geri dönmem gerekiyor. Ayrıca bazı otomatik yeniden yapılandırmaları da engeller - örneğin bir arabirim tanımında bir yöntemi satır içi yapamazsınız.
Tom Anderson

4
@Tom: Efendim, sizi seve seve savaşa dahil ederdim, Eclipse - Intellij. Ancak, bariz bir engeli olan biriyle fiziksel çatışmalara girmemi önleyen olağanüstü bir ahlaki kodum var. BOOM. Eclipse’in kötü olduğunu söylemiyorum, Eksen güçleri savaş makinelerini inşa etmek veya tasarlamak için kullandıysa, İkinci Dünya Savaşı’nın “İki günlük kargalama” olarak bilineceğini söylüyorum. Ciddiyim, hazır IDE'lerde (Intellij / VS + ReSharper) kullandığımda ciladan yoksun olduğunu gördüm. Kendimi birden fazla kez bununla savaşırken buldum - bu çok fazla.
Watson

46

Açık kaynak kodlu bir şey kullanmayın (ya da sizin için Microsoft geliştiricisi olmayan .NET geliştiricileri)

Microsoft geliştirmediyse - burada kullanmıyoruz. ORM - EF kullanmak, IOC - Unity kullanmak, log - kurumsal logging uygulama bloğunu kullanmak istiyor. Pek çok daha iyi kütüphane var - ama ben her zaman gelişim dünyasının dolar menüsünden sipariş vermekten mahrum kaldım. Microsoft Best Practices’i her duyduğuma yemin ederim, "McDonald's Beslenme Yönergeleri" olduğunu düşünüyorum. Tabii, eğer onları takip edersen muhtemelen yaşayacaksın, ama aynı zamanda yetersiz beslenmiş ve fazla kilolu olacaksın.

  • Not Bu olmayabilir sizin en iyi uygulama, ancak ortak bir kimse hemen hemen her yerde ben çalıştığım takip var.

13
Kulağa korkunç geliyor ... = (Muhtemelen diğer tarafta çok
fazlayım

Bu şekilde olmamalı. Bir kütüphane, yalnızca kimin yaptığını düşünmeden değil değeri için seçilmelidir. Örneğin, EF'i seviyorum ama Enterprise Library ile ilgili kötü bir deneyimim oldu ve FluentValidation, log4net ve Elmah gibi doğrulama ve kayıt için daha iyi araçlar buldum.
Matteo Mosca

4
IBM ^ wMicrosoft
Christopher Mahan

17
Aynada yansıtma sürümü de vardır, yani Asla Microsoft hiçbir şey kullanmayın veya ödemeniz gereken hiçbir şeyi kullanmayın.
Richard Gadsden

5
Yaygın olarak tutulan bir dogmanın olmadığı bir organizasyonda çalışacak kadar şanslıyım, ancak ticari çözümleri benimsediğimiz yerlerde çok fazla acı var. Ticari çözümün bir kısmı pek işe yaramadığında sorun ortaya çıkıyor. Açık kaynak olduğunda, kaynağa bakabilir (nihai dokümantasyon) ve neyin yanlış gittiğini öğrenebilirsiniz. Kapalı kaynak sayesinde, yaptığınız ürün hakkında daha az şey bilen teknik destek bilgisine erişim ayrıcalığını ödemek zorundasınız . Ve bu sadece mevcut 'düzeltme'.
SingleNegationElimination

40

Nesne yönlendirme

Varsayım var, sadece kod "nesne yönelimli" olduğundan, sihirli bir şekilde iyidir. Böylece insanlar işlevselliği sınıflara ve yöntemlere, sadece nesneye yönelik olmak için sıkmaya devam ediyorlar.


7
Object Orientation'ın sağladığı organizasyondan yararlanmadan, önemli boyutta bir yazılım sistemi kurmayı hayal edemiyorum.
Robert Harvey

18
Robert. Unix nesne yönelimli değildir ve kesinlikle önemli boyutta bir yazılım sistemi olarak nitelendirir. Aynı zamanda oldukça popüler görünüyor (Mac OSX, iPhone, Android telefonlar, vb. Düşünün)
Christopher Mahan

7
Demek istediğim, en uygun metodolojiyi kullanmamız gerektiğini düşünüyorum. İnsanları, "nesne yönelimli" olduğu için zahmetli ve pek anlamlı olmayan yöntemler ve sınıflar kullandıklarını gördüm. Bu kargo tarikatı.
LennyProgramcılar

8
Gümüş mermi yok. İşlevsel Programlama (Haskell) nesne yönelimli olmadan oldukça başarılıdır. Günün sonunda, birden fazla aracınız var ve eldeki görev için en iyi ürün çeşitliliğini seçmek sizin işiniz.
Matthieu M.

9
İşin komik yanı, sınıfları, polimorfizmi ve benzerlerini kullanmanın yanı sıra, nesne yönelimli kodun çoğunun aslında prosedürel kod olmasıdır.
Oliver Weiler,

35

Tüm kodlar yorumlanmalı.

Hayır, olmamalıydı. Bir süre açık kodunuz var, örneğin ayarlayıcılar özel bir şey yapana kadar yorumlanmamalıdır. Ayrıca, neden bunu yorumlayayım:

/** hey you, if didn't get, it's logger. */
private static Logger logger = LoggerFactory.getLogger(MyClass.class);

13
Tüm kodlar anlaşılabilir olmalıdır . Yorumlar bunda önemli bir araç, ancak yalnızca birinden uzak.
Trevel

Kesinlikle, kod anlaşılabilir olmalıdır. Ancak, örneğin yöntem adı için hiçbir şey eklemeyen bir yorum yazmak için hiçbir neden yoktur. Eğer yazarsanız /** sets rank. */ void setRank(int rank) { this.rank = rank; }, yorumu aptalca olarak kabul ediyorum. Neden yazılı
Vladimir Ivanov

2
Oluşturulan belgeler. Yani ne /** */biçim yerine içindir /* */biçimi comment. Veya .NET için olurdu///
Berin Loritsch

10
Kullanılması }//end if, }//end for, }//end whileşimdiye kadar karşılaştığınız yorumlama savurgan en iyi örneğidir. Bunu açılış açısının 2 satırdan fazla olmadığı yerlerde defalarca gördüm. Eğer IMHO eğer ihtiyaç bu daha sonra bir yorum kodunuzu ihtiyaçlarını ... yeniden faktoring veya 20 $ kadar Midilli ve parantezi eşleşen vurgular bir IDE / Yazı editörü satın almanız gerekir.
scunliffe

7
Kod "nasıl" deyin. Yorumlar "neden" demek zorunda.

32

Metodolojiler, özellikle israf. Yetişkinlerin "Scrum Master" ibaresini kullandığını duyduğumda düz bir yüz tutamıyorum. Metodoloji X'in bazı yönlerinin şirketleri için çalışmadığını, sadece Guru So-and-So'nun söylediğinin protesto edişini duymaktan çok yoruldum. Metodoloji X. "Scrum daha sert, yapmalısın, Padawan öğrencim!"

Çevik metodolojilerde bilgelik külçeleri vardır --- birçoğu --- ama gag refleksimle savaşamayacak kadar gübreye sık sık dokunuyorlar. Vikipedi'nin scrum sayfasından bu biraz alın :

Scrum'da bir takım roller tanımlanmıştır. Tüm roller, gelişim sürecine katılımlarının doğasına bağlı olarak, domuz ve tavuk gibi iki farklı gruba ayrılır.

Gerçekten mi? Domuzlar ve tavuklar mı diyorsun? Büyüleyici! Bunu patronuma atmak için sabırsızlanıyorum ...


İlginç. Bir ölçüde katılıyorum. Yine de bu son kısmı ile: Onlara istediğini söyle, onlar anımsatıcı, hepsi bu.
Steven Evers

12
+1 ... haklısın, bunu ciddiye almak zor. <büyük patlama sesi> * Ben YAZICI'yım * </voice>
GrandmasterB

2
Ve benzetmeler. Bana kilise vaazlarını ya da kendi kendine yardım eden guruların (ve komedyenlerin) meşhur fıkra türlerini hatırlatıyor: "Arkadaşım Steve'i al. Steve, karısı Sheryl ile sürekli tartışıyordu. Bu ikisi saatlerce devam ederdi. Evliliklerinin gerçek tehlikede olduğu nokta. O zaman, bir gün ... "Bu tür didaktik iplikler diğer alanlarda beni rahatsız etmiyor, ama mühendislik bilimlerinde çoğaldıklarını görmekten nefret ediyorum.
evadeflow

2
Peki ya Scrum Ninjalar?
Berin Loritsch

1
"Domuz ve Tavuk" karşılaştırmasına katılmıyorum ... doğrudan Çevik Manifesto karşısında uçuyor. "Sözleşme müzakeresi konusunda müşteri işbirliği". Müşteriler, proje ekibi olarak proje başarısında kazanılmış (moreso değilse). Bazı rollere domuz ve diğer rol tavukları çağırmak, IMHO'nun başarılı projelere giden en büyük engel olduğu "bize ve onlara karşı" zihniyetini oluşturuyor.
Michael Brown

25

Nesne İlişkisel Haritalama ... http://en.wikipedia.org/wiki/Object-relational_mapping

Verilerimden asla soyutlanmak istemiyorum ve bu hassas kontrol ve optimizasyonu da kaybetmek istemiyorum. Bu sistemlerdeki deneyimim son derece zayıf ... Bu soyutlama katmanlarının ürettiği sorgular, sarsıntıdan gördüğümden daha da kötü.


19
Erken optimizasyon tüm kötülüklerin köküdür. Yavaş kod, gerçek hayatta, elde edilemez kodla karşılaştırıldığında, nadiren yalnızca bir problemdir. Bir ORM kullanın, ardından soyutlamayı sadece ihtiyacınız olduğu yerde kesin.
Fishtoaster

28
ORM'ler 80-20 bir araçtır. Bu sonsuz tesisat kodunu bir süre sonra yazmak için bu kadar yorucu hale gelen% 80 CRUD'ları kullanmaları amaçlanıyor. Diğer% 20, saklı yordamları kullanma ve sıradan SQL sorguları yazma gibi daha "geleneksel" yollarla yapılabilir.
Robert Harvey

18
@Fishtoaster: "Küçük verimleri unutmalıyız, zamanın% 97'sini söyleyelim: erken optimizasyon tüm kötülüklerin köküdür. Ancak bu kritik% 3'teki fırsatlarımızı aşmamalıyız."
Robert Harvey

5
@Robert Harcey: Doğrudan bir alıntı kullanmamamın bir nedeni var. Çoğu programcının verimliliğe çok fazla odaklandığını düşünüyorum - bu sorunların bir kaçının çözmesi gereken bir problem. Kuşkusuz, diğerlerinden daha önemli olduğu bazı alanlar vardır, ancak sürdürülebilirlik ve genişletilebilirlik her yerde bir sorundur. Başka bir değiştirilmiş alıntı: "Çalışmasını sağlayın, bakımını sağlayın, okunabilir hale getirin, genişletilebilir yapın, test edilebilir hale getirin ve sonra zamanınız varsa ve ihtiyacınız olursa ortaya çıkar, hızlı olun."
Fishtoaster

12
@Craig: İfadenizdeki ironiyi nasıl tanımadınız? Bir ORM'den nasıl iyi bir performans alacağınızı öğrenmek için bir yıla ihtiyaç duymak, üretilen SQL'i "kontrol etmek" ve depolanmış prosedürleri enjekte etmek gibi ORM'lere karşı mükemmel bir argümandır . Bunun için bir bilginiz varsa, ORM'yi tamamen atlayacak bilgiye sahipsiniz.
Nicholas Knight,

22

İşlev isimlerini İngilizce cümleleriymiş gibi yazmak:

Draw_Foo()
Write_Foo()
Create_Foo()

Bu harika görünebilir, ancak bir API öğrenirken çok acı verici. "Foo ile başlayan her şey" için bir dizin aramak ne kadar kolay?

Foo_Draw()
Foo_Write()
Foo_Create()

vb.


2
Muhtemelen TM'nin fonksiyon listesine Foo yazmak kadar kolay.
Josh K

68
Eğer bunu istiyorum aslında ediyorum gibi geliyor Foo.Draw(), Foo.Write()ve Foo.Create()Yapabileceğin böylece Foo.methods.sortyaFoo.methods.grep([what I seek]).sort
Inaimathi

7
'Get' ile başlamak başka bir örnektir.
JeffO

1
Amaç-c dünyasından geliyorum ve java (diğer hayatım) yaptığımda ayrıntılı yöntem isimlerini özledim. Kod tamamlama çalışmaya başladığından beri, ben de fazladan yazarak bir sorun bulamadım.

2
@Scott Whitlock: Değil o bazı NET geliştiricileri için tarihi geçmiş, iirc, VS 2008 yapmadım. 2010 olsa, ve fantastik.
Steven Evers

22

MVC - Sıklıkla, birçok web tasarımı problemini MVC yaklaşımına dahil etmenin, basitlik veya yapıdan ziyade bir çerçeveyi (raylar vb.) Mutlu etmekten daha fazla olduğunu anlıyorum. MVC, basitlik üzerinde aşırı iskele değerine değer veren "mimarlık astronotlarının" favorisidir. YMMV.

sınıf tabanlı OO - bence değişebilir devletin karmaşık yapılarını teşvik ediyor. Yıllar boyunca sınıf temelli OO için bulduğum tek zorlayıcı vakalar, herhangi bir OO kitabının 1. bölümünü oluşturan corny "shape-> dikdörtgen -> kare" örnekleridir.


4
ASP.NET ve ASP.NET MVC'de web geliştirme yaptım ve MVC iskele gibi görünse de, pek çok sebepten dolayı ASP.NET'i tercih ediyorum: sadelik, bakım kolaylığı ve işaretleme üzerinde son derece hassas kontrol. Her şeyin bir yeri vardır ve her ne kadar biraz tekrarlayıcı görünse de, sürdürmek bir zevktir. Tamamen özelleştirilebilir, bu nedenle kutudan çıkan bir davranışı sevmiyorsanız, değiştirebilirsiniz.
Robert Harvey

1
OO ile ilgili olarak, bunu yapmanın iyi ve kötü yolları vardır. Miras çok fazla abartılıyor ve gerçek dünyada, pek çok kitabın inanacağından çok daha fazla kullanılıyor; Halen OO dünyasında bile, daha işlevsel, değişmez bir gelişme tarzına doğru bir eğilim var.
Robert Harvey

1
MVC'den bahsettiği için +1. MVC kavramı (veri katmanı mantığını, sunum mantığını ve arka plan mantığını ayırmak) fiziksel olarak kod parçacıklarını içeren dosyaların karmasını içeren karmaşık bir klasör hiyerarşisine ayırmak aptalcadır. Bu fenomeni PHP'nin isim alanı desteğinden yoksun bıraktıktan ve yeni başlayan geliştiricilere 'en yeni şey' olarak yüceltmekte olan teknikleri suçluyorum. Çok basit, veritabanı erişimcileri, GUI ve arka plan mantığı (ve gerektiğinde alt ad alanları) için bir ad alanı oluşturun.
Evan Plaice

3
OO’ya gelince, projeniz karmaşıklığı yönetmenin önemli olduğu bir boyuta gelinceye kadar faydalarını görmeyeceksiniz. Mümkün olan her durumda tek bir sorumluluk ilkesine uyun ve kodunuz halka açıksa erişilebilir (ör. Bir .dll için), kodu daha güvenli hale getirmek ve API'yi basitleştirmek için mümkün olan her yerde sınıfların / yöntemlerin / özelliklerin iç uygulamasını gizleyin.
Evan Plaice

1
Ben şahsen, shape-> rectangle-> square örneklerini, op'a karşı en zarif argümanlardan biri olarak buluyorum . örneğin, Square(10).Draw()bunun için yeterli Rectangle(10, 10).Draw(). Bu yüzden kare anlamına gelir dikdörtgen bir alt sınıfıdır. Fakat mySquare.setWidthHeight(5,10)saçmalıktır (IE, Liskov ikame prensibini geçememiştir), bir kare farklı bir yüksekliğe ve genişliğe sahip olamaz, ancak bir dikdörtgen olabilir, böylece dikdörtgenin bir kare alt sınıfı olduğu anlamına gelir. Bu diğer bağlamlarda "Çember, Elips problemi" olarak da bilinir
SingleNegationElimination

22

YAGNI

( İhtiyacın olmayacak )

Bu yaklaşım bana, dikkatli bir planlama yapmadan önce bu özellikleri ekleyeceğimiz mevcut bir kod temeli üzerinde özellikler uygulamak zorunda kalmamın saatlerce sürmesine mal oldu.

Benim fikirlerim YAGNI nedeniyle sık sık reddedildi ve çoğu zaman birileri bu karar için daha sonra ödemek zorunda kaldı.

(Tabii ki, iyi tasarlanmış bir kod tabanının da özelliklerin daha sonra eklenmesine izin vereceğini, ancak gerçeğin farklı olduğunu iddia edebilir)


15
YAGNI ile aynı fikirdeyim, ama neye ulaştığını görüyorum. YAGNI'nin amacı, her şeyi en ufak ayrıntıya kadar planlamak isteyen insanlarla ilgilenmektir . Yine de ondan dokuz kez, mühendis kuralları altında mazeret olarak veya planlamayı tamamen atlamak için kullanılır.
Jason Baker,

12
P. Floyd, @Jason Baker: +1 Kesinlikle doğru. Eski sözler burada geçerlidir "laboratuarda aylar kütüphanede saatlerce tasarruf sağlayabilir"
Steven Evers

Bir spesifikasyon genellikle uygulamanın çoğunu ve arayüzün bir kısmını açık bırakacaktır (ve çoğu zaman gerekir). Spesifikasyonda doğrudan olmayan ancak spekülasyonu uygulamak için gereken her şey, bir uygulama kararının, kullanıcı tarafından görülebilir bir arayüzün veya başka bir şeyin olup olmadığına, şartnamenin dolaylı bir şartıdır. Bir özellik özelliklerde değilse ve özelliklerde belirtilmemişse, o zaman buna ihtiyacınız yoktur. Bu nasıl kafa karıştırıcı olabilir?
SingleNegationElimination

1
@TokenMacGuy en önemli yönü spec kısmı tarafından ima edilmiştir . Görüşlerin çok değiştiği yer burasıdır.
Sean Patrick Floyd,

20

SQL için

  1. Tetikleyicileri kullanma
  2. Tabloları her zaman görünümlerin arkasına gizle

Sırayla:

  1. Onlar yeri olan bir özelliktir. Bir tabloya yönelik birden fazla güncelleme yolunuz mu var veya% 100 denetleme gerektiriyor mu?

  2. Sadece neden? Bir sözleşmeyi sürdürmek için refactoring yapıyor olsaydım, ama halkın herhangi bir tablo değişikliği ile eşleşmesi için görünümü değiştirdiğini okuduğumda olmazdım

Düzenle:

Sayı 3: EXISTS ile * önleme. 1/0 dene. İşe yarıyor. Sütun listesi, SQL standardına göre değerlendirilmez. Sayfa 191


3
# 2 en iyi uygulamadır?
Hogan


1
@Hogan: Temel tabloyu basit bir şekilde yansıtan bir görünüm, temel tabloyu doğrudan kullanmanın güvenliği yoktur. Bir güvenlik kullanıcısı tablosuna katılırsanız veya bazı sütunları gizlerseniz, yeterince adil olur. Ancak her sütunu tablodan veya görünümden SEÇİN: fark yok. Şahsen ben zaten saklı procs kullanırım.
gbn

3
@Hogan: Ben :-) SQL Server hakkında bir şeyler biliyor stackoverflow.com/users/27535/gbn Demek GRANT SELECT masaya görünümü SEÇ ise SEÇ AÇIK VIEW VERMEYİ için hiçbir farklı olduğunu * TABLODAN
GBN

1
@gbn: Katılıyorum. Arada fark yok. Bence aynı şeyi söylüyor olabiliriz. Sanırım orijinal yorumum ("# 2 en iyi uygulama nedir?"), Kişisel deneyimlerime dayanarak, görüşlerin (tetikleyiciler gibi) doğru kullanılmadıklarından daha fazla kullanılmadığını belirtti. Böylece böyle bir en iyi uygulama, istismarın arttırılmamasına, ancak istismara yol açacaktır. En iyi uygulama olarak kabul edilirseniz% 100 haklısınızdır, bu kötüdür.
Hogan

20

Çoğunlukla tasarım desenleri. Aşırı kullanılmış ve az kullanılmışlardır.


13
+1 Tasarım Desenlerinin nasıl güzel ya da zarif çözümler olduğunu hala göremiyorum. Dil eksikliklerine geçici çözümlerdir, başka bir şey yapmazlar.
Oliver Weiler,

2
Sadece dilin kendisini kullanarak, dil kokusunu yok etmek için bir çaba olarak görün.
Filip Dupanović

15

Tek Sorumluluk İlkesi

("her sınıfın yalnızca tek bir sorumluluğu olmalı; başka bir deyişle, her sınıfın değişmesi için tek ve tek neden olması gerekir")

Katılmıyorum. Ben düşünüyorum yöntem değiştirmek için tek bir neden olmalı ve bir sınıftaki tüm yöntemler bir olmalı bire başka mantıklı bir ilişki , ancak sınıf kendisi aslında belki yapmak birkaç (ilgili) şeyler.

Tecrübelerime göre, bu prensip çok fazla aşırı gayretle uygulanmakta ve pek çok minik tek yöntem sınıfıyla son buluyorsunuz. Çalıştığım çevik dükkanlar da bunu yaptı.

.Net API'sinin yaratıcılarının bu tür bir zihniyete sahip olup olmadığını düşünün: List.Sort (), List.Reverse (), List.Find () vs. yerine ListSorter, ListReverser ve ListSearcher sınıflarına sahibiz!

Artık SRP'ye (ki teoride kendisi fena değil) karşı tartışmak yerine , uzun soluklu anekdot deneyimlerimin bir kısmını paylaşacağım:


Çalıştığım bir yerde , beş sınıftan oluşan çok basit bir maksimum akış çözücü yazdım : bir düğüm, bir grafik, bir grafik oluşturucu, bir grafik çözücü ve bir grafik çözücüyü kullanmak için bir grafik gerçek dünya problemi. Hiçbiri özellikle karmaşık ya da uzundu (çözücü en fazla ~ 150 çizgide en uzundu). Bununla birlikte, sınıfların çok fazla “sorumluluğu” olduğuna karar verildi, bu nedenle iş arkadaşlarım kodu yeniden düzenlemeye başladılar. Tamamlandığında, 5 sınıfım, toplam kod satırı orijinalleri üç kattan fazla olan 25 sınıfa genişletildi. Kodun akışı artık açık değildi ve yeni birim testlerinin amacı değildi; Şimdi kendi kodumun ne yaptığını bulmakta zorlandım.


Aynı yerde, hemen hemen her sınıfın sadece tek bir metodu vardı (sadece "sorumluluğu"). Programın içindeki akışı takip etmek neredeyse imkansızdı ve çoğu birim testi , her ikisinin de amacı benim için aynı derecede gizemli olan bu sınıfın başka bir sınıftan kod dediğini test etmekten ibaretti . Kelimenin tam anlamıyla, sadece düzinelerce (IMO) olması gereken yüzlerce sınıf vardı. Her sınıf yalnızca bir "şey" yaptı , ancak "AdminUserCreationAttemptorFactory" gibi adlandırma kuralları olsa bile sınıflar arasındaki ilişkiyi söylemek zordu.


Başka bir yerde (aynı zamanda yalnızca tek bir yöntem zihniyetine sahip olması gereken sınıfları da vardı ), belirli bir operasyon sırasında zamanın% 95'ini kaplayan bir yöntemi optimize etmeye çalışıyorduk. (Aptalca) biraz optimize ettikten sonra, neden dikkatimi bir bajilyon defau olarak adlandırıldığına yönelttim. Bir sınıftaki bir döngüde çağrılıyordu ... onun yöntemi başka bir sınıftaki bir döngüde çağrılıyordu ... ki bu da bir döngüde çağrılıyordu.

Hepsi söylendi, 13 sınıfa yayılmış beş düzey döngü vardı (ciddi olarak). Bir sınıfın gerçekte ne yaptığını sadece bakarak bakarak belirlemek imkansızdı - hangi metodun ne dendiğini ve bu metotların hangi metotların adlandırıldığını vb. Hepsi tek bir yöntemde toplanmış olsaydı, sorunlu yöntemimiz hemen anlaşılan beş döngü seviyesinin içine yerleştirilmiş ancak 70 satır uzunluğunda olurdu.

Bu 13 sınıfı bir sınıfa yeniden ateşleme isteğim reddedildi.


6
Birisi "Desen Ateşi" veya bu durumda bu "İlke Ateşi" gibi görünüyor. Liste sınıfı SRP'yi ihlal etmiyor. Tüm işlevleri, bir nesne koleksiyonunu manipüle ederek bir amaca hizmet eder. Sınıfta sadece bir işleve sahip olmak bana aşırı kulağa benziyor. SRP'nin arkasındaki ilke, bir kod biriminin (yöntem, sınıf veya kütüphane olabilir) özünde belirtilebilecek tek bir sorumluluğa sahip olması gerektiğidir.
Michael Brown

3
Bu tür deliliği saf düz fonksiyonel kod yazmayı imkansız bulan insanlardan görmeye başladım. Dünyadaki her problemin bir kalıp kitaptan çözülebileceğini öğretmek çok fazla. Pragmatizm hakkında yeterli düşünce yok. Sizin gibi bazı sınıf tabanlı OO kodları gördüm, o kadar korkunç ki onu takip etmek tamamen imkansız. Ve iri ve şişirilmiş.
Çabucak_şimdi

3
Burada 2. yorum. Birçok "ilke" uygulanmaktadır. Tam tersini yapmanın bazen uygun olduğu iyi fikirler olan birçok şey var. İYİ programcılar mola kurallarını ne zaman biliyorum. Kurallar "kurallar" olmadığı için, "aptalca bir fikir olduğu durumlar hariç" çoğu zaman iyi uygulamaların ifadeleridir.
Çabucak_şimdi

".Net API'sinin yaratıcılarının bu tür bir zihniyete sahip olup olmadığını düşünün: List.Sort (), List.Reverse (), List.Find () vs. yerine ListSorter, ListReverser ve ListSearcher sınıflarına sahibiz. !". Bu tam olarak C ++ 'da yapılır ve bu harikadır . Algoritmalar veri yapılarından ayrılır, bu yüzden kendi kabını yazarsam, standart kütüphaneyle çalışan tüm algoritmalar sadece yeni kapsayıcımla çalışır. Sıralamak istediğiniz her yeni konteynır için yeni bir sıralama işlevi yazan .Net ülkesinde korkunç olmalı.
Mankarse

14

Şimdi, Temiz Kod'dan bahsettiğinize göre, bazı iyi fikirler içeriyor olsa da, tüm metotları alt metotlara, alt tortulardakileri vb. Birkaç on satırlık yöntem yerine yirmi (sözde iyi adlandırılmış) tek gömlek tercih etmeniz gerekiyor. Açıkçası birisi temiz olduğunu düşünüyor, ama bana göre orijinal versiyondan çok daha kötü görünüyor.

Ayrıca, basit basit şeyleri değiştirmek gibi

0 == memberArray.length

sınıfın kendi yöntemine yapılan çağrıyı içeren bir sınıf içinde

isEmpty()

sorgulanabilir bir "iyileştirme" olan IMHO. Ekleme: Fark, ilk kontrolün yaptığı şeyi aynen yaptığıdır: dizi uzunluğunun 0 olup olmadığını kontrol eder. Tamam, isEmpty()dizi uzunluğunu da kontrol edebilir. Ancak bu şekilde de uygulanabilir:

return null != memberArray ? 0 == memberArray.length : true;

Yani, örtük bir null çek içerir! Bu, genel bir yöntem için iyi bir davranış olabilir - dizi null olursa, o zaman bir şey kesinlikle boştur - ancak sınıf içindekilerden bahsederken, bu o kadar iyi değildir. Dışarıya kapsülleme bir zorunluluk olsa da, sınıf sınıfının sınıfta neler olduğunu tam olarak bilmesi gerekir. Sınıfı kendinden kapatamazsınız . Açık, örtük olmaktan iyidir.


Bu, uzun metodları yıkmanın veya mantıksal karşılaştırmalar yapmanın iyi olmadığını söylemek değildir; Elbette öyle, ama ne dereceye kadar yapmak - tatlı nokta nerede - tabii ki bir zevk meselesi. Uzun bir yöntemi yıkmak daha fazla yöntemle sonuçlanır ve bu ücretsiz değildir. Gerçekten neler olup bittiğini görmek için, kaynak kodun etrafından atlamak zorundasınız, eğer bütün bunlar tek bir yöntemde olsaydı bir bakışta görebiliyordunuz.

Hatta bazı durumlarda 1 satırlı bir yöntemin bir yöntem olmayı hak edemeyecek kadar kısa olduğunu söyleyeceğim kadar ileri giderdim .


6
Bunu nadiren bir sorun olarak görüyorum. Çoğunlukla bunun nedeni genellikle çok az değil, tek bir yöntemde çok fazla görmemdir. Bununla birlikte, bazı çalışmalara göre yöntemlerde çok düşük karmaşıklık aynı zamanda orta derecede düşük karmaşıklıktan biraz daha yüksek bir hata oranına sahiptir. enerjy.com/blog/?p=198
MIA

Evet, bu kesinlikle yalnızca Temiz Kodda bir sorundur. Gerçek hayatta, yöntemlerin dediğiniz gibi çok uzun olma eğilimindedir. Ama bu eğriyi görmek ilginç! Gerçekten, işler mümkün olduğu kadar basit yapılmalı, ancak daha basit olmamalıdır.
Joonas Pulakka,

1
İkinci örneğinizi daha okunaklı buluyorum ve herkese açık hale getiriyorsanız, bu form (veya sınıfın kendisinde bir Length özelliği gibi) buna benzer bir zorunluluktur.
Robert Harvey,

@Robert Harvey: İkinci örnek kamuya açık bir yöntemdir, ancak bunu sınıfın içinden çağırmak sorgulanabilir, çünkü nasıl uygulandığını görmeden önce ne yaptığını tam olarak bilmiyorsunuz. Mesela null değerini kontrol edebilir. Yukarıdaki ekime bakınız.
Joonas Pulakka

@Joonas: Yeterince adil.
Robert Harvey

13

"Yorumlarla liberal ol"

Yorumlar kesinlikle iyi bir şeydir, ancak yeterince fazlası olmadığı kadar kötüsü de çok kötü. Neden? Çok fazla gereksiz kişi görürlerse insanlar yorumları ayarlama eğilimindedir. Mükemmel bir şekilde kendi kendine belgelendirme koduna sahip olabileceğinizi söylemiyorum, ancak açıklama için yorum gerektiren kodların kullanılması tercih edilir.


1
kendini belgeleyen kod kesinlikle güzel. Bununla birlikte, basit hesaplamalar gibi bir şeylerin yanında yorum yapmaktan hoşlanıyorum (geri dönüş tipi veya döndürülen değerin ne olduğunu ifade etmek için). Ancak yorumlarınız kodun kendisinden daha fazla kelimeye ihtiyaç duyuyorsa, muhtemelen kodu tekrar yazma zamanı gelmiştir.
sova

6
Sova'nın bunu koyma şekline katılıyorum. Yorumlara temiz kod tercih edilir.
riwalk

4
Hala içeride "neden" var!

Nedenini açıklayan yorumları tercih ederim. Bu, bakmaya geldiğimde kodun tersine mühendislik konusunda daha az düşünmem gerektiği anlamına geliyor.
Çabucak_ancak

12

GoTo Zararlı Gördü

Bir durum makinesi uyguluyorsanız, bir GOTO ifadesi "yapılandırılmış programlama" yaklaşımından daha anlamlı olabilir (okunabilirlik ve verimli kod). Yeni bir işte yazdığım ilk kodun sadece bir değil birkaç ifadeye dahil olması bazı meslektaşları gerçekten endişelendiriyordu. Neyse ki, bu özel durumda en iyi çözüm olduğunun farkına varacak kadar akıllılardı.

Kurallarında mantıklı ve belgelenmiş istisnalara izin vermeyen herhangi bir "en iyi uygulama" sadece oldukça korkutucu.


16
Dokuz yıldan beri tek bir açıklama yapmadan programlama yapıyorum (dediğiniz gibi birkaç devlet makinesi dahil). Fikrinizi yeni fikirlere genişletin.
riwalk,

3
@Mattieu M. - anladım - GOTO'yu yapısal kontrol ifadeleriyle karıştırmak mantıklı değil. (Bu saf C idi ve bir sorun değildi.
MZB

1
@ Stargazer2 - basit bir FSM ile durumun bir değişkenin içine konmasına ve bir prosedür çağırmak için bir indeks olarak kullanılmasına (hesaplanan GOTO ile aynı değil mi?) Program sayacını kullanmaktan daha açık / daha hızlı kod vermesine bağlıdır. FSM durumu olarak. Bunu çoğu durumda en iyi çözüm, bazı durumlarda en iyi çözüm olarak savunmuyorum. Fikrinizi alternatif yaklaşımlara genişletin.
MZB

5
@MZB, bir işlev çağrısının da yalnızca hesaplanmış bir GOTO olduğunu kabul etmiyor musunuz? Aynısı / süre / if / else / anahtar yapıları için de geçerlidir. Dil tasarımcıları bir nedenle program sayacındaki doğrudan değişiklikleri soyutlar. Goto kullanmayın.
riwalk

3
Doğrudan bir statemachine uygulamak muhtemelen bir antipattern'dir. Durumları ve geçişleri kelimenin tam anlamıyla ifade etmeden bir devlet makinesine sahip olmanın birçok yolu vardır. örneğin,import re
SingleNegationElimination 19:11

12

Kodları test edilebilir hale getirmek için yaptığımız fedakarlıklar

Kodumu test edilebilir hale getirmek için birçok çemberin içinden atlıyorum, ancak seçim yapsam bile söylemeyeceğim gibi davranmadım. Ancak, çoğu zaman insanların “en iyi uygulamalar” olduğu fikrini zorladığını duyuyorum. Bu uygulamalar şunları içerir (.Net dilinde yazılmıştır ancak diğer diller için de geçerlidir) :

  • Her sınıf için bir arayüz oluşturma . Bu, ele alınacak sınıfların (dosyaların) sayısını iki katına çıkarır ve kodu çoğaltır. Evet, arayüz programlama iyidir, fakat kamu / özel tanımlayıcıların anlamı budur.
  • Başlangıçta başlatılmayan her sınıfın bir fabrikaya ihtiyacı vardır. Açıkçası, new MyClass()bir fabrika yazmaktan çok daha basittir, ama şimdi onu yaratan yöntem yalıtılmış olarak test edilemez. Bu gerçek olmasa, şu an yaptığım fabrika sınıfı sayısının sadece 1 / 20'sini yapardım.
  • Her sınıfta herkesi açık yapın; bu da sınıflarda erişim tanımlayıcılarına erişim amacını ortadan kaldırır. Ancak, halka açık olmayan sınıflara diğer projelerden erişilemez (ve bu nedenle test edilebilir), bu nedenle diğer tek seçenek tüm test kodunu aynı projeye taşımaktır (ve böylece nihai ürünle serbest bırakmaktır).
  • Bağımlılık Enjeksiyonu. Açıkça her diğer sınıfa vermek zorundayım ki bir alan kullanıyorum ve bir yapıcı-parametresi sadece ihtiyacım olduğunda onları yaratmaktan çok daha fazla iş yapıyor; ama o zaman bu sınıfı ayrı ayrı test edemiyorum.
  • Bu kadar çok baş ağrısına yol açan Tek Sorumluluk İlkesi, onu kendi cevabına taşıdım .

Peki bunu düzeltmek için ne yapabiliriz? Dil mimarisinde ciddi bir değişime ihtiyacımız var:

  • Sınıflarla dalga geçme yeteneğine ihtiyacımız var.
  • Özel iç sınıf yöntemlerini, başka bir projeden test etme yeteneğine ihtiyacımız olacaktı (bu bir güvenlik açığı gibi görünebilir, ancak sınanan testçi sınıflarını adlandırmaya zorlanırsa bir sorun göremiyorum) .
  • Bağımlılık enjeksiyonu (veya hizmet yeri) ve mevcut fabrika düzenimize eşdeğer bir şey , dilin temel bir parçası olmalıdır .

Kısacası, sıfırdan test edilebilir bir akılda kalmadan tasarlanmış bir dile ihtiyacımız var .


Sanırım TypeMock'ı hiç duymadın mı? Bu, alaycı sınıfları, özel eşyaları, statiği (fabrika), her şeyi sağlar.
Allon Guralnek,

@ Allon: Bende var ama ücretsiz değil, çoğu insan için bir seçenek değil.
BlueRaja - Danny Pflughoeft

Çok fazla fabrika sınıfı yazmak zorundaysanız, yanlış bir şey yapıyorsunuz demektir. Akıllı DI kütüphaneleri (örneğin, C # için Autofac), kendiniz herhangi bir kazan plakası yazmadan fabrikalar için Func <T>, Lazy <T>, Delegeler vb.
gix

10

Uygulamaları Katmanlara Ayırma; Veri Katmanı, İş Katmanı, Kullanıcı Arabirimi

Bundan hoşlanmamamın ana nedeni, bu yöntemi izleyen çoğu yerin, bunu yapmak için çok kırılgan çerçeveleri kullanmasıdır. IE UI Katmanı, iş katmanı nesneleriyle başa çıkmak için elle kodlanmıştır, iş katmanı nesneleri iş kuralları ve veritabanıyla başa çıkmak için elle kodlanmıştır, veritabanı SQL'dir ve halihazırda kırılgandır ve değişiklikten hoşlanmayan "DBA" grubu tarafından yönetilmektedir.

Bu neden kötü? En yaygın geliştirme isteği "X ekranında Y olan bir alana ihtiyacım var" olabilir. Bang! Her bir katmanı etkileyen yeni bir özelliğiniz var ve katmanları farklı programlayıcılarla ayırırsanız, çok basit bir değişiklik için, birden fazla kişiyi ve grubu içeren büyük bir sorun haline geldi.

Ek olarak, kaç kez böyle bir şey yapan tartışmalarda bulunduğumu bilmiyorum. "Ad alanı maksimum 30 uzunluğa sahip, bu bir UI katmanı mı, işletme katmanı mı yoksa veri katmanı sorunu mu?" Ve yüzlerce argüman var ve doğru cevap yok. Cevap aynıdır, tüm katmanları etkiler, kullanıcı arayüzünü aptallaştırmak istemez ve tüm katmanlardan geçmek ve veritabanında başarısız olmak istemezsiniz, böylece kullanıcı girişinin çok uzun olduğunu fark eder. Değiştirirseniz, tüm katmanları vb. Etkiler.

"Katmanlar" da sızıntı yapma eğilimindedir; Herhangi bir katman işlem / makine sınırları ile fiziksel olarak ayrılırsa (IE web kullanıcı arayüzü ve iş geçmişi mantığı), her şeyin makul şekilde çalışmasını sağlamak için kurallar çoğaltılır. Diğer bir deyişle, bir işletme mantığı kullanıcı arabiriminde sona ermektedir, bir "iş kuralı" olsa da, kullanıcının kullanıcı arabirimine yanıt vermesi gerekir.

Kullanılan çerçeve veya kullanılan mimari, küçük değişikliklere ve sızıntılara, yani meta verilere dayalı ve tüm katmanlar arasında dinamik olarak ayarlanmışsa, daha az acı verici olabilir. Ancak bu çerçevelerin çoğu, her küçük değişiklik için UI değişiklikleri, iş katmanı değişiklikleri ve veritabanı değişiklikleri gerektiren ve tekniğin üretmesi gerekenden daha fazla iş ve daha az yardım gerektiren bir kraliyet acısı.

Muhtemelen bunun için çarpacağım, ama işte :)


+1, en son ayrıntıdaki en son çalıştığım yer gibi görünüyor! Katmanlı uygulamalara prensipte saygı duyuyorum, ancak çok fazla insan mantıklı gelmediğinde gümüş bir kurşun gibi davranıyor. Çoğu iş yazılımı şaşırtıcı derecede düşük bir iş mantığına sahiptir ve sahip olduğu şey nispeten basittir. Bu, katmanlama iş mantığını bir kazan kodunun kabusu haline getirebilir. Sorgu iş mantığı olduğundan, çoğu zaman veri erişimiyle iş mantığı arasında çizgiler bulanıklaşabilir.
maple_shaft

... ayrıca, çoğu dükkan kesinlikle UI mantığını veya Sunum mantığını tanımakta başarısız olur. Tipik bir CRUD uygulamasında ne kadar az işletme mantığı bulunduğunu anlamadıkları için, mantıklarının çoğunluğu sunum katmanında sunum mantığı olarak bulunduğunda yanlış bir şeyler yapmaları gerektiğini düşünüyorlar. Yanlış bir şekilde iş mantığı olarak tanımlanır ve daha sonra insanlar onu başka bir sunucu çağrısı için sunucuya iter. Bir İnce Müşteri Sunum mantığına sahip olabilir ve olmalıdır. (DropDown3'te seçenek1 seçiliyse, textField2'yi gizleyin).
maple_shaft


7

Kullanıcı Hikayeleri / Kullanım Kılıfları / Personas

 

Aşina olmadığınız bir endüstri için programlama yaparken bunun gerekliliğini anlıyorum, ancak tam olarak uygulandıklarında çok kurumsal olduklarını ve zaman kaybettiklerini düşünüyorum.


7

80 karakter / satır limiti aptal

GUI tarafındaki (ekran çözünürlüğü sınırlamaları, vb.) En yavaş koşucunun hızıyla eşleşmek için bazı uzlaşmaların yapılması gerektiğini biliyorum ama neden bu kural kod formatlama için geçerli?

Bakın ... En sağ piksel sınırının dışındaki sanal ekran alanını yönetmek için oluşturulan yatay kaydırma çubuğu adı verilen bu küçük buluş vardı. Neden sözdizimi vurgulama ve otomatik tamamlama gibi büyük verimlilik artırıcı araçlar yaratmayı başaran geliştiriciler kullanıyor?

Elbette, VT220 terminallerinin yorgunluğundaki eski kısıtlamaları takip eden * nix dinozorları tarafından dini olarak kullanılan CLI editörleri var, ama neden hepimiz aynı standarda tutulduk?

80 karakter limitini boşver diyorum. Eğer dinozorlar bütün gün emacs / vim'e dokunacak kadar destansıysa, neden otomatik olarak çizgileri saran veya CLI IDE'lerine yatay kaydırma kabiliyeti veren bir uzantı oluşturamıyor?

1920x1080 piksel monitörler nihayetinde norm haline gelecektir ve dünya çapındaki geliştiriciler hala, neden dışlanmadıklarına, hiçbir zaman programlamaya başladıklarında, yaşlıları tarafından yapmaları söylendiği şey dışında hiçbir kısıtlama olmadan aynı sınırlamalar altında yaşıyorlar.

80 karakter limitler değil en iyi yöntem ama programcılar çok azınlık için bir niş uygulama ve bu şekilde muamele edilmelidir.

Düzenle:

Birçok cihazın yatay kaydırma çubuğunu sevmemesi anlaşılır bir şey çünkü fare hareketi gerektiriyor ... Neden sütun genişliği sınırını modern ekranları kullananlar için daha yüksek bir sayıya (80'den fazla) yükseltmiyorsunuz?

800x600 bilgisayar monitörü çoğu kullanıcı için norm haline geldiğinde, web geliştiricileri çoğunluğu barındırmak için web sitelerinin genişliğini arttırdı ... Neden geliştiriciler aynı şeyi yapamıyor.


1
@Orbling Güzel GWB mantığı ___ ile kötü açıdır. Öyleyse hScroll'den nefret ediyorsun, col-width'in 80 karakterle sınırlandırılması için geçerli bir nedeniniz var mı? Neden 160 veya 256 değil? Sanırım, çoğu geliştiricinin VT220 terminallerini emekli olduklarını ve puTTY ile değiştirdiklerini, böylece genişliği yine de programatik olarak uzatabileceklerini düşünebiliriz.
Evan Plaice

4
80 karakter limitine sadık kalmayı tercih ediyorum. Bana daha fazla yatay alan verdiğiniz zaman, diğerleriyle birlikte yan yana ek belgeler açmaya çalışacağım. Dört şekilde kaydırmak zorunda kalmaktan nefret ediyorum. Ayrıca, çoğu zaman 80 karakterlik başlık ile daha okunaklı kod yazmaya zorladığımı fark ettim.
Filip Dupanović

2
nasıl basarsın?

5
Üzgünüz - bu konuda hemfikir olmamalıdır. Uzun uzun çizgilerden gerçekten nefret ediyorum - daha fazla göz hareketi gerektiriyor, fare hareketleri arasında gezinmek için zor, bir satırın sonunda hafifçe sarkan küçük şeyleri görmek daha zor. Vakaların yaklaşık% 99'unda, daha net ve okunması daha kolay olan birkaç (daha kısa) hat üzerinden bir şeyler yayınlanmasının temiz yolları vardır. 80 Karakterler keyfi olabilir ve "delikli kart günlerinde böyleydi çünkü" ama yine de yukarıda belirtilen nedenlerden dolayı - çoğu zaman - içinde çalışmak için makul bir çerçeve.
Çabucak_ancak

3
2 boşlukla girinti. Otomatik girinti izleyicili bir editör kullanın. Yıllarca böyle yaptım, önemli değil. (Doğru modlara sahip
Emac'ler

5

Ölç, Ölç, Ölç

Çok iyi, uzak ölçün, ancak performans hatalarını izole etmek için , ardışık eliminasyonun yanı sıra çalışmalar da ölçülür. İşte kullandığım yöntem.

Ölçü "bilgelik" ölçüsü kaynağını izlemeye çalışıyorum. Yeterince uzun bir sabun kutusu olan biri, dedi ve şimdi seyahat ediyor.


5

Öğretmenim tüm tanımlayıcılarıma (sabitler dahil değil) küçük harflerle başlamamı istiyor myVariable.

Küçük bir şey gibi gözüktüğünü biliyorum, ancak birçok programlama dili büyük harflerle başlamak için değişkenler gerektiriyor . Tutarlılığa değer veriyorum, bu yüzden her şeyi büyük harflerle başlatmak benim için bir alışkanlık.


9
CamelCase'i gerektiren bir öğretmenim vardı, çünkü insanların gerçek Dünyada kullandığı şeydi diye ısrar etti ... Aynı zamanda işimde iki farklı grupta programlama yapıyordum - her iki grup da düşük puanlar üzerinde ısrar ediyordu. Önemli olan grubunuzun kullandığı şey. Kendisini lider programcı olarak tanımlayabilirdi ve her şey kitabımda iyi olurdu - sözleşmelerini takip ediyoruz - ama her zaman geçerli bir başka şey yokmuş gibi "gerçek dünyada işlerin yapıldığı yol" olarak görüşünü veriyordu. yol.
xnine

@xnine Bu sitede henüz yorumunuzu derecelendirecek yeteri kadar temsilcim yok, bu yüzden sadece bu onay yorumuyla
Maxpm

5
Deve davası (ilk harf küçük harf), Pascal davası (büyük harfle yazılan her kelimenin ilk harfi) oldukça yaygın bir kongredir. Çoğu dilde, camelCase, PascalCase'in sınıflar, yöntemler, özellikler, ad alanları, genel değişkenler üzerinde kullanıldığı özel / dahili değişkenlerde kullanılır. Farklı bir adlandırma şeması kullanan projelere hazır olmak alışmak için kötü bir uygulama değildir.
Evan Plaice

2
Sadece bir FYI. Bazı diller, bir değişkenin ilk harfinin büyük harf olup olmamasından anlam çıkarır. Böyle bir dilde, ilk harf büyükse, değişken sabit olarak değerlendirilir - herhangi bir değişiklik yapma girişimi hata verecektir.
Berin Loritsch

1
In Go , kamu yöntemleri ve sınıflarında üyeleri Büyük harf harf ile başlar; Küçük harfli özel olanlar.
Jonathan Leffler

5

Singletons kullanın

Sadece bir şeyin bir örneğine sahip olmanız gerektiğinde. Daha fazla katılmıyorum . Asla bir singleton kullanmayın ve yalnızca bir kez ayırın ve gerektiğinde imleci / nesneyi / referansı geçirin. Bunu yapmamak için kesinlikle hiçbir neden yoktur.


2
Bu, beni singletonlar hakkındaki gerçek tutumunuzla ilgili olarak kafam karıştı.
Paul Butcher

1
@ Paul Kasap: Singletons'dan nefret ediyorum ve hiç kullanılmamalı

1
@ rwong: Şahsen hiçbir neden meşru bir sebep olduğunu sanmıyorum. Sadece normal bir sınıf olarak yaz. Gerçekten, tembellikten başka bir singleton kullanmak ve kötü alışkanlıkları veya tasarımları teşvik etmek için hiçbir neden yoktur.

6
Singeltons kullanmanın en iyi yöntem olduğunu kim söylüyor?
Phil Mander,

2
Singletons, özellikle operasyonel bir yapının başlangıçta tahsis edildiği ve doldurulduğu durumlarda kendi yerine sahiptir, daha sonra temelde yalnızca programın çalışma süresi boyunca okunur. Bu durumda, sadece bir işaretçinin diğer tarafında bir önbellek olur.
Tim Mesaj

5

İmzasız int iterator olarak kullanma

İmzalı int kullanmanın daha güvenli ve daha az hata eğilimli olduğunu ne zaman öğrenecekler? Dizi indeksinin sadece pozitif bir sayı olması neden bu kadar önemli, 4 - 5'in 4294967295 olduğu gerçeğini göz ardı etmekten mutluluk duyuyor?


Tamam, şimdi merak ediyorum - neden böyle söyledin? Kendimi biraz aptal hissediyorum - ifadelerinizi yedeklemek için bazı kod örnekleri verebilir misiniz?
Paul Nathan,

4
@ Paul Nathan: gelincik kadarıyla burada bir örnek var: (imzasız int i = 0; i <10; i ++) {int crash_here = my_array [max (i-1,0)];}
AareP

@AareP: Emin olmak için - ben imzasız int zaman gerçeği baþvurduðunuzu tahmin 0azaltılır 1, aslında ile bitirmek maksimum pozitif değer imzasız int saklayabileceği?
Adam Paynter

1
@Adam Paynter: evet. Bu, c ++ programcıları için normal görünebilir, ancak kabul edelim ki, "imzasız int" yalnızca pozitif sayıların kötü bir "uygulamasıdır".
AareP 10'10,

Küçük gömülü makinelerde iyi bir fikir değil - sık sık işaretsiz girişler daha küçük ve daha hızlı kodlar üretecektir. Derleyiciye ve işlemciye göre değişir.
hızla

4

Yöntemler tek bir ekrandan daha uzun olmamalıdır

Tek sorumluluk ilkesine tamamen katılıyorum, ancak neden insanlar bunu "bir işlev / yöntemin en iyi mantıksal ayrıntı düzeyinde tek bir sorumluluğa sahip olamayacağı" anlamına geldiğini düşünüyor?

Fikir basit. Bir işlev / yöntem bir görevi yerine getirmelidir. Bu işlevin / yöntemin bir kısmı başka bir yerde kullanılabilirse, onu kendi işlevine / yöntemine bölün. Projenin başka bir yerinde kullanılabilirse, onu kendi sınıfına veya yardımcı sınıfına taşıyın ve dahili olarak erişilebilir hale getirin.

Kodda yalnızca bir kez çağrılan 27 yardımcı yöntem içeren bir sınıfa sahip olmak, aptalca, yer kaybı, karmaşıklıkta gereksiz bir artış ve çok büyük bir zaman alıcıdır. Daha çok kodları yeniden gözden geçirmekle meşgul görünmek isteyenler için çok iyi bir kural gibi görünüyor.

İşte benim kuralım ...

Bir şeyi başarmak için işlevler / yöntemler yazın

Bazı kodları kopyalayıp yapıştırmak konusunda kendinizi bulursanız, kendinize bu kod için bir işlev / yöntem oluşturmanın daha iyi olup olmadığını sorun. Bir işlev / yöntem yalnızca bir kez başka bir işlevde / yöntemde çağrılıyorsa, ilk etapta uygulamanın gerçekten bir anlamı var mı (gelecekte daha sık çağrılacak mı). Hata ayıklama sırasında işlevlere / yöntemlere daha fazla atlama / atlama eklemek değerli midir (yani, eklenen atlama hata ayıklamayı kolaylaştırır veya zorlaştırır mı)?

200 çizgiden daha büyük fonksiyonların / yöntemlerin incelenmesi gerektiğine tamamen katılıyorum, ancak bazı işlevler yalnızca bir görevi birçok çizgide gerçekleştiriyor ve projenin geri kalanında soyutlanabilecek / kullanılabilecek hiçbir parça içermiyor.

Bir API dev perspektifinden bakıyorum ... Eğer yeni bir kullanıcı, kodunuzun sınıf diyagramına bakacak olsaydı, bu diyagramın kaç bölümü projenin bütününde daha anlamlı olacak ve yalnızca kaçının var olacağı konusunda projenin içindeki diğer parçalara yardımcı olacaklar.

İki programlayıcı arasında seçim yapsaydım: Birincisi, çok fazla şey yapmaya çalışan işlevler / yöntemler yazma eğiliminde; ikincisi, her işlevin / yöntemin her parçasını en ince ayrıntı seviyesine keser; İlk elleri aşağı seçerdim. Birincisi daha fazlasını başaracaktı (yani uygulamanın daha fazla etini yazacak), kodunu hata ayıklaması daha kolay olacaktır (hata ayıklama sırasında işlevlerin / yöntemlerin içeri / dışarı atlamasının daha az sıçraması nedeniyle) ve nasıl daha az zaman harcayacağını Kod, kodun nasıl çalıştığını mükemmelleştiriyor.

Gereksiz soyutlamaları sınırlayın ve otomatik tamamlamayı kirletmeyin.


Bu. Bir keresinde, uzun bir fonksiyonun birçoğuna, sadece neredeyse hepsinin orijinal kodun neredeyse tüm parametrelerine ihtiyaç duyduğunun farkına varmak için yeniden düzenlendi. Parametre kullanımı o kadar acı vericiydi ki eski koda geri dönmek daha kolaydı.
l0b0

3
Bence bunun bir karşıt argümanı, büyük bir yöntemin parçalarını ayrı çağrılara yeniden yansıtmanın daha büyük yöntemi okumayı kolaylaştıracağıdır. Yöntem sadece bir kez çağrılsa bile.
Jeremy Heiler 17:11

1
@ Jeremy Nasıl? Bir kod bölümünün çıkarılması ve kendi yöntemine yerleştirilmesi, kod grubunun en üstüne ne olduğunu açıklayan bir satır yorum yapmaktan daha okunaklı hale getirir? Bu kod bloğunun yalnızca bu kod bölümünde bir kez kullanıldığını varsayalım. Gerçekten mi yani çoğu programcı bunu okurken kod çalışma parçaları ayrıştırmak ve / veya birkaç tek satırlık onlar yapamazsan ne onları hatırlatmak için yorumlar yerleştirmek için zor?
Evan Plaice

4
@Evan: fonksiyonların içine kod parçaları koyarak etkili bir onlara verir isim umarım iyi kod o parça ne yaptığını açıklayan. Şimdi, bu kod parçasının adı nerede olursa olsun , algoritmanın kendisini analiz etmek ve anlamak yerine , kodun ne yaptığını açıklayan adı görebilirsiniz . İyi yapılırsa bu, kodun okunmasını ve anlaşılmasını çok kolaylaştırabilir.
sbi

1
+1 ve yapabilseydim daha fazlasını verirdim. Tek bir işlevde 1000 satırlık bir C kodu topluluğunda hiçbir yanlışlık yoktur (örneğin, büyük bir anahtara sahip bir ayrıştırıcı ()) Amacın net ve basittir. Küçük parçaları parçalamak ve onları çağırmak, sadece anlaşılması zor bir şey yapar. Elbette bunun da sınırları var ... mantıklı yargı her şeydir.
Çabucak_ancak
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.