Gerçekten “Yumuşak Kodlama” nedir?


87

Gelen bu makalede Alex Papadimoulis tarafından, bu pasajı görebilirsiniz:

private void attachSupplementalDocuments()
{
  if (stateCode == "AZ" || stateCode == "TX") {

    //SR008-04X/I are always required in these states
    attachDocument("SR008-04X");
    attachDocument("SR008-04XI");
  }

  if (ledgerAmnt >= 500000) {
    //Ledger of 500K or more requires AUTHLDG-1A
    attachDocument("AUTHLDG-1A");
  }

  if (coInsuredCount >= 5  && orgStatusCode != "CORP") {
    //Non-CORP orgs with 5 or more co-ins require AUTHCNS-1A
    attachDocument("AUTHCNS-1A");
  }
}

Bu makaleyi gerçekten anlamıyorum.

Alıntı yaparım:

Her iş kuralı sabiti bir yapılandırma dosyasında saklanmış olsaydı, yaşam , yazılımı koruyan herkes için çok [daha fazla ( sic )] zor olurdu: bir, büyük dosyayı (ya da sohbeti paylaşan) bir sürü kod dosyası olurdu. bir sürü küçük yapılandırma dosyası); iş kurallarında değişikliklerin dağıtılması yeni kod gerektirmez, ancak yapılandırma dosyalarını el ile değiştirin; ve hata ayıklama çok daha zor.

Bu, bir yapılandırma dosyasında "500000" sabit tamsayıya veya "AUTHCNS-1A" ve diğer dize sabitlerine sahip olmanın bir argümanıdır.

Bu nasıl kötü bir uygulama olabilir?

Bu kod parçasında, "500000" bir sayı değildir. Örneğin, aynı değil:

int doubleMe(int a) { return a * 2;}

buradaki 2, soyutlanması gerekmeyen bir sayıdır. Kullanımı açıktır ve daha sonra tekrar kullanılabilecek bir şeyi temsil etmez.

Aksine, “500000” sadece bir sayı değildir. İşlevsellikte bir kırılma noktası fikrini temsil eden önemli bir değer. Bu numara birden fazla yerde kullanılabilir, ancak kullandığınız numara değil; sınırın / sınır çizgisinin fikri, altında hangi kural uygulanır, hangisinin üzerindedir?

Nasıl hatta bir yapılandırma dosyasından kendisine atıfta bulunarak, ya bir #define, constya da dil değerini içeren daha kötüsü sağlar ne olursa olsun? Yazılım başka bir seçim yapar, böylece daha sonra programa veya başka bir programcı üzerinde, ayrıca, bu sınırda gerektiriyorsa, (çünkü vidalı konum zaman değişeceği, hiçbir şey her iki dosyalarında değişiklik olacağını size garanti). Bu hata ayıklama için açıkça daha kötü.

Ek olarak, yarın ise, hükümet "5.03.2050 tarihinden itibaren AUTHLDG-1A yerine AUTHLDG-122B eklemelisin" diye soruyorsa, bu dize sabiti basit bir dize sabiti değildir. Bir fikri temsil eden; bu, sadece bu fikrin şu anki değeridir (“defter 500k'nin üzerindeyse ekleyeceğiniz şeydir”).

Netleştireyim. Makalenin yanlış olduğunu söylemiyorum; Sadece anlamıyorum; belki de çok iyi açıklanmamıştır (en azından benim düşünceme göre).

Mümkün olan her dize değişmez veya sayısal değeri sabit, tanımlanmış veya konfigürasyon değişkeni ile değiştirmenin sadece gerekli değil, işleri karmaşık hale getirdiğini, ancak bu özel örneğin bu kategoriye girmediğini anlıyorum. Daha sonra ihtiyacınız olmayacağını nereden biliyorsunuz? Ya da bu konuda başka biri?


21
Bulmacayı oyna: bu rakamlar için iyi bir isim ne olabilir? Sanırım ismin hiçbiri bir değer katmadığını ya da belirsizliği eklerken kodun zaten açıkladığı her şeyi açıklar ("LedgerLimitForAuthDlg1A"?). Bu makalenin tam olarak ne kadar alakalı olduğu konusunda parlak buldum . Her iki yaklaşımı da kullanan sistemleri korudum ve size iş kurallarının koda ait olduğunu söyleyebilirim - izlemesi, bakımı ve anlaması çok daha kolay. Konfigürasyon kullandığınızda, sayımını arttırmanız daha iyi - çok daha pahalı.
Luaan

2
Yapılandırılması gereken şeyler için yapılandırma ayrılmalıdır. İş kuralları genel olarak yapılandırılamazsa, bunun bitlerini yapılandırmaya koymak size hiçbir şey kazandırmaz.
biziclop

Uygun şekilde gelişmiş diller için yapılandırma, dizgiler yerine gerçek alt yordamlar biçimini alır.
Thorbjørn Ravn Andersen

Yanıtlar:


100

Yazar erken soyutlamaya karşı uyarıyor.

Bu çizgi if (ledgerAmt > 500000), gereksinimleri inanılmaz derecede karmaşık ancak kesin ve iyi belgelenmiş büyük karmaşık iş sistemleri için görmeyi beklediğiniz türden bir iş kuralı gibi gözüküyor.

Genellikle bu tür gereksinimler, yeniden kullanılabilir mantıktan ziyade istisnai / son durumlardır. Bu gereksinimler genellikle mühendisler yerine iş analistleri ve konu uzmanları tarafından karşılanır ve korunur

(Bu durumlarda Business Analistler / uzmanlar tarafından gereksinimlerin 'sahipliğinin' tipik olarak uzmanlık alanlarında çalışan geliştiricilerin yeterli alan uzmanlığına sahip olmadığı durumlarda ortaya çıkar, bununla birlikte geliştiriciler ve alan uzmanları arasında tam iletişim / işbirliği beklememeyi beklerim. belirsiz veya kötü yazılı gereklilikler.)

Gereksinimleri son vakalarla dolu ve oldukça karmaşık bir mantıkla dolu olan sistemleri sürdürürken, genellikle bu mantığı soyutlamak veya daha iyi bir bakım yapmak için hiçbir yol yoktur; Soyutlamalar yapmayı denemek çabasıyla kolayca geri tepebilir - sadece zaman kaybına neden olmaz, aynı zamanda daha az bakım gerektirebilen kodlarla sonuçlanır.

Bir config dosyasından veya #define, const veya diliniz ne sağlarsa sağlayın, değeri dahil etmekten daha mı kötü? Daha sonra programda veya başka bir programlayıcıda bu sınır çizgisini gerektiriyorsa, yazılım başka bir seçim yapsın diye, vidalanırsınız (çünkü değiştiğinde, hiçbir şey size her iki dosyada da değişeceğini garanti etmez). Bu hata ayıklama için açıkça daha kötü.

Bu tür bir kod, kodun kendisinin büyük olasılıkla bire bir eşleştirmeye sahip olması nedeniyle korunma eğilimindedir; Bir geliştirici zaman yani bilir o 500000rakam gereksinimlerinde iki kez görünür, yani geliştirici ayrıca kodda iki kez göründüğünü bilir.

500000Gereksinimler belgesinde birden fazla yerde görünen diğer (eşit derecede muhtemel) senaryoyu düşünün , ancak Konu Meselesi Uzmanları bunlardan sadece birini değiştirmeye karar verir; Orada, constdeğeri değiştiren birisinin 500000farklı şeyler ifade etmek için kullanıldığının farkına varmayacağına dair daha da kötü bir riskiniz var - geliştirici bunu kodda bulduğu tek ve tek yerde değiştirir ve kodunu değiştirdiği bir şeyle sonuçlanır değiştiklerini anlamadılar.

Bu senaryo, ısmarlama yasal / finansal yazılımlarda çok fazla olur (örn. Sigorta teklifi mantığı) - bu tür belgeleri yazan insanlar mühendis değildir ve herhangi bir kopyasını + spekülasyonun tamamını yapıştırmadan, birkaç kelime / rakamı değiştirmeden problem çıkarmazlar. çoğunu aynı bırakarak.

Bu senaryolarda, kopyala-yapıştır gereklilikleri ile başa çıkmanın en iyi yolu kopyala-yapıştır kodunu yazmak ve kodu mümkün olduğu kadar (tüm verileri kodlama dahil) gereksinimlere benzetmektir.

Bu tür gereksinimlerin gerçekliği, genellikle kopya ve yapıştırma işlemlerinde uzun süre kalmamaları ve değerler bazen düzenli olarak değişmemeleridir, ancak çoğu zaman birlikte değişmezler, bu nedenle bu gereklilikleri rasyonelleştirmeye veya özetlemeye çalışırlar Onları herhangi bir şekilde bire bir gereksinim koduna çevirmeden daha fazla bakım baş ağrısı yaratır.


28
Bir Etki Alanına Özel Dil (DSL), kodu gereksinim belgesi gibi daha fazla okumak için iyi bir yol olabilir.
Ian,

13
DSL'nin diğer bir avantajı, uygulama, sunum veya sebat mantığını yanlışlıkla iş kurallarıyla karıştırmayı zorlaştırmasıdır.
Erik Eidt

16
Uygulamanızın, kendi DSL'sini garanti altına almak için yeterince özel olduğunu düşünmek, genellikle kocadır.
brian_o

8
Those requirements are typically owned and maintained by business analysts and subject matter experts, rather than by engineersbu her zaman iyi bir fikir değildir. Bazen bu gereklilikleri koda dönüştürmek, gereklilikleri iyi tanımlanmayan ya da iş dünyasına aykırı olacak şekilde tanımlanmış köşe durumlarını ortaya çıkarır. İş analistleri ve geliştiricileri ortak bir hedefe ulaşmak için işbirliği yapabilirlerse, o zaman birçok sorundan kaçınılabilir.
kasperd

4
@BenCottrell Yazılımı yazmayı kolaylaştırmak için kuralları değiştirmeyi önermiyordum. Ancak, kurallarda çok sayıda şartlandırmaya sahip olduğunuzda, kurallar ilk başta tanımlanırken, bunlar arasındaki bazı etkileşimlerin kaçırılması tamamen mümkündür. Ancak spesifikasyonu koda dönüştürdüğünüzde, geliştirici bu koşullar arasında olası bir etkileşim olduğunu fark etmek zorundadır. Bu noktada, geliştiricinin şartnamenin katı bir şekilde yorumlanmasının müşterilerin sistemi oynamasını sağlayacak kasıtsız bir fiyata yol açtığını bulması mümkündür.
kasperd

44

Makalenin iyi bir noktası var. Bir yapılandırma dosyasına sabitleri çıkarmak nasıl kötü bir uygulama olabilir? Gereksiz yere kodu zorlaştırıyorsa, kötü bir uygulama olabilir. Doğrudan kodda bir değere sahip olmak, onu bir yapılandırma dosyasından okumaktan çok daha kolaydır ve kodun yazıldığı gibi takip edilmesi kolaydır.

Buna ek olarak, yarın, hükümet "5.03.2050 tarihinden itibaren AUTHLDG-1A yerine AUTHLDG-122B eklemelisin" diye devam ediyor.

Evet, sonra kodu değiştir. Makalenin amacı, bir yapılandırma dosyasını değiştirmek yerine, kodu değiştirmenin daha karmaşık olmadığıdır.

Makalede açıklanan yaklaşım, daha karmaşık bir mantık elde ederseniz ölçeklendirilmez, ancak asıl nokta, bir yargılama çağrısı yapmanız gerektiğidir ve bazen en basit çözüm, en iyisidir.

Daha sonra ihtiyacınız olmayacağını nereden biliyorsunuz? Ya da bu konuda başka biri?

Bu, YAGNI ilkesinin amacıdır. Şimdilik tamamen farklı olabilecek bilinmeyen bir gelecek için tasarım yapmayın. Bunu doğru olup olmadığını değeri 500000 programda çeşitli yerlerde kullanılan tabii ki sabit ayıklanır edilmelidir. Ancak söz konusu kodda durum böyle değil.

Yazılım kodlaması gerçekten endişelerin ayrılması meselesidir . Bildiğiniz yazılım yazılımı temel uygulama mantığından bağımsız olarak değişebilir . Hiçbir zaman bir bağlantı dizesini bir veritabanına zorlamazsınız, çünkü bunun uygulama mantığından bağımsız olarak değişebileceğini biliyorsunuz ve farklı ortamlar için ayırt etmeniz gerekecek. Bir web uygulamasında, iş mantığını html şablonlarından ve stil sayfalarından ayırmayı severiz, çünkü bunlar bağımsız olarak değişebilir ve hatta farklı kişiler tarafından değiştirilebilir.

Ancak kod örneğinde, kodlanmış dizeler ve sayılar uygulama mantığının ayrılmaz bir parçasıdır. Kontrolünüz dışındaki bazı politika değişikliklerinden dolayı bir dosyanın adını değiştirmesi düşünülebilir, ancak farklı bir durum için yeni bir if-dal kontrolü eklememiz gerekebilir. Dosya adlarını ve numaralarını ayıklamak, bu durumda aslında uyumu bozuyor.


4
Çoğu zaman kod değiştirmek bir yapılandırma dosyasından çok daha karmaşıktır. Birincisi için bir geliştiriciye ve bir derleme sistemi / sürüm döngüsüne ihtiyacınız olabilir; ikincisi ise yalnızca uyumlu bir yapılandırma kullanıcı arabiriminde bir kutudaki bir sayıyı değiştirmeyi gerektirir.
OrangeDog

6
@OrangeDog Evet, ilk bakışta böyle görünüyor. Eğer böyle şeyler yaparsanız Ama, yapılandırma kullanıcı arayüzü şey olacak ama kim bilir ne soran tamamen anlamsız metin kutuları yüzlerce dost. Şimdi kullanıcı arayüzünü oluşturup belgelemeniz gerekiyor. Unutmayın, bu yapılandırma hiçbir zaman gitmek için iyi bir yol olmadığı anlamına gelmez - kesinlikle doğru seçim olduğu durumlar vardır. Ancak makaledeki örneklerin hiçbirinde yok . En son ne zaman bir yasa sadece sayıyı değiştirdi? KDV kuralları burada en son değiştiğinde, yine de tüm hesaplamaları tekrar yapmak zorunda kaldık.
Luaan

2
@OrangeDog: Burada, yazılım konfigürasyonunun yapmanız gereken kontrol için gerekli kancaları sağladığını varsayıyorsunuz. OP'de her birinin iffarklı bir değişkene nasıl dayandığını not edin! İhtiyacınız olan değişken konfigürasyondan erişilebilir değilse, yazılımı yine de değiştirmeniz gerekir.
Matthieu M.

2
@OrangeDog , bir yazılım uygulamasının mantığında , dev / qa / release döngüsü ve uygun testler olmadan önemli değişiklikler yapılması gerektiğini öne sürüyorsunuz.
NPSF3000

3
@OrangeDog: Tamam örnekte mantığı yapılandırmak için YAML kullanıyorsunuz. Mantık şartlı kurallar içerdiğinden, bu şartlı maddeleri YAML'da temsil etmenin bir yolunu bulursunuz. Tebrikler, Python'u yeniden icat ettiniz. Neden tüm uygulamayı Python'a yazmıyorsunuz?
JacquesB

26

Makale, muhtemelen neye karşı savunduğunun daha iyi bir örneği olan 'Kurumsal Kural Motoru' hakkında konuşmaya devam ediyor.

Mantık, konfigürasyonunuzun kendi programlama dilini içerecek kadar karmaşık hale geldiği noktaya genelleştirebilmenizdir.

Örneğin, örnekte belge eşleştirmeye yönelik durum kodu bir yapılandırma dosyasına taşınabilir. Ancak daha sonra karmaşık bir ilişki ifade etmeniz gerekir.

<statecode id="AZ">
    <document id="SR008-04X"/>
    <document id="SR008-04XI"/>
</statecode>

Belki de defter miktarını da koyarsınız?

<statecode id="ALL">
    <document id="AUTHLDG-1A" rule="ledgerAmt >= 50000"/>
</statecode>

Yakında yeni bir dilde programlama yaptığınızı keşfettiniz ve bu kodu kaynak veya değişiklik kontrolü olmayan yapılandırma dosyalarına kaydedin.

Bu makalenin, böyle bir şeyin ortak bir yaklaşım olduğu 2007'den itibaren olduğu belirtilmelidir.

Günümüzde sorunu muhtemelen bağımlılık enjeksiyonuyla (DI) çözeceğiz . Yani, bir 'zor kodlanmış' olurdu

InvoiceRules_America2007 : InvoiceRules

sabit kodlu veya daha yapılandırılabilir bir kodla değiştireceğiniz

InvoiceRules_America2008 : InvoiceRules

Hukuk ya da iş gereksinimleri değiştiğinde.


4
Belki de "DI" yi tanımlamalısın. Ve belki biraz daha açıklayabilirim.
Basil Bourque,

9
Bu dosya neden kaynak kontrol sisteminde olmasın?
JDługosz

2
Müşteriye özelse, kodlanmış sürümde ifher bir müşteriye farklı değerler vermek için muazzam bir ifade karmaşası var mı? Bir yapılandırma dosyasında olması gereken bir şeye benziyor . Bir tür dosyada veya başka bir dosyada olmak, hepsinin eşit olması, dosyayı kontrol etmemesi / izlememesi / yedeklememesi için bir neden değildir. @ewan bir DSL dosya görüntü ve ses dosyaları ve dokümantasyon gibi bile olmayan kod varlıklar kesinlikle nedense projesinin bir parçası olarak kaydedilemez söyleyerek gibi görünüyor olduğunu .
JDługosz

2
XML'inizden "50000" değerini gerçekten yeniden etkilemeli ve ayrı bir yapılandırma dosyasına koymalısınız, değil mi? ... ve bu arada, 500000 olması gerekiyordu.
Joker

1
Bir ERE kavramı @jdlugosz, sistemi satın almanız ve ihtiyaçlarınız için yapılandırmanızdır. belki de içsel dev'ler bu 'esnek' sistemlerle rekabet halinde oldukları için onları taklit etmeye çalışacaklardı. IBM gibi büyük şirketlerden gelen sistemlerde bile konfigürasyonun kontrolünü değiştirmek çoğu zaman bir düşünceydi. Satış noktasında hızlı bir değişiklik oldu
Ewan

17

Aksine, “500000” sadece bir sayı değildir. İşlevsellikte bir kırılma noktası fikrini temsil eden önemli bir değer. Bu sayı birden fazla yerde kullanılabilir, ancak kullandığınız sayı değil, bir kuralın geçerli olduğu sınırın / sınır çizgisinin, bunun altında başka bir kuralın fikri.

Ve bununla ifade edilir (ve yorumun bile gereksiz olduğunu iddia edebilirim):

 if (ledgerAmnt >= 500000) {
    //Ledger of 500K or more requires AUTHLDG-1A
    attachDocument("AUTHLDG-1A");
  }

Bu sadece kodun ne yaptığını tekrar ediyor:

LEDGER_AMOUNT_REQUIRING_AUTHLDG1A=500000
if (ledgerAmnt >= LEDGER_AMOUNT_REQUIRING_AUTHLDG1A) {
    //Ledger of 500K or more requires AUTHLDG-1A
    attachDocument("AUTHLDG-1A");
}

Yazarın, 500000'in anlamının bu kurala bağlı olduğunu varsaydığını; başka bir yerde tekrar kullanılması muhtemel olan ya da kullanılması muhtemel olan bir değer değildir:

Tek ve tek iş kuralı, bu önceki Soft Coding'in hesaba katabileceği değişikliklerden biri, AUTHLDG-1A formunu gerektiren defter miktarındaki değişikliktir. Diğer herhangi bir iş kuralı değişikliği daha da fazla iş gerektirecektir - konfigürasyon, dokümantasyon, kod vb.

Makalenin ana noktası, benim görüşüme göre, bazen bir sayı sadece bir sayıdır: Kodda aktarılandan başka bir anlamı yoktur ve başka yerlerde kullanılması muhtemel değildir. Bu nedenle, sadece kodlanmış değerlerden kaçınmak için kodun ne yaptığını (şimdi) değişken bir adla özetlemek, usulsüz bir şekilde tekrarlamak için gereksizdir.


2
Sabiti tanıtırsanız LEDGER_AMOUNT_REQUIRING_AUTHLDG1A, yorumu artık koda yazmazsınız. Yorumlar programcılar tarafından iyi korunmaz. Miktar hiç değiştiyse, ifkoşul ve yorum senkronizasyondan çıkar. Aksine, sabit LEDGER_AMOUNT_REQUIRING_AUTHLDG1Ahiçbir zaman kendisiyle eşitleme yapmaz ve amacını gereksiz yorum yapmadan açıklar.
ZeroOne

2
@ ZeroOne: Eğer işletme kuralı "500K veya daha büyük muhasebe defteri" için AUTHLDG-1A ve AUTHLDG-2B gerektiriyorsa "olarak değişirse, attachDocument("AUTHLDG-2B");çizgiyi ekleyen kişinin aynı anda sabit adı güncellememesi muhtemeldir . Bu durumda, kodun ne bir yorum ne de bir açıklayıcı değişkeni ile yeterince açık olmadığını düşünüyorum . (Bu mantıklı olabilir rağmen kod yorumlar aracılığıyla iş gereksinimleri belgenin uygun bölümü gösteren bir kongre için böyle bir kongre, yapan bir kod comment altında. O burada uygun olacaktır.)
ruakh

@ruakh, tamam, sonra çağrılacak sabiti yeniden denemek isterim LEDGER_AMOUNT_REQUIRING_ADDITIONAL_DOCUMENTS(ki muhtemelen ilk başta yapmalıydım). Ayrıca, iş gereksinimi kimliklerini Git koduna değil kaynak koduna koymayı da alışkanlık haline getirdim.
ZeroOne

1
@ ZeroOne: Ancak AUTHLDG-3C için defter tutarı gerçekten maksimum . Ve AUTHLDG-4D için uygun defter miktarı duruma göre değişir. (Henüz bir noktaya değindiniz mi? Bu tür bir kod için, kodunuzun iş kurallarını soyutlama girişimi değil, iş kurallarını yansıtmasını istersiniz, çünkü iş kurallarının evriminin buna uymasını beklemenin bir nedeni yoktur. kabul ettiğin soyutlamalar.)
ruakh

2
Şahsen, sihirli sayıyı koda koymaya itiraz etmiyorum, kodu yapılandırmaya itiraz ediyorum, bu yüzden bu yorumlara ihtiyacı var. Ben olsaydım, her belgeye kendi attachIfNecessary()yöntemiyle enum örneği yapardım ve hepsinin üzerinden geçtim .
David Moles

8

Diğer cevaplar doğru ve düşünceli. Ama işte benim kısa ve tatlı cevabım.

  Rule/value          |      At Runtime, rule/value…
  appears in code:    |   …Is fixed          …Changes
----------------------|------------------------------------
                      |                 |
  Once                |   Hard-code     |   Externalize
                      |                 |   (soft-code)
                      |                 |
                      |------------------------------------
                      |                 |
  More than once      |   Soft-code     |   Externalize
                      |   (internal)    |   (soft-code)
                      |                 |
                      |------------------------------------

Kurallar ve özel değerler kodun bir yerinde görünüyorsa ve çalışma sırasında değişmiyorsa, soruda gösterildiği gibi kod yazınız.

Kurallar veya özel değerler kodda birden fazla yerde görünüyorsa ve çalışma sırasında değişmiyorsa yazılım kodu. Bir kural için yazılımla kodlama, belirli bir sınıf / yöntem tanımlamam veya Oluşturucu desenini kullanmam olabilir . Değerler için yumuşak kodlama, kodunuzda kullanılacak değer için tek bir sabit veya enum tanımlamak anlamına gelebilir.

Kurallar veya özel değerler çalışma sırasında değişebilirse, bunları dışlamanız gerekir. Genellikle bir veritabanındaki değerler güncellenerek yapılır. Veya veri giren bir kullanıcı tarafından bellekteki değerleri manuel olarak güncelleyin. Değerleri, dosya değişikliği tarih / saat değişikliği için tekrar tekrar taranan bir metin dosyasına (XML, JSON, düz metin, her neyse) kaydederek de yapılır.


1
Cevabını beğendim, ancak uygulamada değişip değişmediğini de düşünmelisin. Bu, örneğin, bir süpervizörün X, vb. Gibi para iadelerini onaylaması gerekip gerekmediği konusunda farklı kurallara sahip olabilecek birçok kuruluşta kullanılacak bir ürün ise, bu
durumla ilgilidir

Hem bu cevapla hem de uygulama hakkındaki yorum ile hemfikir oldular. Üzerinde çalıştığım şeyler birçok kuruluş tarafından uygulanmaktadır ve çoğunun ihtiyaç duydukları incelikle farklı değerleri vardır. Bu 'ayarları' config dosyasından ziyade bir veritabanında saklama eğilimindeyiz, fakat ilke, onu uygulayan her şirket için farklı yazılım derlemeleri yapmak istemememizdir (daha sonra her geliştirdiklerinde bu farklı derlemeleri tekrarla). .
RosieC

7

Bu, bir oyuncak problemi kullanırken düşmemiz ve daha sonra gerçek bir sorunu göstermeye çalıştığımızda sadece strawman çözümleri ortaya çıkarması tuzağıdır .

Verilen örnekte, verilen değerlerin satır içi değerler olarak kodlanmış veya consts olarak tanımlanmış olup olmadığı bir fark değildir.

Örneği bir bakım ve kodlama korkusu yapan çevreleyen koddur. Çevreleyen kod yoksa , snippet en azından sürekli yeniden yapılandırma ortamında olur. Yeniden yapılanmanın gerçekleşme eğiliminde olmadığı bir ortamda, kısa bir süre sonra ortaya çıkacak nedenlerden dolayı bu kodun koruyucular çoktan ölmüştür.

Bak, onu çevreleyen kod varsa, o zaman açıkça kötü şeyler olur.

İlk kötü şey, 50000 değerinin bir yerlerde başka bir değer için kullanılmasıdır, örneğin, bazı eyaletlerde vergi oranının değiştiği defter miktarı ... sonra değişiklik olduğunda, bakıcının bunları bulduğunda bilmesi gereken bir şey yoktur. aynı 50k veya tamamen ilgisiz 50k anlamına gelse de, kodda iki 50000 örneği bulunur. Ayrıca birinin de sabit olarak kullanması durumunda 49999 ve 50001'i de aramalısınız? Bu, bu değişkenleri ayrı bir hizmetin bir yapılandırma dosyasında bölmek için yapılan bir çağrı değildir: ancak satır içi kodlama da açıkça yanlıştır. Bunun yerine, kullanıldıkları sınıf veya dosyada sabit ve tanımlanmış ve kapsamda olmalıdırlar. 50k'nin iki örneği aynı sabiti kullanıyorsa, muhtemelen aynı yasal kısıtlamayı temsil ederler; eğer değilse, muhtemelen yapmazlar; ve her halükarda, bir isimleri olacak.

Dosya adları, temel dosya adlarını dizge olarak, yol ya da uzantı olmadan kabul eden - attachDocument () - işlevine geçirilir. Dosya isimleri, esasen, bazı dosya sistemlerine veya veritabanlarına ya da attachDocument () 'in dosyaları aldığı her yerde yabancı anahtarlardır. Ancak dizgiler size bu konuda hiçbir şey söylemez - kaç dosya var? Hangi dosya türleri? Yeni bir pazara açıldığında bu fonksiyonu güncellemeniz gerekip gerekmediğini nasıl biliyorsunuz? Hangi tür şeylere eklenebilirler? Sağlayıcı tamamen karanlıkta bırakılır ve sahip olduğu tek şey kodda birden çok kez görünebilen ve her göründüğünde farklı şeyler ifade edebilen bir dizedir. Bir yerde, "SR008-04X" bir hile kodudur. Bir diğerinde, dört adet SR008 yükseltici roketi sipariş etmek bir emirdir. Burada' sa dosya adı? Bunlar ilgili mi? Birisi az önce bu işlevi "CLIENT" adlı başka bir dosyadan bahsetmek üzere değiştirdi. O zaman, kötü niyetli, "İSTEMCİ" dosyasının "MÜŞTERİ" olarak yeniden adlandırılması gerektiği söylendi. Ancak "CLIENT" dizgisi kodda 937 kez görünüyor ... nereden bakmaya başlıyorsunuz?

Oyuncak sorun değerler tüm sıradışı ve makul kodunda benzersiz olmasını garanti edilebilir olmasıdır. "1" veya "10" değil, "50,000" değil. "İstemci" veya "rapor" değil, "SR008-04X".

Strawman impenetrably opak sabitlerin sorunu çözmek için tek yol, bazı alakasız hizmetin yapılandırma dosyasında bunları kapalı kovanına olmasıdır.

Birlikte, bu iki yanlışı herhangi bir argümanın doğru olduğunu kanıtlamak için kullanabilirsiniz.


2
Oyuncak problemi değil, pipetçi değil. Bu, bu türden iş uygulamalarında her zaman göreceğiniz bir şeydir . “Yeni bir pazara açılma” yoktur, aynı sayının tekrar kullanımı yoktur (sonuçta, bu yine de başka bir anlam ifade eder) ve her durumda, makale DRY'ye karşı hiçbir şey söylemez - değere iki bağımlılık varsa, ya bir metoda ya da sabite taşınır. Bu sabitlerin (config ayarları, gerçekten önemli değil) nasıl isimlendirilmesi gerektiği ve kodları gelecekteki kanıtı ve koddan daha net bir şekilde depolanması gerektiği örnekleri göster.
Luaan

4
Örnek bozulmuyor çünkü bu bir oyuncak sorunu. Çevreleyen kod her zaman korkunç olacak çünkü yazılımın yürütmesi gereken iş kuralları korku . Kural motorları ve DSL'ler ile bu temel zorluğu bir kenara atmaya çalışır ve programlayıcı ertelemesini sık sık yapmazsanız , çünkü CS sorunlarını çözmek vergi formlarının karmaşıklıklarını çözmekten daha zevklidir. 'Eleganlığı' başarma girişimleri çoğu zaman aptaldır; çünkü yazılımın nihai görevi karmaşık bir felaketi modellemektir.
whatsisname,

İş kuralları korku olabilir, ancak bu kendi başına bu tür vasat prosedür kodunu yazmak için bir bahane değil. (Papadimoulis ile kuralları kodlamada modellemenin ve düzenlemenin daha kolay olması gerektiğine karar vermenin daha kolay olduğuna katılıyorum, sadece daha iyi kod olması gerektiğini düşünüyorum.) Gördüğüm DRY sorunu sihirli sayılar değil, tekrar ediyor if (...) { attachDocument(...); }.
David Moles,

2

Bunda birkaç sorun var.

Bir sorun, tüm kuralları programın dışında kolayca yapılandırılabilir hale getirmek için bir kural altyapısının oluşturulması gerektiğidir. Buna benzer durumlarda cevap çoğu zaman hayır. Kurallar, tahmin edilmesi zor garip şekillerde değişecek; bu da, bir değişiklik olduğunda kural motorunun genişletilmesi gerektiği anlamına geliyor.

Başka bir sorun, bu kuralların nasıl ele alınacağı ve sürüm kontrolünüzdeki değişikliklerin nasıl yapılması gerektiğidir. Buradaki en iyi çözüm, kuralları her kural için bir sınıfa bölmektir.

Bu, her kuralın kendi geçerliliğine sahip olmasına izin verir, bazı kurallar her yıl değişir, bazı izinler verildiğinde veya bir fatura verildiğinde bazı değişiklikler yapılır. Hangi versiyonun uygulanacağı kontrolünü içeren kural.

Ayrıca sabit özel olduğu için kodda başka bir yerde yanlış kullanılamaz.

Sonra tüm kuralların bir listesini yapın ve listeyi uygulayın.

Diğer bir konu ise sabitlerin nasıl ele alınacağıdır. 500000 göze çarpmayan görünebilir ancak doğru şekilde dönüştürüldüğünden emin olmak için çok dikkatli olunması gerekir. Herhangi bir kayan nokta aritmetiği uygulanırsa, 500.000.00001'e dönüştürülebilir, bu nedenle 500.000.00000 ile bir karşılaştırma başarısız olabilir. Veya daha da kötüsü 500000 her zaman amaçlandığı gibi çalışır, ancak bir şekilde 565000 dönüştürüldüğünde başarısız olur. Dönüşümün açık olduğundan ve derleyici tahmininde bulunmadığınızdan emin olun. Bu, kullanılmadan önce bazı BigInteger veya BigDecimal dosyalarına dönüştürülerek yapılır.


2

Doğrudan soruda bahsedilmese de, önemli olanın iş mantığını koda gömmemek olduğunu belirtmek isterim .

Kod, yukarıdaki örnekte, gibi kodlar gerçekten kaynak ağacının, belki adında ayrı bir bölümünde yaşaması gerektiği dışarıdan belirtilen iş ihtiyaçlarını businesslogico sağlamak için ya da benzer bir şey ve dikkatli olunmalıdır sadece okunabilecek şekilde, basitçe iş ihtiyaçlarını kodlar ve en az kazan ile ve net ve bilgilendirici yorumlarla mümkün olduğu kadar kesin.

O gerektiğini değil "altyapı" koduyla karıştırılabilir uygulayan böyle demek gibi iş mantığını yürütmek için gereken işlevselliğe, uygulanması attachDocument()genel olarak örnekteki yöntemle veya örneğin UI, günlük veya veritabanı kodu. İken bir bu ayrılığı zorlamak için bir yol bir yapılandırma dosyasında "yumuşak kod" Tüm iş mantığı için, bu kadar sadece (veya en iyi) yönteminden olduğunu.

Bu tür bir iş mantığı kodu, kodlama becerisine sahip olmayan bir iş alanı uzmanına göstermiş olsanız, bunu anlayabilecekleri kadar net bir şekilde yazılmalıdır. En azından, eğer işletme gereksinimleri değişiyorsa ve bunları değiştirdiğinde, kodlayan kodun önceden tanımlanmış bir ailesi olmayan yeni bir programcının bile, iş mantığını kolayca bulabilmesi, gözden geçirebilmesi ve güncelleyebilmesi gerektiği açık olmalıdır. niteliksel olarak yeni işlevler gerekli değildir.

İdeal olarak, bu tür bir kod aynı zamanda iş mantığı ve temel altyapı arasındaki ayrımı zorlamak için alana özgü bir dilde de yazılabilir, ancak temel bir kurum içi uygulama için gereksiz yere karmaşık olabilir. Bununla birlikte, örneğin, her birinin kendi özel iş kurallarına ihtiyacı olan yazılımı birden çok müşteriye satıyorsanız, basit bir etki alanına özgü komut dosyası dili (örneğin, bir Lua sanal alanına göre ) sadece bir şey olabilir.


Bu tam olarak ne düşünüyordum !!! Mantık kodun derinliklerine gömüldüğünde, bir alan / konu uzmanı veya işletme kullanıcısı doğru olduklarından emin olmak ve sistemin davranışını teşhis etmek için kullanılan değerleri ve mantığı nasıl görebilir? Bir yapılandırma dosyasının yaptığı tek şey ayarları görünür hale getirmektir . İş kurallarının görünürlüğünü arttırmanın bir yolu olmalı - kodlamayı "zorlaştırsa" bile. İş kullanıcısı, diğer kaygılara karışmadan - işi kullanıcılara erişme ve anlama araçlarına sahip olduğu sürece, ince bir sınıfı veya işi yapan sınıfları kabul edebilirim.
ErikE,
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.