web-dev-qa-db-ja.com

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

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

動詞を活用するアルゴリズムは、実際には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に入れて、使用する必要があるときに逆シリアル化することもできますが、ポイントはありますか?これらの文字列は自然言語の一部であり、変化しますが、速度は遅いです。

私の懸念は、物事を「正しい」方法で行い、一部のデータソースを逆シリアル化することで、問題を複雑にするだけでなく複雑にする必要がないだけでなく、 veはまた、アルゴリズムアプローチの全体的な目標を完全に逆追跡します。データソースを使用するしない! C#では、これらの文字列をXMLに詰め込んでnamespace Verb.Conjugationを作成する代わりに、class Irregular(例:class IrregularVerbDeserializer)の下にクラスを作成して、列挙型などにこれらの文字列を格納できます。

したがって、質問:veryがアプリケーションの存続期間中に変更される可能性が低い文字列をハードコードすることは適切ですか? もちろん、変更できない保証はできません100%ですが、リスクとコストの関係は、目で見て簡単です-ハードコーディングはここでより良いアイデア。

Editproposed duplicate大量の静的文字列を保存する方法を尋ねます、私の質問はですが、私はhard-codeこれらの静的文字列をいつすべきですか?.

39
Chris Cirefice

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

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

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

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

56
Dan Pichelman

あなたは間違ったスコープで推論しています。

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

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

  • 近い将来、100%に近い確実性でアプリを他の言語に拡張しますか?そうであれば、代わりにJSONまたはXMLファイル(単語、単語の一部など)および動的言語(ルール用)にエクスポートする必要がありました。アプリの主要部分を自分で書き直すように強制します。

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

例として、Microsoft Wordのスペルチェッカーを取り上げます。ハードコーディングされていると思いますか?

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

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

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

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

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

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

25

値がプログラムロジックから個別に変更できる場合は、文字列を構成ファイルまたはデータベースに抽出する必要があります。

例えば:

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

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

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

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

プログラムロジックを変更せずに実際の文字列を変更できない場合、文字列はhardcodedになります。

例:

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

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

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


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

15
JacquesB

Dan Pichelmanの回答に100%同意しますが、もう1つ追加してください。ここで自問する必要があるのは、「Wordリストを保守、拡張、修正するのは誰ですか?」です。特定の言語のルールも維持している人(特定の開発者だと思います)である場合、外部設定ファイルを使用しても、これにより状況が複雑になっても意味がありません。メリットはありません。この。この観点から、新しいリストをaの一部として配信するのに十分である限り、haveを変更する場合でも、そのようなWordリストをハードコードすることは理にかなっています。新しいバージョン。

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

5
Doc Brown

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

これにより、リストのメンテナンスに伴う煩雑さが大幅に軽減されます。 VCSで、コミットによってアルゴリズムが変更されたかどうか、または共役のバグを修正したかどうかを簡単に識別できます。また、考慮しなかった場合のために、将来的にリストを追加する必要があるかもしれません。特に、カウントした32の不規則動詞の数は正確ではないようです。それらは一般的に使用されるものをカバーしているようですが、私はそれらの 1 または 5 への参照を見つけました。

2
Bergi

重要な部分は、懸念の分離です。それを達成する方法はあまり重要ではありません。つまり、Javaで結構です。

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

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

単純なJava APIはクリーンな言語にとらわれないインターフェースの背後にあります-どちらの場合も必要になるため、最初に開始します。必要に応じて、後からいつでもXMLファイルに基づくインターフェースの実装をいつでも追加できます、しかし私はその問題にすぐに(またはこれまでに)取り組む必要があるとは思いません。

0
ptyx