Asla değişmeyecek sabit kod dizeleri


39

Bu yüzden, Fransızca için fiilleri (algoritmik olarak değil, veri kümesi aracılığıyla) eşlenikleştirmek için bir program yazma çabalarımda ufak bir sorunla karşılaştım.

Fiilleri birleştiren algoritma, fiilleri 17 ya da öylesine fiil durumları için oldukça basittir ve her durum için belirli bir düzen üzerinde çalışır; bu nedenle, bu 17 sınıf için eşlenik sonekleri statiktir ve yakın zamanda herhangi bir zamanda değişmeyecektir (büyük olasılıkla). Örneğin:

// Verbs #1 : (model: "chanter")
    terminations = {
        ind_imp: ["ais", "ais", "ait", "ions", "iez", "aient"],
        ind_pre: ["e", "es", "e", "ons", "ez", "ent"],
        ind_fut: ["erai", "eras", "era", "erons", "erez", "eront"],
        participle: ["é", "ant"]
    };

Bunlar, Fransızca'daki en yaygın fiil sınıfı için çekim ekleridir.

Konjugasyonları da muhtemelen gelecek bir iki yüzyıl için durağan kalacak başka fiil sınıfları (düzensiz) vardır. Düzensiz olduklarından tam eşleniklerinin statik olarak dahil edilmesi gerekir, çünkü bir örüntüden güvenilir şekilde konjuge edilemezler (ayrıca sadece [sayım] 32 düzensizler de vardır). Örneğin:

// "être":
    forms = {
        ind_imp: ["étais", "étais", "était", "étions", "étiez", "étaient"],
        ind_pre: ["suis", "es", "est", "sommes", "êtes", "sont"],
        ind_fut: ["serai", "seras", "sera", "serons", "serez", "seront"],
        participle: ["été", "étant"]
    };

Bütün bunları XML'e, hatta JSON'a koyabilir ve kullanılması gerektiğinde seri hale getirebilirim, ama bir nokta var mı? Bu dizeler, değişen, ancak yavaş bir oranda, doğal dilin bir parçasıdır.

Benim endişe şeyler "doğru" yolu yapıyor ve bazı veri kaynağını deserializing etmekle, yok sorunu karmaşık değil olmanızdır ihtiyaç karmaşık olmak, ama aynı zamanda tamamen bütün hedefe arka takip ettik algoritmik yaklaşım: için değil bir veri kaynağı kullanın! C # 'da, bu dizeleri numaralandırılmış türde ya da bir şeyde barındırmak için namespace Verb.Conjugation(örn. class Irregular) Altında bir sınıf oluşturabilirim , onları XML içine doldurmak ve a oluşturmak class IrregularVerbDeserializer.

Söz Yani: o vardır koda dizeleri uygundur çok bir uygulamanın ömrü boyunca değişim pek mümkün? Elbette değişmeyeceklerinin% 100'ünü garanti edemiyorum, ancak maliyete karşı risk neredeyse gözlerimdeyken önemsiz - kodlama burada daha iyi bir fikir.

Düzenleme : Önerilen yinelenen sorar statik dizeleri çok sayıda saklamak için nasıl benim sorum ise, ne zaman yapayım ki koda Bu statik dizeleri .


26
Gelecekte bu yazılımı Fransızca'dan başka bir dil için kullanmak isteyebilir misiniz?

10
Algoritmik yaklaşım olsun ya da olmasın, bu 32 * 20 karakter dizilerini (ve daha fazla dil eklerken daha fazla kod yazmanız) basitçe kodlamanız gerektiği ve tek gerçek soru onları nereye koyacağınızdır. Sizin için en uygun olanı seçerim, ki şu an için kodda olduğu gibi geliyor. Onları daha sonra her zaman karıştırabilirsin.
Ixrec

1
@ChrisCirefice Bu bana oldukça uygun geliyor. Göreyim seni.
Ixrec

2
@Gusdor Açıkça okuduğunuzu sanmıyorum - Konjugasyon paternlerinin muhtemelen hiç değişmeyeceğini ya da değişmeyeceğini, bu yüzden nadiren her 100 yılda bir yeniden derlenmenin iyi olacağını söyledi. Elbette kod değişecek, ancak dizgiler oraya girdiğinde, nasıl yeniden istediğimde, yeniden düzenleme yapmadığım sürece gelecek 100 yıl boyunca durağan olacaklar.
Chris Cirefice

1
+1. 60-100 yıl içerisinde maliyetin var olmayacağını ya da tamamen daha iyi bir versiyonla değiştirileceğini söylemeye gerek yok.
HarryCBurn

Yanıtlar:


56

uygulamanın kullanım ömrü boyunca değişmesi muhtemel olmayan kod dizgilerine uygun mu? Elbette değişmeyeceklerinin% 100'ünü garanti edemiyorum, ancak maliyete karşı risk neredeyse gözlerimde ağır basmak için önemsizdir - kodlama burada daha iyi bir fikirdir

Bana göre kendi sorunuzu cevapladınız.

Karşılaştığımız en büyük zorluklardan biri, değişmesi muhtemel olan şeyleri değişmeyecek olan şeylerden ayırmaktır. Bazı insanlar delirir ve ellerinden gelen her şeyi kesinlikle bir config dosyasına dökerler. Diğerleri diğer uç noktasına gider ve en belirgin değişiklikler için bile bir derleme gerektirir.

Bunu daha karmaşık hale getirmek için zorlayıcı bir neden bulana kadar uygulamak için en kolay yaklaşıma giderdim.


Sağol Dan, düşündüğüm gibi bir şey. Bunun için bir XML şeması yazmak, izlenmesi gereken başka bir dosyaya sahip olmak ve verileri seri hale getirmek için bir arabirim yazmak zorunda kalmak, tıpkı fazla sayıda dize gibi görünmediği düşünülüyor gibi görünüyordu. önümüzdeki 100 yıl içinde. Neyse ki, bugünlerde programlama dillerinde, bu ham veriyi güzel görünümlü bir arayüzün arkasına soyutlamak için, örneğin French.Verb.Irregular.Etresorumun verilerini içeren fantazi yöntemlerimiz var . Ben yolunda
gider

3
+1 Burada Ruby kampından, kodlama işlemine başlar ve gerektiğinde yapılandırmak için taşınırdım. İşleri yapılandırılabilir hale getirerek projenizi zaman aşımına uğramayın. Sadece seni yavaşlatıyor.
Overbryd

2
Not: Bazı grupların farklı bir "hardcoding" tanımı vardır, bu yüzden bu terimin birden fazla şey ifade ettiğini unutmayın. Değerlerinizi, bir fonksiyonun ifadelerine kodladığınız, bildiğiniz gibi veri yapıları oluşturmaktan ziyade iyi tanımlanmış bir kalıp vardır if (num == 0xFFD8). Bu örnek if (num == JPEG_MAGIC_NUMBER), hemen hemen her durumda okunabilirlik nedeniyle olduğu gibi bir şey haline gelmelidir . Ben sadece şunu işaret ediyorum, çünkü "hardcoding" kelimesi, insanların alternatiflerine bağlı olarak sık sık kılları çıkarır (benimki gibi).
Cort Ammon

@CortAmmon JPEG çok sayıda sihirli numaraya sahiptir. Kesinlikle JPEG_START_OF_IMAGE_MARKER?
user253751

@ immibis Sabit adlandırma seçiminiz muhtemelen benimkinden daha iyi.
Cort Ammon

25

Yanlış kapsamda akıl yürütüyorsunuz.

Sadece bireysel fiilleri kodlamadın. Dili ve kurallarını kodladınız . Bu da, başvurunuzun başka bir dil için kullanılamayacağı ve başka kurallarla genişletilemeyeceği anlamına gelir.

Bu sizin amacınızsa (yani sadece Fransızca için kullanıyorsanız), YAGNI nedeniyle doğru yaklaşım budur. Ancak, daha sonra başka diller için de kullanmak istediğinizi kendiniz kabul ediyorsunuz, bu çok yakında, tüm kodlanmış kısımları yine de yapılandırma dosyalarına taşımak zorunda kalacağınız anlamına gelir. Kalan soru şudur:

  • Yakın gelecekte% 100'e yakın bir kesinlikte uygulamayı diğer dillere yayabilecek misiniz? Öyleyse , uygulamanızın ana bölümünü yeniden yazmaya zorlamak yerine, şeyleri şu anda JSON veya XML dosyalarına (kelimeler için, kelimelerin bir kısmı, vb.) Ve dinamik dillere (kurallar için) ihraç ediyor olmalısınız .

  • Veya uygulamanın gelecekte bir yere genişletilmesi için küçük bir olasılık var, bu durumda YAGNI en basit yaklaşımın (şu anda kullandığınız) daha iyi olduğunu belirtiyor?

Örnek olarak, Microsoft Word'ün yazım denetleyicisini alın. Sence kodlanmış kaç şey var?

Bir metin işlemcisi gelişmekte iseniz, kodlanmış kurallar ve hatta kodlanmış sözlerle basit yazım motoru tarafından başlayabileceğini: if word == "musik": suggestSpelling("music");. Hızla, kelimeleri taşımaya başlayacaksın, sonra kendini kodunun dışında yöneteceksin. Aksi takdirde:

  • Ne zaman bir kelime eklemek zorundaysan, tekrar derlemek zorundasın.
  • Yeni bir kural öğrendiyseniz, kaynak kodunu bir kez daha değiştirmeniz gerekir.
  • Daha da önemlisi, motoru çok büyük miktarda kod yazmadan Almanca ya da Japonca'ya uyarlamanın bir yolu yoktur.

Kendinizi vurguladığınız gibi:

Fransızca'dan çok az kural Japoncaya uygulanabilir.

Bir dilin kurallarını zorladığınız anda, her biri, özellikle doğal dillerin karmaşıklığı göz önüne alındığında, daha fazla kod gerektirecektir.

Başka bir konu, kodları değil, farklı kuralları nasıl ifade ettiğinizdir. Sonuçta, bir programlama dilinin bunun için en iyi araç olduğunu görebilirsiniz. Bu durumda, motoru tekrar derlemeden uzatmanız gerekirse, dinamik diller iyi bir alternatif olabilir.


1
Tabii ki orada her şey kodlanmış değil: P sanırım arayüzün neye benzemesini istediğimi belirlemeye başlıyorum, böylece birden çok dile uygulayabiliyorum. Sorun şu ki, henüz tüm dilleri yeterince iyi tanımıyorum, bu yüzden bu kesinlikle imkansız. Sanırım eksik olduğun tek şey, konjugasyon kalıplarının (benim de bahsettiğim şey bu), bir dilde çok durağan olduğudur ve bu, gerçekten duruma göre olan bir şeydir. Fiiller için Fransızca'da yaklaşık 17 eşlenik kalıp vardır. Yakında herhangi bir zaman uzatmayacak ...
Chris Cirefice

4
Katılmıyorum - yeniden yapılanma sırasında doğal olarak gelmeden önce herhangi bir şeyi kodun dışına çıkarmanın bir anlamı olmadığını düşünüyorum. Bir dille başlayın, başkalarını ekleyin - bir noktada ILanguageRule uygulaması, bir XML (veya başka bir dosya ile) parametreli hale getirilmiş tek bir uygulamanın daha verimli olması için gereken kodu paylaşacaktır. Fakat o zaman bile tamamen farklı bir yapıya sahip olan Japonlarla başa çıkabilirsiniz. Arayüzünüzü XML (veya benzeri) olmaya zorlayarak başlamak, yalnızca uygulamada değişiklik yapmak yerine arayüzde değişiklik yapmak için yalvarıyor.
ptyx

2
Not: Daha fazla dil eklemek istiyorsanız, bu, dilleri bir yapılandırma dosyasına taşımak anlamına gelmez! Aynı derecede LanguageProcessorbirden fazla alt sınıfı olan bir sınıfa sahip olabilirsiniz . (Etkili olarak, "config dosyası" aslında bir sınıftır)
user253751

2
@MainMa: Neden bir kelime eklerken yeniden derlemenin bir sorun olduğunu düşünüyorsun? Yine de kodda başka bir değişiklik yaparken yeniden derlemeniz gerekir ve sözcüklerin listesi muhtemelen zamanla değişmesi en muhtemel olan kodun bir parçasıdır .
JacquesB

3
Bir alt sınıftaki her dilin çok özel gramer kurallarını kodlayabilme esnekliğinin sonunda aynı kuralları bir yapılandırma dosyasından yükleme yeteneğinden daha uygun olacağından şüpheleniyorum (çünkü yapılandırmaları yorumlamak için kendi programlama dili).
David K

15

Değerler program mantığından bağımsız olarak değişebiliyorsa , dizeler bir yapılandırma dosyasına veya veritabanına çıkarılmalıdır .

Örneğin:

  • UI metinlerini kaynak dosyalarına çıkarma. Bu, programcı olmayan bir kişinin metinleri düzenlemesini ve prova okumasını ve yeni yerelleştirilmiş kaynak dosyaları ekleyerek yeni diller eklemesini sağlar.

  • Konfigürasyon dosyalarına bağlantı dizgilerinin, URL'lerin harici servislere vs. çıkarılması. Bu, farklı ortamlarda farklı yapılandırmaları kullanmanıza ve anında yapılandırmaları değiştirmenize izin verir, çünkü uygulamanızın dışındaki nedenlerden dolayı değişmeleri gerekebilir.

  • Kontrol edilecek kelimelerin sözlüğüne sahip bir yazım denetleyicisi. Program mantığını değiştirmeden yeni kelimeler ve diller ekleyebilirsiniz.

Ancak, yapılandırmaya ayıklanan ek bir karmaşıklık da var ve bu her zaman mantıklı değil.

Program mantığını değiştirmeden gerçek string değişemediğinde dizeler kodlanmış olabilir.

Örnekler:

  • Bir programlama dili için bir derleyici. Anahtar kelimeler bir yapılandırmaya ayıklanmaz, çünkü her bir anahtar kelimenin derleyicideki kodla desteklenmesi gereken belirli bir semantiği vardır. Yeni bir anahtar kelime eklemek her zaman kod değişikliği gerektirir, bu nedenle dizeleri bir yapılandırma dosyasına çıkarmanın bir değeri yoktur.
  • Bir protokol uygulamak: Ör. Bir HTTP istemcisi, "GET", "content-type" vb. gibi kodlanmış dizgilere sahip olacaktır. Burada dizgiler protokolün belirtiminin bir parçasıdır, bu yüzden kodun değişmesi en muhtemel parçalarıdır .

Sizin durumunuzda, kelimelerin program mantığının bütünleşik bir parçası olduğu (belirli kelimeler için belirli kuralları olan bir konjugatör oluşturduğunuzdan) ve bu kelimeleri harici bir dosyaya çıkarmanın bir değeri olmadığını düşünüyorum.

Yeni bir dil eklerseniz, yine de yeni bir kod eklemeniz gerekir, çünkü her dilin kendine özgü bir eşleşme mantığı vardır.


Bazıları, isteğe bağlı diller için eşlenik kurallar belirlemenizi sağlayan bir tür kural motoru ekleyebilmenizi önerdi , bu nedenle yeni diller yalnızca yapılandırma ile eklenebilir. O yola girmeden önce çok dikkatli düşünün, çünkü insan dilleri oldukça gariptir, bu nedenle çok etkileyici bir kural motoruna ihtiyacınız vardır. Temel olarak , şüpheli fayda için yeni bir programlama dili (konjugasyon DSL) icat ediyor olacaktınız . Ancak, emrinizde, ihtiyaç duyduğunuz her şeyi yapabileceğiniz bir programlama dili zaten var. Her durumda, YAGNI.


1
Aslında, MainMa'ya yapılan bir yorumda, bunun için bir DSL yazmanın anlamsız olacağından bahsettim, çünkü çok az sayıda doğal dil, çabaya değecek kadar benzer. Belki Fransızca / İspanyolca / İtalyanca yeterince yakın olurdu , ancak kuralların herhangi bir dilde yüksek derecede statik olduğunu göz önünde bulundurarak fazladan çabaya değmezdi. Karmaşıklıktan bahsettiğiniz diğer noktalar benim endişelerimden biriydi ve bence soruma sorduğum şeyi çok iyi anladığınızı ve örneklerle harika bir cevap verdiğinizi düşünüyorum.
Chris Cirefice

5

Dan Pichelman'ın cevabına% 100 katılıyorum, ancak eklemek istediğim bir şey var. Burada kendinize sormanız gereken soru “kelime listesini kim koruyacak / genişletecek / düzeltecek?”. Her zaman belirli bir dilin kurallarını da koruyan kişi ise (belirli geliştirici, sanırım siz), o zaman işleri daha karmaşık hale getirirse harici bir yapılandırma dosyası kullanmanın bir anlamı yoktur - bundan faydalanamazsınız bu. Bu bakış itibaren, sen bile böyle kelime listeleri kodlamalısınız mantıklı hale getirecek olan zaman zaman bunları değiştirmek için yeni bir sürümünün bir parçası olarak yeni bir liste sunmak için yeterli olduğu sürece,.

(Öte yandan, ileride birisinin listeyi koruyabilmesi için hafif bir şans varsa veya uygulamanızın yeni bir sürümünü dağıtmadan sözcük listelerini değiştirmeniz gerekirse, ayrı bir dosya kullanın.)


Bu iyi bir nokta - ancak, en azından önümüzdeki birkaç yıl boyunca, kodu koruyan tek kişi ben olacağım. Bunun iyi yanı, dizelerin kodlanmış olmasına rağmen, kısa bir süre içinde herhangi bir zaman değişmesi muhtemel olmayan çok küçük bir dizi dizi / kuraldır (doğal bir dil olduğu için, yıllarca değişmez. -yıl). Bununla birlikte, fiil çekimi kuralları, fiil sonlandırma dizeleri vb., Ömür boyu aynı olacaktır :)
Chris Cirefice

1
@ChrisCirefice ": tam olarak amacım.
Doc Brown

2

Burada kodlama iyi görünse bile ve config dosyalarını dinamik olarak yüklemekten daha iyi olsa da , verilerinizi (fiillerin sözlüğü) algoritmadan kesinlikle ayırmanızı öneririm . Onları derleme işleminde doğrudan uygulamanıza derleyebilirsiniz.

Bu, listenin bakımı ile size çok fazla tasarruf sağlayacaktır. VCS'nizde, bir taahhüdün algoritmayı değiştirip değiştirmediğini kolayca belirleyebilirsiniz veya bir konjugasyon hatası düzeltin. Ayrıca, dikkate almadığınız durumlar için listenin gelecekte eklenmesi gerekebilir. Özellikle, saydığınız 32 düzensiz fiilin sayısı tam olarak görünmüyor. Bunlar yaygın olarak kullanılanları kapsıyor gibi görünse de, 133'üne hatta 350'sine referanslar buldum .


Bergi, verileri algoritmadan ayırmayı planladım. Tanımı - Fransız düzensiz ilgili dikkat ne gayri muntazam en iyi yanlış anlaşılır. Düzensiz derken kastettiğim şey, 'hesaplanamayan' ya da tek başına sonsuz biçimlerinden konjuge edilemeyen fiillerdir. Düzensiz fiillerin hiçbir özel bir şekli yoktur ve bu yüzden konjugasyonlarının açıkça listelenmesi gerekir (örneğin, French.Verb.Conjugation.Irregular` altında). Teknik olarak, -ir fiilleri 'düzensiz', ama aslında sabit bir eşlenik düzenine
sahipler

0

Önemli olan kaygıların ayrılmasıdır. Bunu nasıl başardığın daha az alakalı. yani Java iyi.

Kuralların nasıl ifade edildiğinden bağımsız olarak, bir kural değişikliği dili eklemeniz gerekir: kaç tane kod ve dosya düzenlemek zorundasınız?

İdeal olarak, yeni bir dil eklemek, bir 'english.xml' dosyası ekleyerek veya yeni bir 'EnglishRules ILanguageRules' nesnesini uygulayarak mümkün olmalıdır. Bir metin dosyası (JSON / XML), bunu derleme yaşam biçiminizin dışında değiştirmek istiyorsanız, ancak karmaşık bir gramer gerektirdiğinde, ayrıştırırken ve hata ayıklaması daha zor olacağında size bir avantaj sağlar. Bir kod dosyası (Java), karmaşık kuralları daha basit bir şekilde ifade etmenizi sağlar, ancak yeniden oluşturulmasını gerektirir.

Her iki durumda da ihtiyaç duyduğunuz gibi temiz bir dil agnostik arayüzün arkasındaki basit bir Java API ile başlayacağım. İsterseniz, daha sonra bir XML dosyası tarafından desteklenen bu arabirimin bir uygulamasını daha sonra isterseniz ekleyebilirsiniz, ancak bu sorunu hemen (veya hiç) çözme gereğini görmüyorum.

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.