4

クラスのシリアライゼーション コードをどこに配置するかについて、私はしばしば困惑し、この件に関する他の人の考えを知りたいと思っていました。

Bog の標準シリアライズは簡単です。問題のクラスを装飾するだけです。

私の質問は、装飾されたプロパティを盲目的にシリアル化するのではなく、さまざまなプロトコルまたはさまざまな形式にシリアル化され、プロセスにいくつかの考え/最適化が必要なクラスに関するものです。

すべてのコードを独自のクラスの 1 つの形式に関連付ける方がクリーンだと感じることがよくあります。また、新しいクラスを追加するだけでフォーマットを追加することもできます。例えば。

class MyClass
{
}

Class JSONWriter
{
    public void Save(MyClass o);
    public MyClass Load();
}

Class BinaryWriter
{
    public void Save(MyClass o);
    public MyClass Load();
}

Class DataBaseSerialiser 
{
    public void Save(MyClass o);
    public MyClass Load();
}

//etc

ただし、これは多くの場合、他のクラスが効果的にシリアル化するために、MyClass がより多くの内部を外部に公開する必要があることを意味します。これは間違っていると感じ、カプセル化に反します。それを回避する方法があります。たとえば、C++ ではシリアライザーをフレンドにすることができます。また、C# では特定のメンバーを明示的なインターフェイスとして公開することもできますが、それでも気分は良くありません。

もちろん、他のオプションは、 MyClass にさまざまな形式との間でシリアル化する方法を知ってもらうことです。

class MyClass
{
    public void LoadFromJSON(Stream stream);
    public void LoadFromBinary(Stream stream);

    public void SaveToJSON(Stream stream);
    public void SaveToBinary(Stream stream);
    //etc
}

これはよりカプセル化されて正しいように感じますが、書式設定をオブジェクトに結合します。MyClass が知らないコンテキストのために、外部クラスがより効率的にシリアル化する方法を知っている場合はどうなるでしょうか? (おそらく、多数の MyClass オブジェクトが同じ内部オブジェクトを参照しているため、外部シリアライザーはそれを一度だけシリアライズすることで最適化できます)。さらに、新しい形式が必要な場合は、新しいクラスを作成するだけでなく、すべてのオブジェクトにサポートを追加する必要があります。

何かご意見は?個人的には、プロジェクトの正確なニーズに応じて両方の方法を使用しましたが、特定の方法に賛成または反対する強い理由がある人がいるかどうか疑問に思いましたか?

4

2 に答える 2

2

シリアライゼーションが使用されるコンテキストと、それを使用するシステムの制限に本当に依存していると思います。たとえば、Silverlight リフレクションの制限により、シリアライザーが機能するためには、一部のクラス プロパティを公開する必要があります。もう 1 つは、WCF シリアライザーでは、可能なランタイム タイプをアドホックに知る必要があります。

ご指摘とは別に、シリアル化ロジックをクラスに入れることはSRPに違反します。クラスが自分自身を別の形式に「変換」する方法を知る必要があるのはなぜですか?

さまざまな状況でさまざまな解決策が必要ですが、私はほとんどの場合、分離されたシリアライザー クラスが機能しているのを見てきました。確かに、クラス内部の一部を公開する必要がありましたが、場合によっては、とにかくそれを行う必要があります。

于 2011-11-11T10:53:55.327 に答える
2

最も柔軟なパターンは、オブジェクトを軽量に保ち、特定の種類のシリアライゼーションに別のクラスを使用することです。

別の 3 種類のデータ シリアル化を追加する必要がある場合を想像してみてください。クラスは、気にしないコードですぐに肥大化します。「オブジェクトは、それらがどのように消費されるかを知っているべきではありません」

于 2011-11-11T10:47:49.180 に答える