Çözüm mümkün olduğunca jenerik mi yoksa mümkün olduğunca spesifik mi olmalı?


124

Diyelim ki "type" özelliğine sahip bir varlık var. 20+ olası tip olabilir.

Şimdi, tek kullanım durumu olan A-> B türünü değiştirmeye izin verecek bir şey yapmam isteniyor.

Öyleyse, geçerli türler olduğu sürece türün keyfi değişikliklerine izin veren bir şey mi uygulamalıyım? Yoksa SADECE gereksinime göre A-> B'den değişmesine izin vermeli ve B-> A veya A-> C gibi diğer tip değişiklikleri reddetmeli miyim?

Gelecekte benzer bir şartın ortaya çıkması durumunda, genel bir çözümün daha az çalışacağı anlamına gelen her iki tarafın artılarını ve eksilerini görebiliyorum, ancak bu, daha fazla yanlış gitme şansı anlamına da geliyor (% 100’ü, bu konuda arayan kişiyi kontrol etmemize rağmen) puan).
Özel bir çözüm daha az hataya eğilimlidir, ancak benzer bir gereksinim ortaya çıkarsa gelecekte daha fazla çalışma gerektirir.

İyi bir geliştiricinin değişimi öngörmeye ve sistemi tasarlamaya çalışacağını duymaya devam ediyorum, böylece gelecekte kolayca genişletilebiliyor, bu da genel bir çözüm gibi geliyor mu?

Düzenle:

Belirli olmayan örneğime daha fazla ayrıntı ekleme: Bu durumda "genel" çözüm, "özel" çözümden daha az iş gerektirir; zira özel çözüm eski türün yanı sıra yeni tür üzerinde de doğrulama gerektirir; yalnızca yeni türü doğrulamanız gerekir.


97
Bu ilginç bir soru. Ben böyle bir şey hakkında çok büyük bir zamanlayıcı programcısı olan çok büyük bir konuşmam vardı ve yanıtı, “kendi probleminizi çözen en jenerik şey” satırındaydı, ki bu bir fantaziye düşüyor ” Değişir". Yazılım Geliştirmedeki Battaniye ifadeleri nadiren işe yarıyor - işler her zaman duruma göre alınmalıdır.
T. Sar

2
@ T.Sar bunu bir cevap olarak ekler ve ben de oyuna girerim :-)
Christophe

4
Sizce "genel bir çözüm" nedir? Ayrıca, lütfen "sadece kullanım durumu" ile ne demek istediğinizi açıklığa kavuşturun. Yalnızca A-> B'den bir geçişe izin verildiğini mi yoksa yalnızca geçişin belirtildiğini mi, yani başka bir durumdan başka bir duruma geçişin bir hata koşulu olmadığını mı kastediyorsunuz? Geliştirici olarak açıklamak için kullanım davasının yazarına sormanız gerekir. Başka bir geçişe izin verilmezse ve kodunuz arayanı kimin kontrol ettiğine bakılmaksızın izin verirse, kodunuz gereksinimleri karşılamada başarısız olmuştur.
RibaldEddie

5
Eğer X iyi bir fikir ise, o zaman sadece X her zaman en uygun olmalıdır prensibi, geliştiricilere (veya en azından aralarında bir vokal grubuna) özel bir çekiciliğe sahip görünüyor, ancak şunu göz önünde bulundurun: atasözleri gibi, bununla sık sık karşıt sonuçları olan bir çift bulabilirsiniz. Bu, kararınızı (buradaki cevapların savunduğu gibi) kullanmanız ve dogmaya dikkat etmeniz gerektiğinin bir işaretidir.
sdenham

2
Erken Genelleştirme, Erken Optimizasyon kadar mide yanmasına neden olabilir - hiç kullanılmayacak kadar çok sayıda kod yazıyorsunuz. Önce belirli bir problem için çözüldü, ardından ihtiyaç ortaya çıktıkça genelleştirin.
John Bode,

Yanıtlar:


296

Temel kuralm:

  1. sorunla ilk karşılaştığınızda, yalnızca belirli sorunu çözün (bu YAGNI ilkesidir)
  2. İkinci kez aynı problemle karşılaştığınızda, çok fazla iş yoksa, ilk durumu genelleştirmeyi düşünün.
  3. genelleştirilmiş sürümü kullanabileceğiniz üç özel durumunuz olduğunda, genelleştirilmiş sürümü gerçekten planlamaya başlamalısınız - şimdiye kadar, sorunu genelleştirmek için yeterince iyi anlamanız gerekir.

Elbette, bu bir kılavuzdur ve zor ve hızlı bir kural değildir: Asıl cevap, en iyi kararınızı duruma göre kullanmaktır.


1
YAGNI'nin ne olduğunu açıklayabilir misiniz?
Bernhard,

7
@ Bernhard İhtiyacınız olmayacak . Çok kullanışlı bir yazılım tasarım ilkesi.
Angew

4
"At thing1, thing2, belki bir dizi kullanmayı düşünün. At thing1, thing2, thing3, neredeyse kesinlikle thing[]dizi kullanın." Birden fazla değişken veya tek bir dizi arasında karar vermek için benzer bir kuraldır.
Joker_vD

15
1. kuralı belirtmenin başka bir yolu: "Bir şeyi genelleştiremezsiniz."
Wayne Conrad,

2
@SantiBailors: Doc Brown'un cevabında dediği gibi, ilk atılanı kurarak harcayacağımız boşa harcanan emeğin miktarını büyük ölçüde abartıyoruz. In Mythical Man-Ay Fred Brooks diyor: "Plan uzakta bir tane atmak için - nasıl olsa, olur." Bununla birlikte, eğer bir şey için birden fazla kullanımla hemen karşılaşırsanız - örneğin, aynı sorunu bir kereden fazla açıkça çözmeniz gerekecek bir dizi gereksinim sağlayarak - o zaman genelleştirmek için birden fazla vakanız var ve bu tamamen iyi ve cevabımla çelişmiyor.
Daniel Pryden

95

Özel bir çözüm [...] benzer bir gereksinim gerekliyse gelecekte daha fazla çalışma gerektiriyor

Bu tartışmayı birkaç düzine kez duydum ve - deneyimlerime göre - düzenli olarak bir yanlışlık olduğu ortaya çıkıyor. Şimdi veya daha sonra genelleme yaparsanız, ikinci benzer gereksinim ortaya çıktığında, çalışma neredeyse tamamen aynı olacaktır. Bu nedenle, genelleme için ek bir çaba harcamanın kesinlikle bir anlamı yoktur, bu çabanın ne kadar işe yarayacağını bilmiyorsanız.

(Açıkçası bu, daha genel bir çözüm daha az karmaşık olduğunda ve belirli bir çözümden daha az çaba gerektirdiğinde geçerli değildir, ancak deneyimlerime göre, bunlar nadir vakalardır. Böyle bir senaryo soruyu sonradan düzenledi ve sorun bu değildi. birincisi cevabım hakkında).

“Benzer ikinci durum” ortaya çıktığında, genelleme hakkında düşünmeye başlamanın zamanı gelmiştir. Doğru şekilde genelleme yapmak çok daha kolay olacaktır , çünkü bu ikinci gereklilik size doğru olanı genel hale getirdiyseniz doğrulayabileceğiniz bir senaryo verir. Sadece bir vaka için genelleme yapmaya çalışırken karanlıkta çekim yapıyorsunuz. Şanslar yüksektir, genelleştirilmesi gerekmeyen bazı şeyleri fazla abartırsınız ve olması gereken diğer kısımları kaçırırsınız. Ve o zaman ikinci bir vaka ortaya çıktığında ve yanlış şeyleri genelleştirdiğinizi fark ederseniz, bunu düzeltmek için yapacak çok işiniz vardır .

Bu yüzden, "sadece durumda" olan şeyleri yapmak için herhangi bir günaha gecikmeyi tavsiye ediyorum. Bu yaklaşım, yalnızca üç, dört veya daha fazla kez genelleme fırsatını kaçırdığınızda ve daha sonra bakımı için benzer görünümlü bir kod (yani yinelenen) kodunuz olduğunda daha fazla iş ve bakım çabasına yol açacaktır.


2
Bana göre bu cevap OP bağlamında anlam ifade etmiyor. Şimdi genelleme için daha az zaman harcayacağını ve gelecekte uygulamanın spesifik olması gerekmedikçe gelecekte daha az zaman harcayacağını söylüyor. "Genelleştirme için ek çaba harcama" ya karşı savunuyorsunuz, oysa OP sadece genelleme yapmazlarsa ek çaba harcayacak . (düşünüyorum) .... garip: $
msb

2
@ msb: bu bağlam cevabımı yazdıktan sonra eklendi ve OP'nin daha önce söylediklerine aykırı gitti, özellikle de alıntı yaptığım kısımda. Düzenlemeye bak.
Doktor Brown

2
Ayrıca, genelleştirilmiş çözüm daha karmaşık olacaktır, bu yüzden ikinci duruma uyarlamanız gerektiğinde, tekrar anlamak daha uzun sürecektir.
AndreKR

4
Doktor, bir yana, ama asla yerli olmayan bir konuşmacı olduğunu tahmin edemezdim. Cevaplarınız her zaman iyi yazılmış ve iyi tartışılmıştır.
user949300,

2
Gelecekteki cevaplarını okurken aksanını hayal edeceğim. :-)
user949300

64

TL; DR: Bu, çözmeye çalıştığınız şeye bağlıdır.

Biz nasıl konuşurken ben, bu konuda benim Grampsler benzer bir konuşma yaptım Func ve Eylem C # müthiş. Gramps çok eski bir zamanlayıcı programcısıdır, yazılım bütün odayı kullanan bilgisayarlarda çalıştırıldığından beri kaynak kodları etrafındadır.

Hayatında birkaç kez teknik değiştirdi. C, COBOL, Pascal, BASIC, Fortran, Smalltalk, Java kodlarını yazdı ve sonunda bir hobi olarak C # ile başladı. IBM'in SideKick'in mavi editöründeki ilk kod satırlarımı oyup, bir şey yaparken, kucağında otururken, onunla nasıl programlanacağını öğrendim. 20 yaşına geldiğimde, dışarıda oynamaktan çok daha fazla zaman geçirdim.

Bunlar biraz hatıralarım, bu yüzden onları yeniden uygularken tam olarak pratik olmazsam özür dilerim. Bu anlardan biraz düşkünüm.

Bana öyle dedi:


“Bir sorunun genelleştirilmesi için mi gitmeli, yoksa belirli bir kapsamda çözmeli miyiz, soruyor musunuz? Peki, bu bir ... soru.”

Gramps, kısa bir süre düşünmek için durdu, gözlüklerinin yüzündeki konumunu sabitledi. Eski ses sisteminde Deep Purple'ın LP'sini dinlerken bilgisayarında bir maç-3 oyunu oynuyordu.

“Bu, hangi sorunu çözmeye çalıştığınıza bağlı olacaktır” dedi. “Tüm tasarım seçimleri için tek ve kutsal bir çözümün var olduğuna inanmak cazip geliyor, ama bir tane yok. Yazılım Mimarisi peynir gibidir, görüyorsunuz.”

“... Peynir, Gramps?”

“En sevdiğin hakkında ne düşündüğün önemli değil, her zaman koklamak olduğunu düşünen biri olacak”.

Bir süreliğine karışıklık içinde göz kırptım, fakat Gramps'ın devam ettiği bir şey söylemeden önce.

"Bir araba inşa ederken, bir parça için malzemeyi nasıl seçersiniz?"

“Ben ... Sanırım bunun maliyetlere ve parçanın ne yapması gerektiğine bağlı olduğunu düşünüyorum.”

“Bu, parçanın çözmeye çalıştığı soruna bağlı. Çelikten yapılmış bir lastik veya deriden yapılmış bir ön cam üretmeyeceksiniz. Elinizdeki problemi en iyi çözen malzemeyi seçersiniz. Şimdi, ne genel bir çözüm? Veya belirli bir çözüm? Hangi soruna, hangi kullanım durumuna? Tam işlevsel bir yaklaşımla mı gitmeli, sadece bir kez kullanılacak olan bir koda maksimum esneklik mi vermelisiniz? Sisteminizin çok ve çok fazla kullanım ve muhtemelen çok fazla değişiklik görecek bir parçası mı? Bunun gibi tasarım seçimleri, bir otomobilde bir parça için seçtiğiniz malzemeler veya küçük bir ev inşa etmek için seçtiğiniz Lego tuğlası şeklindedir. "Hangi Lego tuğlası en iyisi?"

Yaşlı programcı, devam etmeden önce masasında aldığı küçük bir Lego tren modeline ulaştı.

“Sadece o tuğlaya neye ihtiyacınız olduğunu biliyorsanız , cevap verebilirsiniz . Belirli bir çözümün jenerik olandan daha iyi olup olmadığını nasıl bileceksiniz, ya da tam olarak ne gibi bir problem olduğunu bilmiyorsanız, Çözmeye çalışıyor musunuz? Anlamadığınız bir seçeneği göremiyorsunuz. ”

“..Sadece Matrix'ten alıntı yaptın ?

"Ne?"

"Hiçbir şey, devam et."

“Ulusal Fatura Sistemine bir şeyler inşa etmeye çalıştığınızı varsayalım. Bu cehennem API'sinin ve otuz bin satırlık XML dosyasının içeriden nasıl göründüğünü biliyorsunuz. Bu dosyayı oluşturmak için 'genel' bir çözüm nasıl görünürdü? Dosya, isteğe bağlı parametrelerle doludur, yalnızca çok özel iş kollarının kullanması gereken durumlarla doludur .. Çoğu durumda, bunları güvenli bir şekilde görmezden gelebilirsiniz .. Genel bir fatura sistemi oluşturmanıza gerek kalmaz. Şimdiye kadar satacağım ayakkabıdır.Sadece ayakkabı satmak için bir sistem oluşturun ve onu orada en iyi ayakkabı satan fatura sistemi haline getirin.Şimdi, herhangi bir müşteri türü için fatura sistemi oluşturmak zorundaysanız, daha geniş bir uygulamada - Bağımsız, genel bir satış sistemi olarak yeniden satılmak,örneğin - şimdi yalnızca Gaz, yiyecek veya alkol için kullanılan seçeneklerin uygulanması ilginçtir.Şimdi bunlar olası kullanım durumları. Onlar sadece biraz varsayımsal olmadan önce Davaları kullanmayın ve uygulamak istemezsiniz Davaları kullanmayın . "Sakın kullanma , ihtiyacın olmayan küçük kardeş ."

Gramps lego trenini yerine koydu ve 3. maçına döndü.

“Yani, belirli bir sorun için genel veya özel bir çözüm seçebilmek için önce bu sorunun ne olduğunu anlamanız gerekir. Aksi takdirde, sadece tahmin edersiniz ve tahmin etmek yöneticilerin işidir, programcıların değil. BT’deki her şey buna bağlı. "


Yani, işte orada. "Değişir". Yazılım tasarımı hakkında düşünürken muhtemelen en güçlü iki kelimeli ifadedir.


14
Eminim bu hikayede yararlı bir şeyler var ama okumak çok acı vericiydi, üzgünüm
GoatInTheMachine

28
İlk gönderiniz kısa ve eğlenceli bir anekdottu - ve elbette bu bir fikir meselesi - ama birileri yazı stilini gerçekten beğenmediğim sürece, bu gerçekten hoşgörülü ve kişisel bir blog dışında biraz uygunsuz olan uzun hikayeler buluyorum
GoatInTheMachine

16
@ T.Sar, bilgisayar kurucularını dinlemiyor, yazınız bir gurunun yararlı tavsiyesi. +1
LLlAMnYP

7
"Yazılım mimarisi peynir gibidir" kısmı tamamen muhteşemdi. Gerçekten, bu cevap bir mücevher!
Mathieu Guindon

3
Belki bu cevap da peynir gibidir? ;) Ama lütfen, "SmallTalk" "Smalltalk" olmalı ve evet, o adamım, üzgünüm.
fede s.

14

Öncelikle, bu tür bir değişikliğin ortaya çıkmasının muhtemel olup olmadığını tahmin etmeye çalışmalısınız - sadece bir çizgide uzak bir ihtimal değil.

Olmazsa, şimdi basit bir çözüme gitmek ve daha sonra genişletmek daha iyidir. O zaman neye ihtiyaç duyulduğuna dair daha net bir resme sahip olmanız oldukça olası.


13

Sizin için yeni olan bir alanda çalışıyorsanız , Daniel Pryden’in bahsettiği üç kuraldan kesinlikle yararlanılmalıdır. Ne de olsa, eğer o alanda acemiyseniz, faydalı soyutlamalar nasıl yapacaksınız? Nadiren durum böyle olsa da, insanlar soyutlamaları yakalama konusunda kendilerine güvenirler. Tecrübelerime göre, erken soyutlama, kod çoğaltmasından ziyade kötü bir şey değildir. Yanlış soyutlamalar anlamak gerçekten çok acı vericidir. Bazen refactor için daha acı verici.

Üzerinde çalıştığı bilinmeyen bir alan geliştiricisi hakkındaki noktaya değinen bir kitap var . Çıkarılan faydalı soyutlamalarla özel alanlardan oluşuyor.


Soru somut bir sorun hakkında net.
RibaldEddie

4
Cevap, bu somut soruna cevap verecek kadar genel. Ve soru, somut bir makbuz verilecek kadar spesifik değil: Görebildiğiniz gibi, bir soruda hiçbir etki alanı detayından söz edilmiyor. Sınıf isimleri bile belirtilmez (A ve B sayılmaz).
Zapadlo

7
"Bir yığın akışı cevabı mümkün olduğunca genel veya mümkün olduğu kadar özel olmalı mı?"
Lyndon White

@ LyndonWhite bir yığın akışı sorusu olabildiğince genel (çok geniş!) Veya mümkün olduğu kadar spesifik (bu başarısızlık ne olursa olsun!) Olmalıdır? Ha.

4

Sorunuzun gövdesinin niteliği göz önüne alındığında, doğru anladığımı varsayarak, bunu genel sisteme özgü spesifik çözümler hakkında bir sorudan çok, merkezi sistem özelliklerinin tasarım sorusu olarak görüyorum.

Ve merkezi sistem özellikleri ve yetenekleri söz konusu olduğunda, en güvenilir olanlar orada olmayanlardır. Minimalizmin yanına, özellikle de uzun süredir arzu edilmeyen, sayısız bağımlılıkla birlikte sorunlu işlevselliği kaldırmaktan çok daha fazla bağımlılıkla birlikte işlevselliği eklemenin daha kolay olduğu düşünülürse, sistemle çalışmayı çok daha zorlaştırmıştır. Her yeni özellik ile birlikte sonsuz tasarım sorusu ortaya çıkarırken, olması gerektiğinden daha fazla.

Aslında, gelecekte bunun sık sık gerekli olup olmayacağına dair güçlü bir beklentiden yoksun olsa da, mümkünse A'dan B'ye bir tür değiştirme olarak bakmaktan kaçınmaya çalışacağım ve bunun yerine sadece A durumunu dönüştürmenin bir yolu olarak arayacağım. Örneğin, farklı bir 'türüne' geçmeden kullanıcıya morf yapmak ve B gibi görünmesi için bazı alanları A olarak ayarlayın - A durumundaki kompozisyonu ve arama fonksiyonlarını kullanarak A deposunu B'de yapabilirsiniz. mümkünse uygulamayı basitleştirmek için B'yi taklit etmesi gerektiğini belirtmek üzere ayarlanmıştır. Bu çok basit ve minimal derecede istilacı bir çözüm olmalı.

Her neyse, birçoğunu yankılandırarak, bu durumda genel çözümlerden kaçınmanın yanında hata yapmayı öneririm, ama daha fazlası, bunun merkezi sisteme çok cesur bir yetenek katmayı göz önüne aldığına inanıyorum. Özellikle şimdilik, onu dışarıda bırakma yönündeki hataları önerdi.


"Kodlamadığınız tüm hataları özlüyorsunuz." (basketbol posterinden: almadığınız tüm atışları özlüyorsunuz)

3

Bu özel soruna genel bir cevap vermek zor ;-)

Ne kadar jenerik olursa, gelecekteki değişiklikler için o kadar fazla zaman kazanırsınız. Örneğin, bu nedenle birçok oyun programı , oyundaki karakterlerin ve nesnelerin çok ayrıntılı fakat katı tip bir sistemini oluşturmak yerine varlık bileşen modelini kullanır.

Öte yandan, bir şeyi genel yapmak, çok özel bir şeyden çok daha yüksek olan tasarıma önceden bir zaman ve emek yatırımı gerektirir. Bu, aşırı mühendislik ve gelecekteki potansiyel ihtiyaçlarda bile kaybolma riskini taşımaktadır.

Size bir atılım yapacak doğal bir genelleme olup olmadığını her zaman görmeye değer. Ancak, sonuçta, şimdi harcayabileceğiniz ve gelecekte ihtiyaç duyabileceğiniz çaba arasında bir denge sorunu olabilir.


3
  1. Hibrid. Bu bir / veya soru olmak zorunda değildir. Şu anda yalnızca ihtiyacınız olan belirli dönüştürmeyi uygularken, genel tür dönüştürmeleri için API'yi tasarlayabilirsiniz. (Biri genel API'nizi desteklenmeyen bir dönüşümle çağırırsa, "desteklenmeyen" bir hata durumu ile başarısız olduğundan emin olun.)

  2. Test yapmak. A-> B dönüşümü için, bir (veya az sayıda) test yazmak zorunda kalacağım. Genel bir xy> y dönüşümü için bütün bir test matrisi yazmak zorunda kalabilirim. Tüm dönüşümler tek bir genel uygulamayı paylaşsa bile, bu daha büyük bir iştir.

    Öte yandan, tüm olası dönüşümleri test etmenin genel bir yolu olduğu ortaya çıkarsa, o zaman daha fazla çalışma olmaz ve daha erken bir zamana kadar genel bir çözüme gitme eğiliminde olabilirim.

  3. Kavrama. A'dan B'ye bir dönüştürücünün mutlaka A ve B ile ilgili uygulama ayrıntılarını bilmesi gerekebilir (sıkı bağlantı). A ve B hala evrimleşiyorsa, bu, dönüştürücüyü (ve testlerini) tekrar gözden geçirmeye devam etmem gerekebileceği anlamına geliyor, ama bu en azından A ve B ile sınırlı.

    Ben her türlü ayrıntıları erişmesi gerektiği genel bir çözüm ile gitmiş olsaydı, o zaman bile C'ler ve D's gelişmeye olarak, bana yavaşlatabilir jenerik dönüştürücü (ve bir sürü test), verdiği tutmak gerekebilir bile Yine de hiç kimse bir C veya D dönüştürmek zorunda değil .

    Hem genel hem de belirli dönüşümler yalnızca türlerin ayrıntılarına gevşek bir şekilde bağlı olacak şekilde uygulanabilirse, o zaman bu konuda endişelenmem. Bunlardan biri gevşek bir şekilde bağlanabilir, ancak diğeri sıkı bir şekilde bağlanmayı gerektiriyorsa, bu, kapıdan çıkan gevşek bir şekilde bağlanmış yaklaşım için güçlü bir argümandır.


2
Test etmek iyi bir nokta. Kategori teorisindeki kavramlara dayanan genel çözümleri tasarlarsanız, bu büyük bir avantajdır , çünkü o zaman bir imza için mümkün olan tek uygulamanın (derleyicinin tür denetleyicisinin kabul ettiği) doğru olanı veya en azından olduğunu kanıtlayan serbest teoremleri alırsınız. Algoritma belirli bir tip için çalışıyorsa, diğer tüm tipler için de çalışması gerekir.
leftaroundabout

Yalnızca bir tür dönüşümün istenmesinin neden olduğu etki alanına özgü bir neden olduğunu tahmin ediyorum, bu nedenle çoğu tür dönüşümünün sorun alanındaki geçersiz eylemler olacağı ve bu nedenle, uygulama tarafından desteklenmemesi gerektiği anlaşılıyor. resmen izin verilir. Bu cevaplar bu tartışmaya en yakın olanıdır.
Ralf Kleberhoff

3

Çözüm mümkün olduğunca jenerik mi yoksa mümkün olduğunca spesifik mi olmalı?

Bu cevaplanabilir bir soru değil.

Makul bir şekilde elde edebileceğiniz en iyi şey, belirli bir çözümü ne kadar genel veya özel yapacağınıza karar vermeniz için birkaç buluşsal yöntemdir. Aşağıdaki işlem gibi bir şeyle çalışmak, genellikle birinci dereceden yaklaşım doğru (ya da yeterince iyi). Olmadığı zaman, neden burada ayrıntılı olarak ele alınmayacak kadar alana özgü olması muhtemeldir.

  1. Birinci mertebeden yaklaşım: Daniel Pryden, Doc Brown ve ark .

    Muhtemelen bunu yapabilir en iyisi, çünkü bu genel-kullanışlı sezgisel olduğunu gelmez etki ve diğer değişkenlere bağlıdır.

    Öyleyse, ilk varsayım şudur: en spesifik şeyi yaparız.

  2. İkinci dereceden yaklaşım: sizin uzman bilgisine dayalı çözüm etki diyorsunuz

    Bu durumda "genel" çözüm, "belirli" çözümden daha az iş gerektirir

    bu yüzden belki biz gereksiz önlemek tavsiye olarak YAGNI yeniden yorumlamak işi oldukça gereksiz genelliği kaçınarak daha. Dolayısıyla ilk varsayımımızı değiştirebiliriz ve bunun yerine en kolay olanı yapabiliriz.

    Bununla birlikte, çözüm alanı bilginiz en kolay çözümün bir çok hata açacağını veya yeterince test etmek veya başka bir soruna yol açmanın zor olduğunu gösteriyorsa, kodlaması daha kolay olmak bizim için önemli bir neden değildir. Orijinal seçim

  3. Üçüncü mertebeden yaklaşım: sorunlu alan bilginiz en kolay çözümün gerçekten doğru olduğunu mu gösteriyor yoksa anlamsız ya da yanlış olduğunu bildiğiniz birçok geçişe izin veriyor musunuz?

    Kolay fakat genel çözüm, sorunlu görünüyorsa veya bu riskleri yargılama konusunda kendinize güvenmiyorsanız, fazladan iş yapmak ve ilk tahmininizle kalmak muhtemelen daha iyidir.

  4. Dördüncü dereceden yaklaşım: müşteri davranışı bilginiz veya bu özelliğin başkaları ile olan ilişkisi veya proje yönetimi öncelikleri veya ... başka hiçbir teknik açıdan önemli olmayan hususlar mevcut çalışma kararınızı değiştirir mi?


2

Bu basit bir cevapla cevaplanması kolay bir soru değil. Pek çok cevap, 3 kuralı etrafında inşa edilen sezgisel özellikleri veya benzer bir şeyi vermiştir. Bu tür kuralların ötesine geçmek zor.

Gerçekten için gerçekten sorunuza cevap, size iş A-> B değiştirir şey uygulamak değil büyük olasılıkla olduğunu düşünmek zorundayız. Bir müteahhit iseniz, belki de şart bu, ancak bir çalışansanız, şirket için daha birçok küçük iş yapmak üzere işe alındınız. A-> B'yi değiştirmek bu görevlerden sadece bir tanesidir. Şirketiniz, talepte belirtilmemiş olsa bile gelecekteki değişikliklerin ne kadar iyi yapılabileceğine dikkat edecektir. "TheBestImplementation (tm)" yi bulmak için, gerçekten ne yapmanız istendiğine dair daha büyük bir resme bakmanız ve ardından bunu A-> B'yi değiştirmek için verdiğiniz küçük talebi yorumlamak için kullanmanız gerekir.

Üniversiteden yeni çıkmış, düşük seviyeli bir giriş programcısıysanız, tam olarak yapmanız gerekenleri yapmanız tam olarak önerilir. 15 yıllık deneyime sahip bir yazılım mimarı olarak işe alındıysanız, tipik olarak büyük resimli şeyler düşünmeniz önerilir. Her gerçek iş “dar görevin ne yaptığını yapın” ile “büyük resmi düşünün” arasında bir yere düşecek. Eğer insanlarla yeterince konuşursanız ve onlar için yeterince iş yaparsanız, işinizin bu spektrumda nerede uyduğunu hissedeceksiniz.

Sorunuzun bağlama dayalı kesin bir cevabı olduğu birkaç somut örnek verebilirim. Güvenlik açısından kritik bir yazılım yazdığınız durumu göz önünde bulundurun. Bu, ürünün vaat edildiği gibi performans göstermesini sağlamak için ayağa kalkmış bir test ekibiniz olduğu anlamına gelir. Bu test ekiplerinden bazılarının, koddaki olası her yolu test etmesi gerekir. Onlarla konuşursanız, bu davranışı genelleştirirseniz, test maliyetlerine 30.000 $ ekleyeceğinizi, çünkü tüm bu ekstra yolları test etmek zorunda kalacağınızı görebilirsiniz. Bu durumda, yok sen esere yüzünden 7 veya 8 kez yinelenen gerekse bile, genelleştirilmiş işlevsellik eklemek. Şirketten tasarruf edin ve isteğinizi tam olarak belirtin.

Diğer tarafta, müşterilerin şirketinizin yaptığı bir veritabanı programındaki verilere erişmesine izin vermek için bir API yaptığınızı düşünün. Bir müşteri değişikliklere izin vermek ister A-> B. API'ler genellikle onlara altın kelepçe yönüne sahiptir: Bir API'ye işlevsellik eklediğinizde, genellikle bu işlevi kaldırmanız gerekmez (bir sonraki ana sürüm numarasına kadar). Müşterilerinizin birçoğu, bir sonraki ana sürüm numarasına yükseltme maliyetini ödemek için istekli olmayabilir, bu nedenle uzun bir süre boyunca seçtiğiniz herhangi bir çözüme bağlı kalabilirsiniz. Bu durumda, baştan beri jenerik çözümü yaratmanızı şiddetle tavsiye ederim. Gerçekten bir defalık davranışlarla dolu kötü bir API geliştirmek istemiyorsunuz.


1

Hmm ... bir cevabın devam etmesi için fazla bir bağlam yok ... daha önceki cevapların yankılanması, "Bu değişir".

Bir anlamda, deneyimine geri dönmelisin. Sizinki değilse, o zaman etki alanında daha kıdemli biri. Kabul ölçütlerinin ne ifade ettiği hakkında bilgi alabilirsiniz. 'Kullanıcı' tipini "A" 'den "B"' ye kadar değiştirebilmeli "," kullanıcı "türünü şu anki değerden izin verilen herhangi bir alternatif değere değiştirebilmelidir".

Sık sık kabul kriterleri yorumlamaya tabidir, ancak iyi QA personeli eldeki göreve uygun kriterleri yazarak gerekli yorumu en aza indirir.

"A" dan "C" ye veya başka bir seçeneğe değiştirmeye izin vermeyen, sadece "A" den "B" ye değiştirmeye izin veren etki alanı kısıtlamaları var mı? Yoksa bu sadece “ileri görüşlü” olmayan, dar bir şekilde belirlenmiş bir gereklilik midir?

Genel durum daha zor olsaydı, işe başlamadan önce gidip soracağım, ancak sizin durumunuzda 'diğer' tip 'değişiklik taleplerinin gelecekte geleceğini' tahmin edebilirsem ': a) genel durum için yeniden kullanılabilir bir şey yazın ve b) şimdilik yalnızca A -> B'ye izin veren bir koşul içinde sarın.

Otomatik testlerde mevcut durumun doğrulanması için yeterince kolay ve farklı kullanım durumları ortaya çıktığında / sonra ortaya çıktığında diğer seçeneklere açılacak kadar kolay.


1

Benim için, bir süre önce oluşturduğum bir rehber: "Varsayımsal şartlar için sadece varsayımsal kod yaz." Diğer bir deyişle - ek gereksinimler öngörüyorsanız, bunları nasıl uygulayacağınız hakkında biraz düşünmeli ve mevcut kodunuzu bu şekilde engellemeyecek şekilde yapılandırmalısınız.

Ama şimdi bunlar için gerçek kod yazmayın - ne yapacağınız hakkında biraz düşünün. Aksi takdirde, işleri genellikle gereksiz yere karmaşık hale getirirsiniz ve daha sonra, beklentileriniz beklediğinizden farklı olan gerçek gereksinimler ortaya çıktığında büyük olasılıkla sinirleneceksiniz.

Dört örnek: kontrolünüzde convert yönteminin tüm kullanımlarına sahipseniz, şimdilik bunu convertAToB olarak adlandırabilir ve daha sonra daha genel bir işlevselliğe ihtiyacınız varsa, yeniden adlandırmak için IDE'de yeniden adlandırılan bir "yeniden adlandırma yöntemi" kullanmayı planlayabilirsiniz. Ancak, dönüştürme yöntemi genel bir API’nin parçasıysa, bu durum oldukça farklı olabilir: bu özelliğin daha sonra genelleştirmeyi engelleyeceği için bu durumda bazı şeyleri yeniden adlandırmak zor.


0

İyi bir geliştiricinin değişimi öngörmeyi ve sistemi tasarlamayı ve böylece gelecekte daha kolay genişletilebilmesini sağlaması gerektiğini duymaya devam ediyorum.

Prensip olarak evet. Ama bu yok değil mutlaka jenerik çözümlere yol açar.

Yazılım geliştirmede, gelecekteki değişimi öngörmeniz gereken iki konu var:

  • 3. taraflarca kullanılması amaçlanan kütüphaneler ve
  • genel yazılım mimarisi.

İlk durum, uyum / birleşiminizi, bağımlılık enjeksiyonunuzu veya her neyse onu izleyerek çözülür. İkinci durum daha soyut bir seviyededir, örneğin büyük bir uygulama için büyük bir monolotik kod bloğu yerine servis odaklı bir mimari seçmek.

Sizin durumunuzda, gelecekteki herhangi bir etkisi olmayan belirli bir problem için özel bir çözüm istiyorsunuz. Bu durumda, YAGNI ve DRY, çekim için iyi sloganlardır:

  • YAGNI (buna ihtiyacın olmayacak), şu anda ihtiyacın olan ve kullanman gereken asgari, temel maddeleri uygulamanı söyler . TDD / BDD / FDD tarzı bir geliştirme kullanmanız gerekiyorsa, mevcut test setinizi kırmızıdan yeşile çeviren minimumun uygulanması anlamına gelir. Tek bir satır değil.
  • (Kendinizi tekrar etmeyin) KURU tekrar benzer bir sorun hakkında geliyorsa, demek o zaman size genel bir çözüm gerek olmadığını iyi bir sabit bakmak.

Diğer modern uygulamalarla bir araya getirildiğinde (güvenli bir şekilde yeniden refaktör yapabilmek için iyi test kapsamı gibi), bu, gerektiği gibi hızlı bir şekilde yazılı, yalın, ortalama kodla sonuçlandığınız anlamına gelir.

genel bir çözüme benzeyen sesler hangisidir?

Hayır, ihtiyaç duyduğunuzda yeniden düzenleyiciyi kolaylaştıracak ve eğlenceli hale getirecek programlama ortamlarına, dillere ve araçlara sahip olmalısınız. Genel çözümler bunu sağlamaz; Uygulamayı asıl etki alanından ayırırlar.

Modern ORM'lere veya MVC çerçevelerine bakınız, örneğin Ruby on Rails; Uygulama düzeyinde, tüm odak noktası jenerik olmayan bir iş yapmaktır. Raylar kütüphanelerinin kendileri neredeyse% 100 jeneriktir, ancak alan kodunun (sorunuzun konusu olduğu) bu yönden en az miktarda shenanigan yapıyor olmalıdır.


0

Sorun hakkında düşünmenin farklı bir yolu, neyin anlamlı olduğunu düşünmektir.

Örneğin, geliştirmekte olduğum bir uygulama vardı, neredeyse aynı şeyi yapan ancak tutarsız izin kuralları olan bölümler vardı. Onları farklı tutmak için hiçbir neden olmadığından, bu bölümü tekrar değiştirdiğimde, hepsine aynı şekilde izin vermelerini sağladım. Genel kod daha küçük, daha basit hale getirildi ve arayüz daha tutarlıydı.

Yönetim başkalarının bir özelliğe erişmesine izin vermeye karar verdiğinde, sadece bir bayrağı değiştirerek başarabildik.

Belli bir tür dönüşüm yapmak için açıkçası mantıklı. Eklenti türü dönüşümler yapmak da mantıklı mı?

Genel çözümün uygulanması daha hızlı ise, o zaman kendine özgü durum da kolaydır, izin verdiğiniz tek tür dönüşümünün olup olmadığını kontrol edin.

Uygulama çok düzenlenmiş bir alanda ise (tıbbi ya da finansal uygulama) tasarımınıza daha fazla insanı dahil etmeye çalışı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.