2008-09-08 18 views
3

だから(kvpsの各リストが表す返さ別のオブジェクト)、何が最良の方法でしょうか?上記で定義されたキー値のペアのリストからオブジェクトを作成しようとすると、どのようなデザインが良いでしょうか?私は、テキストファイルを解析する方法を持っていると<strong>リストを返す</em><strong>リスト</strong><em><strong></em>のキーと値のペアの</strong><em>を</strong>、およびkvpsからオブジェクトを作成する場合

private const string NAME = "name"; 
private const string PREFIX = "prefix"; 

と私は私がしたいの定数のために取得したキーに対してチェック、:

心にポップ第1の方法は非常に簡単です、ちょうどキーワードのリストを保持します。これは私が取り組んでいるプロジェクトのかなり中核的な部分ですので、私はそれをうまくやりたいのです。誰もがもっと頑強な提案をしているのですか(上記の方法について本質的に不安定なものは何もないと言っているわけではありません。

編集:

さらに詳しい情報が必要です。私は暇な時間にちょっとしたゲームをしています。設定ファイルでゲームの世界を構築しています。 4つのクリーチャーがすべて定義され、もう1つはすべてのクリーチャーを定義し、別のクリーチャーはすべてのクリーチャーを定義し、別のクリーチャーはすべてのクリーチャーを定義し、他のすべてのオブジェクトを定義します。最初の3つの設定ファイルでは、ファイルの内容に基づいてオブジェクトを作成します。テキストが重いので、文字列、名前、複数形、接頭辞などがたくさんあります。設定値は次のようになります。

- 
key: value 
key: value 
- 
key: value 
key: value 
- 

「 - 」は新しいセクション/オブジェクトを表します。

答えて

1

列名と一致するインターフェイスを作成し、Reflection.Emit APIを使用して、実行時にフィールド内のデータにアクセスできる型を作成できます。

3

をよくご覧ください。 XMLオンディスクを使用しないように制限されていても、その機能の一部をコピーすることができます。これは、このようになります。あなたのファイルフォーマットのバージョンのいくつかの種類が含まれるようにかかわらず、

public class DataObject { 
    [Column("name")] 
    public string Name { get; set; } 

    [Column("prefix")] 
    public string Prefix { get; set; } 
} 

は注意してください、またはあなたは、次のフォーマット変更を来る地獄の台所になります。

2

何が必要ですか?あなたがそれを記述する方法として、あなたは何らかの種類の(キーワイズの)制限付き地図として使用します。

[java-inspired pseudo-code:]
class RestrictedKVDataStore { 
    const ALLOWED_KEYS = new Collection('name', 'prefix'); 
    Map data = new Map(); 

    void put(String key, Object value) { 
     if (ALLOWED_KEYS.contains(key)) 
      data.put(key, value) 
    } 

    Object get(String key) { 
     return data.get(key); 
    } 
} 
0

@デビッド:あなたが相続のいくつかの種類を必要としない場合、私は単純に、このようなオブジェクトにマップのような構造をラップしたい
は、私はすでにパーサを持っている(これらのほとんどは次のようになります手書きで書かれたので、私はXMLに反対した)。しかし、それは私が実際にやっているような素晴らしい方法のように見えます。私はそれをチェックする必要があります。バージョン管理についての優れた点。

@Argelbargel:
これも良いようです。 : ')

3

私は、最良の方法は、キー値のペアのリストを受け取って適切なオブジェクトを返すか、または無効な場合に例外をスローするファクトリを作成することですダミーオブジェクト、または特定の場合には何が良いかなど)。

private class Factory { 

    public static IConfigurationObject Factory(List<string> keyValuePair) { 

     switch (keyValuePair[0]) { 

      case "x": 
       return new x(keyValuePair[1]); 
       break; 
      /* etc. */ 
      default: 
       throw new ArgumentException("Wrong parameter in the file"); 
     } 

    } 

} 

ここで最強の仮定は、すべてのオブジェクトが部分的に(すなわち、それらは同じインターフェイスの例では(IConfigurationObject)を実装したり、同じ継承ツリーに属している)と同じように扱われることができるということです。

もしそうでなければ、それはあなたのプログラムの流れとそれらで何をしているのかによって異なります。それでも、彼らはすべきです:

編集:あなたの説明を考えれば、ファイルタイプごとに1つのファクトリを持つことができます。スイッチは、ファイルタイプごとに許可されたタイプの権威のあるソースになります。反射は可能ですが、これよりも明らかではなく、自己文書化しているので、より危険です。

0

...これは、私が働いているプロジェクトはいえ...

は本当にそれです のかなり中核部分ですか?

これを抽象化し、後でリファクタリングする意図を持つ基本的な実装を提供するのは魅力的です。

次に、重要なことを乗り越えることができます:ゲーム。ただ、思考

< BB/>

0

は実際にそれか?

はい。私はこれを考え出した。私よりも、必要以上に多くの仕事をすることは間違いありません。 : ')

1

はEDIT:これはまだ適用され、

スクラッチが、私はあなたのやっ設定ファイルを読み込み、この中にそれを解析しているものだと思う。この場合

List<List<KeyValuePair<String,String>>> itemConfig = 
    new List<List<KeyValuePair<String,String>>>(); 

、反射ファクトリを使用してオブジェクトをインスタンス化することができます。個々のキー/値のペアを渡す代わりに、ネストされた内部リストを渡します。

OLD POST:ここ

は、リフレクションを使用してこれを行うための賢い少し方法です:

基本的な考え方:

  • は、各オブジェクトクラスに共通の基本クラスを使用します。
  • これらのクラスは、それぞれ独自のアセンブリに配置します。
  • この工場もその工場に入れてください。
  • あなたの設定から読み込んだKeyValuePairを渡し、その代わりにKV.Keyと一致するクラスを見つけてKVでインスタンス化します。値
 
     public class KeyValueToObjectFactory 
     { 
     private Dictionary _kvTypes = new Dictionary(); 

     public KeyValueToObjectFactory() 
     { 
      // Preload the Types into a dictionary so we can look them up later 
      // Obviously, you want to reuse the factory to minimize overhead, so don't 
      // do something stupid like instantiate a new factory in a loop. 

      foreach (Type type in typeof(KeyValueToObjectFactory).Assembly.GetTypes()) 
      { 
       if (type.IsSubclassOf(typeof(KVObjectBase))) 
       { 
        _kvTypes[type.Name.ToLower()] = type; 
       } 
      } 
     } 

     public KVObjectBase CreateObjectFromKV(KeyValuePair kv) 
     { 
      if (kv != null) 
      { 
       string kvName = kv.Key; 

       // If the Type information is in our Dictionary, instantiate a new instance of that class. 
       Type kvType; 
       if (_kvTypes.TryGetValue(kvName, out kvType)) 
       { 
        return (KVObjectBase)Activator.CreateInstance(kvType, kv.Value); 
       } 
       else 
       { 
        throw new ArgumentException("Unrecognized KV Pair"); 
       } 
      } 
      else 
      { 
       return null; 
      } 
     } 
    } 
関連する問題

 関連する問題