2011-08-02 11 views
1

私は主にベストプラクティスをここで探しています。私は、基本的に一連のルール、いくつかのデータ、およびマネージャが、データがルールに従っていることを確認するシステムを持っています。ものすごく単純。私はルールの保存と読み込みを処理する最良の方法を理解しようとしています。最初の試みとして、すべてのルールが継承するIRuleというインターフェースがあります。クラスをXML経由で保存して読み込めるようにする必要がありますか?

interface IRule 
{ 
    /* all rules inherit this */ 
    string RuleName {get;} 
} 
interface IRuleTypeA : IRule 
{ 
    /* Type A Rules */ 
    double[] Data; 
} 

interface IRuleTypeB : IRule 
{ 
    /* Type B Rules */ 
    double[,] Data; 
} 

public static class IRuleExtensions 
{ 
    XElement AsXml(this IRuleTypeA ruleA) 
    { 
    //format my data my way and return an XElement representation 
    return new XElement(...); 
    } 
    XElement AsXml(this IRuleTypeB ruleB) 
    { 
    //format my different data in a different way and return an XElement 
    return new XElement(...); 
    } 
    XElement AsXml(this IRule rule) 
    { 
    object definition = null; 
    if(rule is IRuleTypeA) 
     definition = (rule as IRuleTypeA).AsXml(); 
    else if(rule is IRuleTypeB) 
     definition = (rule as IRuleTypeB).AsXml(); 
    return new XElement("RuleDefinition", new XAttribute("name", rule.RuleName), 
         definition); 
    } 
} 

ここでは、保存するクラスに保存機能を追加しています。私は各要素を取り、ルールを構築する同様のロードメカニズムを実装しようとしていました。私がそれをする前に、これについてのベストプラクティスがあるかどうかを見たいと思っていました。代わりにルールを取る別のシステムを作成して質問し、それをXMLに保存し、ファクトリタイプのシステムを使用してXmlを使用してオブジェクトを構築し直す必要がありますか?

interface RuleToXmlAdaptor 
{ 
    XElement AsXml(IRule rule); 
    IRule FromXml(XElement element); 
} 
class RuleAToXmlAdaptor : RuleToXmlAdaptor 
{ 
    XElement AsXml(IRule rule) { return AsXml(rule as IRuleTypeA); } 
    XElement AsXml(IRuleTypeA rule); 
} 

は、私はどちらか一方を使用しないときは、本当にわからこれらのメソッドの間で前後に行くかまだ良い解決策があるかどう。

ファイルタイプが連続的に変化する可能性があり、このように単純に互換性を管理できるため、シリアル化を使用したくないです。

答えて

6

クラス自体がどのようにシリアライズできるかについて知っておくべきではないと思います。それは単一責任の原則に違反します。明日の新しいシリアライズフォーマットが出てくる、例えばSoupMLを考えてみてください。オブジェクトの外側の誰かがシリアライゼーションを世話するようにしたら、あなたのシステムをSoupMLでうまく動作させるのは本当に簡単で、既存のルールモデルを変更する必要はありません。

明示的にXMLを使用するユニットのみが、XMLを認識する必要があります。この方法では、システムはフォーマットについては気にしないで、インタフェースについてのみ使用できます。後で、シリアライザ/デシリアライザを使用するかどうかを指示されます(Inversion of Control)。このようにすれば、オープンクローズの原則もサポートされます。変更のためにオープンなものを用意する必要はありませんが、拡張のためにオープンされます。

+1

+1、すべての引数が正しいため、複数のシリアル化フォーマットを使用することもできます。さらに、あなたのクラスはもっと簡単で理解しやすくなります。 – neodelphi

+0

よく考えた答えをありがとう。あなたは、アダプタのアプローチや、Save(ISave saver){saver.Save(this); }メソッドを私のルールに適用しますか? – MPavlak

0

私は、あなたのクラスオブジェクトとxmlファイルを簡単にシリアル化し、必要に応じて再度デシリアライズできるようにするクラスとプロパティで使用できるxml属性を調べる必要があると思います。

+0

xml属性を使用してすべてを管理でき、xmlファイルでどのように見えるかを管理できます。 –

0

私はあなたの手を結んでいるので、このようにはしませんが、短期的にはより便利かもしれません。 XElementの代わりに、インターフェイスにDictionary<string,object>が表示されないようにしてください。次に、キーと値のペアを持つことができます(よく知られている値のタイプ、たとえばStringDictionary<string,object>など)。このようにすれば、単体テストがより簡単になり、そうすればより効率的なフォーマットを使用することができます。

interface RuleSerializer 
{ 
    Dictionary<string,object> AsDictionary(IRule rule); 
    IRule FromDictionary(Dictionary<string,object> data); 
} 
関連する問題