2011-01-27 7 views
0

質問:開発者が独自のシリアル化形式を作成するのはどのくらい一般的ですか?具体的には、私はJavaを本質的に変数を区切るためにトークンを持つ巨大な文字列としてオブジェクトを送信しています。オブジェクトの送信/シリアル化のベストプラクティス

My Logic:言語の依存性(Javaの変更されたUTF-8を無視)がほとんどなく、オブジェクトバージョンの問題もないため、これを選択しました。Javaのシリアル化を使用すると、同じバージョンのオブジェクトであるため、古いバージョンで実行されているクライアントはオブジェクトデータのいずれも受信できません。コードはあまりにも醜いではありませんが、それは大丈夫ですが、私の質問は、このインスタンスのベストプラクティスは何ですか?これは個人的なプロジェクトのためのものです。

その他の既知の選択肢:これは、オブジェクトをネットワーク経由で送信するためにオブジェクトをシリアライズしていて、グーグルプロトコルバッファを使用していました。オブジェクトのシリアライズはどのように標準化されていますか?私は本質的にそれを行う3つの方法に出くわしました。 (私はここで私がそれをしたことからJavaについて話します)1)言語の(Javaの)ネイティブシリアライズクラスを使用する2)文字列とトークンを使用してオブジェクトを直列化する独自の方法を使用する3)プロトコルバッファを使用するか 1)速度/効率/サイズ 2)言語の独立性 3)バージョンの受け入れを:私はあなたが、本質的にシリアライズ時に達成するための3つの主な目標を持って集まってきたものから、いくつかの他の既知のフォーマット(JSON、XMLなど)

(古いバージョンのコードでは新しいバージョンの一部を引き続き受け入れることができます)

ほとんどの大規模ソフトウェアプロジェクトではプロトコルバッファを使用していますか?あなたのクライアントがリソースがはるかに少ないモバイルデバイスであれば変化しますか?

+1

グラフを処理しますか? – bestsss

+0

いいえ、オブジェクトは一般的にコンタクト情報(名前、#、アドレス)のようにかなり小さいです。私は文字列を使って自分自身の "シリアライズ"形式を書いています。私は名前と電話番号のようなオブジェクトの一部だけを送信/要求できるので、200〜300件の連絡先を要求するとかなり速くなります。 –

+1

目標を忘れないでください:4)データを壊さないでください。明らかに分かりますが、区切り文字でテキストエンコーディングを作成するには、扱うべき古典的な問題があります(例えば、データに埋め込まれた区切り文字、その他の奇妙な文字など)。 – jtahlborn

答えて

5

標準形式(JSON、XML、またはプロトバッファ)を使用すると、統合ポイント経由でアプリを拡張する機会はますます増えます。しかし、もしそれが内部だけであれば、簡単なことをやってください。個人的には、指定されたオブジェクトのシリアル化された形式を表す専用の永続プロキシクラスを作成します。次に、writeReplaceとreadResolveを使用して、どのようなメソッドを使用してもオブジェクトをシリアル化します(オーバー・ザ・ワイヤ・ライブ転送のJavaシリアル化、長期間の永続化のためのXML)。クラスが進化するにつれ、永続的なプロキシの完全な新しい実装を作成したり、プロキシにバージョン管理を追加したりすることができます。私は、BlochがこのパターンをEffective Javaで議論していると信じています。

純粋なスクラッチワイヤープロトコルを考え出すのは、パフォーマンスがアプリにとってどれほど重要かに大きく依存しています。ほとんどの場合と同様に、標準ライブラリ/プロトコルを活用すればするほど、新しいコードを素早く得ることができます。私はシリアライズに関連する膨大なコードを見ていますが、私は一般的にそれをコードの匂いとみなし、正当化されているかどうかに非常に注意を払います。ちょうど私の$ 0.02。

そして、PS - 誰かがグラフについて質問を投稿しました...これは、私が意図的に標準的なシリアライズを避けた1つの領域です。複雑なグラフをシリアライズするJavaの能力はあまり良くありません。グラフが遠隔で複雑であっても、スタックオーバーフローの問題(ハッハッハー)に巻き込まれます。このような場合、永続プロキシは非常に重要です。すぐに私の心に春

+0

@ケヴィン・デイ - 問題は複雑なものではなく、深い*グラフになります。理論的には、これは一般的なケースではシリアル化が遅くなる可能性がありますが(Sun/Oracleによる)解決可能です。 (再帰的なツリーウォークを、待ち行列または訪問するノードのスタックを使用するものに置き換えてください。) –

+0

@Stephen - 同意します。この分野の教訓として、私はグラフのシリアライズに5レベル以下のグラフで失敗してしまった(明らかに、シリアライゼーションアルゴリズムがグラフを正確に間違った方法で歩くことにした)。深度が問題であることは間違いありませんが、シリアライゼーションアルゴリズムの深さは、グラフのオブジェクト階層の目視検査で期待される深さと同じでないことがよくあります。 –

+0

@ Kevin Day - 実際、ノードへの複数のパスを持つグラフでは、ツリーの深さ/高さを測定する方法が複数あります。 –

2

いくつかのこと:

  • は、すべてのメッセージや接続ネゴシエーションにどちらのバージョン番号を含めます。それは巨大な頭痛からあなたを救うでしょう。受信者がサポートするバージョンを送信者に知らせることが好ましい。

  • 自然にバイナリ(画像、サウンド)のデータを送信しない限り、読み取り可能なプレーンテキスト(UTF-8)形式を使用します。多くのトラブルシューティングに役立ちます。私はJSONに固執しますが、最適ではないかもしれません。 XMLには高いオーバーヘッドがあります。

  • あなたのメッセージは十分な長さであるならば、あなたはGZIP(GZIPOutputStream)のように、いくつかのよく知られているアルゴリズムでそれらを圧縮しようとすることができます。

これらの手順は、表示されるように、サーバーと可能なクライアント間の形式のオープン性と緩やかな結合を促進します。あなたのクライアントが将来どのような技術を使用しなければならないかは誰も知りません。 HTML5 + JSクライアント?サーバの場合も同様です。

+0

JSONはすべての取引のジャックです。 y、それは好きではない。 XMLは冗長ですが、(DTD/XSDを介して)検証することができ、実際には非常に明確なルールを持つ公開APIプロトコルとして立つことができます。メッセージ/ serializarionごとにgzipを使用すると、優れたパフォーマンス(および圧縮レベル)が得られない可能性があります。メッセージベースで圧縮を実装するには、Z_SYNC_FLUSHでフラッシュする必要があります(いくつかの超奇妙な理由はjava.util.zipでサポートされていませんが、jzlibはサポートしています)。 – bestsss

5

質問:開発者が独自のシリアル化形式を作成するのはどのくらい一般的ですか?

ゼロから作成すると仮定すると、答えは「かなり珍しい」となります。

また、私は一般的にこれを行うための「ベストプラクティス」ではないと思います。ほとんどの場合、既存の一般的に使用される選択肢(Javaのシリアライズ、JSON、XMLなど)の1つが良い解決策を提供します。

IMOの場合、明確な要件がある場合や、既存の代替語であるがそうでないという明確な証拠がある場合にのみ、独自のフォーマットを検討し(対応するシリアライゼーション/デシリアライズコードを実装する)仕事。 "XYZが遅い"というフォークの知恵は、十分な証拠ではありません。構造化データXMLの

0

、JSONは最良の選択である可能性が高いです。しかし、単純なフラットレコードの場合は、CSVを検討することをお勧めします。実装するのが簡単で簡単です。レコード数が非常に多い場合は、管理しやすくなります。例えばスプレッドシートにロードする

関連する問題