変更されない文字列のハードコーディング


39

そのため、フランス語の動詞(データセットではなく、アルゴリズム)を活用するプログラムを作成しようとすると、ちょっとした問題に遭遇しました。

動詞を活用するアルゴリズムは、実際には動詞の17程度のケースではかなり単純であり、各ケースの特定のパターンで実行されます。したがって、これらの17のクラスの活用接尾辞は静的であり、(ほとんどの場合)すぐに変更されることはありません。例えば:

// 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"]
    };

これらは、フランス語の最も一般的な動詞クラスの接尾辞です。

他のクラスの動詞(不規則)がありますが、その活用も次の1世紀または2世紀の間は変化しないでしょう。これらは不規則であるため、パターンから確実に共役できないため、完全な共役を静的に含める必要があります(32の不規則もあります)。例えば:

// "ê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"]
    };

これらすべてをXMLまたはJSONに入れて、使用する必要があるときにデシリアライズできますが、ポイントはありますか?これらの文字列は自然言語の一部であり、変化しますが、遅い速度です。

私の懸念は、「正しい」方法でデータソースをデシリアライズすることで、複雑にする必要のない問題を複雑化するだけでなく、アルゴリズム的アプローチ:データソースを使用しない!C#では、これらの文字列をXMLに詰め込んでを作成する代わりに、列挙型などにこれらの文字列を格納するためのクラスをnamespace Verb.Conjugation(たとえばclass Irregular)作成するだけで済みますclass IrregularVerbDeserializer

質問:アプリケーションの存続期間中に変更される可能性非常に低い文字列をハードコードすることは適切ですか?もちろん、それらが変更されないことを 100%保証することはできませが、リスクとコストは私の目にはほとんど重さはありません。ここではハードコーディングの方が良い考えです。

編集提案された複製、多数の静的文字列を保存する方法を尋ねますが、私の質問は、これらの静的文字列をいつハードコーディングする必要があるかです


26
将来、このソフトウェアをフランス語以外の異なる言語で使用したいと思いますか?

10
アルゴリズム的アプローチかどうかにかかわらず、これらの32 * 20文字列をハードコーディングするだけで(さらに言語を追加するとさらにコードが追加される)、それがどこにあるのかが唯一の本当の問題であることが明らかです。私はあなたにとって最も便利だと思うところならどこでも選びますが、それは当分の間コードの中にあるように聞こえます。後からいつでもシャッフルできます。
Ixrec

1
@ChrisCireficeそれは私にとって非常に最適に聞こえます。頑張れ。
Ixrec

2
@Gusdorあなたがはっきりと読んでいるとは思わない- 共役のパターンは決して変わらないか、100年ごとに再コンパイルするのが良いほど頻繁に変わることはないと言った。もちろんコードは変更されますが、リファクタリングを行っていない限り、文字列がそこにあると私はそれらをどのようにしたいのか、今後100年間静的です。
クリスクレフィス

1
+1。言うまでもなく、60〜100年後にはコストがなくなるか、完全により良いバージョンに置き換えられます。
HarryCBurn

回答:


56

アプリケーションの存続期間中に変更される可能性が非常に低い文字列をハードコードすることは適切ですか?もちろん、それらが変わらないことを100%保証することはできませんが、リスクとコストは私の目にはほとんど重さはありません- ここではハードコーディングが良い考えです

あなたは自分の質問に答えたようです。

私たちが直面する最大の課題の1つは、変化する可能性のあるものと変わらないものを区別することです。一部の人々は気を狂わせて、できる限りすべてを構成ファイルにダンプします。他の極端な場合は、最も明白な変更でも再コンパイルが必要です。

それをより複雑にする説得力のある理由が見つかるまで、実装する最も簡単なアプローチを採用します。


おかげでダン、それは私が考えたようなものです。このためのXMLスキーマを記述し、追跡する別のファイルを用意し、データを逆シリアル化するためのインターフェイスを記述する必要があるのは、文字列がそれほど多くないことを考えると、やり過ぎのように思えます。次の100年で。幸いなことに、最近のプログラミング言語では、この生データを見栄えの良いインターフェースの背後に抽象化する素晴らしい方法があります。たとえばFrench.Verb.Irregular.Etre、私の質問からのデータが含まれます。大丈夫だと思う;)
クリスクレフィス

3
+1ここでは、Rubyキャンプからハードコーディングを開始し、必要に応じてconfigに移動します。物事を構成可能にすることによって、プロジェクトを時期尚早に過剰に設計しないでください。それはただあなたを遅くします。
オーバーブライド

2
注:一部のグループでは「ハードコーディング」の定義が異なるため、この用語は複数のことを意味することに注意してください。(if (num == 0xFFD8))のようにデータ構造を作成するのではなく、関数のステートメントに値をハードコーディングするアンチパターンがよく知られています。その例はif (num == JPEG_MAGIC_NUMBER)、読みやすさの理由から、ほとんどすべての場合のようになります。「ハードコーディング」という言葉は、この言葉の別の意味のために、(私のような)人々の首にしばしば髪を上げるので、私はそれを指摘するだけです。
コートアンモン

@CortAmmon JPEGには多くのマジックナンバーがあります。確かにJPEG_START_OF_IMAGE_MARKER
user253751

@immibis定数の命名の選択は、おそらく私よりも優れています。
コートアンモン

25

あなたは間違った範囲で推論しています。

個々の動詞のみをハードコーディングしていません。言語とその規則をハードコーディングしました。これは、アプリケーションが他の言語で使用できず、他のルールで拡張できないことを意味します。

これがあなたの意図である場合(つまり、フランス語のみで使用する場合)、YAGNIのため、これは正しいアプローチです。しかし、後で他の言語でも使用したいことを認めます。つまり、いずれにせよ、ハードコーディングされたすべての部分を構成ファイルに移動する必要があります。残りの質問は次のとおりです。

  • 100%に近い確実性で、近い将来、アプリを他の言語に拡張しますか?その場合、アプリの大部分を書き換えるのではなく、JSONファイルまたはXMLファイル(単語、単語の一部など)および動的言語(ルール)に物事をエクスポートする必要があります。

  • または、アプリが将来どこかで拡張される可能性はわずかですが、その場合、YAGNIは最も簡単なアプローチ(現在使用しているアプローチ)の方が良いと指示しますか?

例として、Microsoft Wordのスペルチェックを使用します。ハードコードされているものはいくつあると思いますか?

テキストプロセッサを開発している場合は、ハードコーディングされたルールとハードコーディングされた単語を備えた単純なスペルエンジンから始めることができますif word == "musik": suggestSpelling("music");。すぐに、単語の移動を開始し、コードの外側でルールをルール化します。さもないと:

  • 単語を追加する必要があるたびに、再コンパイルする必要があります。
  • 新しいルールを学習した場合は、ソースコードをもう一度変更する必要があります。
  • さらに重要なことは、膨大な量のコードを書かずにエンジンをドイツ語または日本語に適合させる方法がないことです。

あなた自身を強調したように:

フランス語のルールはほとんど日本語に適用できませんでした。

言語のルールをハードコーディングするとすぐに、特に自然言語の複雑さを考えると、他のすべてのルールでますます多くのコードが必要になります。

もう1つの主題は、コードを使用しない場合、これらのさまざまなルールをどのように表現するかです。最終的に、プログラミング言語そのための最良のツールであることに気付くかもしれません。その場合、エンジンを再コンパイルせずに拡張する必要がある場合は、動的言語が適切な代替手段になる可能性があります。


1
もちろん、すべてがハードコードされているわけではありません:Pので、複数の言語に適用できるように、インターフェイスをどのように表示するかを決定することになります。問題は、まだすべての言語を十分に理解していないため、事実上不可能です。おそらくあなたが見逃している1つのことは、共役パターン(これは私が話しているすべてです)は言語では非常に静的であり、それは本当にケースバイケースのことです。フランス語には動詞の約17の活用パターンがあります。...いつでもすぐに延長するつもりはない
クリスCirefice

4
私は同意しません-リファクタリングによって自然に来る前にコードの外側に何かを移動することは理にかなっていないと思います。1つの言語から始めて、他の言語を追加します-ある時点で、ILanguageRuleの実装は、XML(または他のファイル)でパラメーター化された単一の実装を持つ方が効率的である十分なコードを共有します。しかし、それでもまったく異なる構造を持つ日本語になってしまうかもしれません。インターフェースをXML(または同様のもの)にすることから始めるのは、実装ではなくインターフェースに変更を加えることだけです。
ptyx

2
注:言語をさらに追加したい場合、それは言語を構成ファイルに移動することを意味しません!同様に、LanguageProcessor複数のサブクラスを持つクラスを作成することもできます。(事実上、「構成ファイル」は実際にはクラスです)
user253751

2
@MainMa:単語を追加するときに再コンパイルすることが問題だと考えるのはなぜですか?とにかくコードに他の変更を行う場合は、再コンパイルする必要があり、単語のリストはおそらく、時間の経過とともに変更される可能性が最も低いコードの一部です。
ジャックB

3
サブクラス内の各言語の非常に具体的な文法規則をコーディングできる柔軟性は、構成ファイルからそれらの同じ規則を何らかの方法でロードする機能よりも最終的には便利だと思います(基本的には構成を解釈する独自のプログラミング言語)。
デビッドK

15

値がプログラムロジックから独立して変化する可能性がある場合、文字列を構成ファイルまたはデータベースに抽出する必要があります。

例えば:

  • リソースファイルへのUIテキストの抽出。これにより、非プログラマーがテキストを編集および校正することができ、新しいローカライズされたリソースファイルを追加して新しい言語を追加できます。

  • 接続ファイル、外部サービスへのURLなどを構成ファイルに抽出します。これにより、異なる環境で異なる構成を使用したり、アプリケーションの外部の理由で変更が必要な場合があるため、その場で構成を変更したりできます。

  • 照合する単語の辞書があるスペルチェッカー。プログラムロジックを変更せずに、新しい単語と言語を追加できます。

ただし、構成への抽出には複雑なオーバーヘッドもあり、常に意味があるとは限りません。

文字列ができるハードコーディング、実際の文字列は、プログラムロジックを変更せずに変更することができないとき。

例:

  • プログラミング言語用のコンパイラ。各キーワードには特定のセマンティクスがあり、コンパイラのコードでサポートする必要があるため、キーワードは構成に抽出されません。新しいキーワードを追加するには、常にコードを変更する必要があるため、構成ファイルに文字列を抽出しても値はありません。
  • プロトコルの実装:例。HTTPクライアントには、「GET」、「content-type」などのハードコードされた文字列があります。ここで、文字列はプロトコルの仕様の一部であるため、変更の可能性最も低いコードの一部です。

あなたの場合、単語はプログラムロジックの統合された部分であることは明らかだと思います(特定の単語の特定のルールを持つ共役器を構築しているため)、これらの単語を外部ファイルに抽出することは価値がありません。

新しい言語を追加する場合、とにかく新しいコードを追加する必要があります。各言語には特定の活用ロジックがあるためです。


ある種の規則エンジンを追加して、任意の言語の活用規則を指定できるようにすることを提案しているため、構成によって純粋に新しい言語を追加できます。その道を進む前に非常に慎重に考えてください。人間の言語は非常に奇妙なので、非常に表現力の高いルールエンジンが必要です。あなたは基本的に疑わしい利益のために新しいプログラミング言語(共役DSL)を発明するでしょう。しかし、あなたはすでにあなたが自由に使えるプログラミング言語を持っています。いずれにしても、YAGNI。


1
実際、MainMaへのコメントで、このためにDSLを書くことは、努力するだけの価値があるほど類似している自然言語はほとんどないので、意味がないと述べました。フランス語/スペイン語/イタリア語で十分かもしれませんが、どの言語でもルールの量が非常に静的であることを考えると、余分な労力をかける価値はありません。あなたが複雑さについて言及する他のポイントは私の正確な心配であり、あなたは私の質問で私が尋ねていたことを素晴らしく理解し、例で素晴らしい答えを与えたと思うので、+ 1!
クリスサイレフィス

5

Dan Pichelmanの答えに100%同意しますが、1つ追加したいことがあります。ここで自問すべき質問は、「誰が単語リストを維持/拡張/修正するのか?」です。特定の言語(特定の開発者、私はあなたと思う)のルールも常に管理している人である場合、これが物事をより複雑にする場合、外部設定ファイルを使用しても意味がありません-あなたは何の恩恵も受けませんこの。この観点から、それはあなたがしても、このような単語リストをハードコーディングするメイクセンスを行います持っている限り、新しいバージョンの一環として、新たなリストを提供するのに十分であるよう、随時それらを変更します。

(一方で、他の誰かが将来リストを維持できる必要がある場合、またはアプリケーションの新しいバージョンをデプロイせずに単語リストを変更する必要がある場合は、別のファイルを使用します。)


これは良い点です-しかし、少なくとも今後数年間は、私が実際にコードを保守しているのは私だけである可能性が非常に高いです。これについての良い点は、文字列がハードコードされていても、すぐにいつでも変更されない非常に小さな文字列/ルールのセットであることです(自然言語なので、あまり進化していません-年)。そうは言っても、活用規則、動詞の終了文字列などは、おそらく私たちの生涯を通じて同じになるでしょう:)
クリス・シレフィス

1
@ChrisCirefice」:まさに私の要点。
Doc Brown

2

ここではハードコーディングは問題ないように見えますが、構成ファイルを動的にロードするよりも優れていますが、データ(動詞の辞書)をアルゴリズムから厳密に分離することをお勧めします。ビルドプロセスでアプリケーションに直接コンパイルできます。

これにより、リストを維持することで多くの煩わしさがなくなります。VCSでは、コミットによってアルゴリズムが変更されたかどうか、または結合のバグを修正したかどうかを簡単に識別できます。また、あなたが考慮しなかった場合のために、将来リストを追加する必要があるかもしれません。特に、カウントした32の不規則な動詞の数は正確ではないようです。これらは一般的に使用されているものをカバーしているように見えますが、133個または350個の参照さえ見つけました。


Bergi、データをアルゴリズムから分離する計画を立てました。定義-あなたはフランス語irregularsについて注意何不規則が最高の状態で誤解されています。不規則と言うとき、私が意味するのは、「計算」できない、または不定形だけでは活用できない動詞です。不規則動詞は特定のパターンをまったく持たないため、それらの活用を明示的にリストする必要があります(たとえば、French.Verb.Conjugation.Irregular`の下)。技術的には、-ir動詞は「不規則」ですが、実際には固定の活用パターンがあります:)
クリスクレフィス

0

重要な部分は関心の分離です。それを達成する方法はあまり重要ではありません。すなわち、Javaは大丈夫です。

ルールの表現方法とは関係なく、ルールを変更する言語を追加する必要がありますか?編集する必要があるコードとファイルの数は?

理想的には、「english.xml」ファイルまたは新しい「EnglishRules implements ILanguageRules」オブジェクトのいずれかを追加することにより、新しい言語を追加できるようにする必要があります。テキストファイル(JSON / XML)は、ビルドライフサイクル外で変更したいが、複雑な文法、解析を必要とし、デバッグが困難な場合に利点があります。コードファイル(Java)を使用すると、複雑なルールをより簡単に表現できますが、再構築が必要です。

どちらの場合でも必要な、きれいな言語に依存しないインターフェースの背後にある単純なJava APIから始めます。必要に応じて、いつでもXMLファイルに裏付けられたそのインターフェイスの実装をいつでも追加できますが、その問題にすぐに(またはこれまでに)取り組む必要はないと思います。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.