2008-09-08 5 views
3

그래서 (kvps의 각 목록을 나타냅니다 다른 객체), 가장 좋은 방법은 무엇입니까?키 값 쌍 목록에서 개체를 만들 때 좋은 디자인이란 무엇입니까? 나는 <strong>목록</em><strong>키 값 쌍</strong>, 그리고</strong><em>이 kvps의 개체가 반환 만들려</em><strong>목록의</strong><em>을 텍스트 파일을 구문 분석하고 반환하는 방법이있는 경우

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

을 나는 위의 정의 내가 원하는 상수, 얻을 키에 대해 확인 :

마음에 팝업 첫 번째 방법은 아주 간단합니다, 그냥 키워드 목록을 유지한다. 이것은 내가 작업하고있는 프로젝트의 핵심 부분이므로 잘하고 싶다; 누구든지 더 강력한 제안을하고 있습니까? (위의 방법에 대해 본질적으로 강건하지 않은 것을 말하지 않고 있습니다 - 나는 단지 주위를 묻고 있습니다)?

편집 :

자세한 내용은 질문이 있습니다. 나는 여가 시간에 작은 게임을하고 있으며 구성 파일로 게임 세계를 구축하고 있습니다. 네 가지가 있습니다. 하나는 모든 생물을 정의하고, 다른 하나는 모든 영역을 정의하고, 다른 하나는 모든 객체를 정의하고, 다른 하나는 다양한 구성 옵션과 다른 곳에 적합하지 않은 객체를 정의합니다. 처음 세 개의 구성 파일을 사용하면 파일의 내용을 기반으로 개체를 만들 것입니다. 텍스트가 굵으므로 많은 문자열, 이름, 복수형, 접두어 등이있을 것입니다. 구성 값은 모두 다음과 같습니다.

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

여기서 '-'행은 새로운 섹션/개체를 나타냅니다.

답변

1

열 이름과 일치하는 인터페이스를 만든 다음 Reflection.Emit API를 사용하여 런타임에 필드의 데이터에 액세스 할 수있는 유형을 만들 수 있습니다.

3

을 자세히 살펴보십시오. XML on-disk를 사용하지 않도록 제한된 경우에도 일부 기능을 복사 할 수 있습니다. 파일의 형식 버전의 어떤 종류를 포함하지만

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

부차적 인 가정을 많이하고, 최선의 방법은 키 값 쌍의 목록을 받고 적절한 객체를 반환하거나 유효하지 않은 경우 예외를 throw하는 팩토리를 만드는 것이라고 생각합니다. 더미 객체 또는 특정 경우에 더 나은 것이 무엇이든지).

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)를 구현하거나 동일한 상속 트리에 속하는) 같은 취급 할 수 있다는 것입니다.

그렇지 않은 경우 프로그램 흐름에 따라 달라지며 무엇을하고 있는지에 따라 다릅니다. 그러나 그럼에도 불구하고, 그들은해야한다 :

편집 : 당신의 설명을 감안할 때, 파일 유형 당 하나의 공장을 가질 수 있습니다. 스위치는 파일 유형 당 허용되는 유형에 대한 신뢰할 수있는 출처가 될 수 있으며 아마도 공통점이 있습니다. 반사는 가능하지만 덜 명확하고 자기보다 더 문서화되기 때문에 위험합니다.

0

...이 내가 생각에서 일하고 있어요 프로젝트의 상당히 핵심 부분 ... 정말

가 무엇입니까?

나중에 리팩토링 할 의도로 추상화하고 기본 구현을 제공하는 것이 유혹적입니다.

그런 다음 중요한 일을 할 수 있습니다. 게임.

그냥 생각

< BB/>

0

그것은 정말?

예; 나는 이것을 생각했다. 필자는 필자보다 더 많은 일을해야한다. : ')

1

이 편집 :이 여전히 적용

스크래치,하지만 난 당신의 행함은 구성 파일을 읽는이로 구문 분석 무슨 생각 :이 경우

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; 
      } 
     } 
    } 
관련 문제