2017-11-14 14 views
3

私は自分のサーバーとの間でデータを送信します。私はダイナミックキャスティングを取り除きたいと思います。何が最良の選択肢ですか?

メッセージを作成し、転送する必要があるタイプ(列挙型)とオブジェクトを設定します。

メッセージは、圧縮されたJSON文字列として送信されます。 私はそれを受け取ったときにメッセージを解析し、オブジェクトをインスタンス化して記入します。私は、転送されたデータをインスタンス化する必要があるとき、私はキーとしてクラスの名前と値としてコンストラクタへのポインタを含むマップを使用します。

これはすべてうまくいきましたが、今はメッセージを消費してそれを行う必要があります(回答を送ったり、DBに書き込むなど)。 これを行う最善の方法は何ですか?今のところ、メッセージの種類を確認し、転送されたオブジェクトのそれぞれを取得します。しかし、私は彼らがどのクラスであるか分からない(明示的ではない)。

すべてを動的にキャストする必要がありますか?私はいつも同じ順序であるという希望でデータを扱うべきですか?または、オブジェクトをマップとして(名前または列挙型をキーとして)保存し、正しくキャストする必要がありますか?

可能であれば、ダイナミックキャスティングを行うべきではないことを知っています。しかし、私はここから始めてスイッチを入れ、正しいオブジェクトを作成してJSONを供給する価値があるのだろうと思います。今のところ、メッセージ全体が問題なく動的に再構築され、私のメッセージマネージャが治療を処理します。それを変更する必要がありますか?

+1

受信したメッセージの内容に基づいて、適切なオブジェクトを作成するために工場パターンを使用しないのはなぜですか? 'dynamic_cast'は必要ありません。 – Peter

+1

私はPeterに同意します。私はおそらく、関連付けられた型のメッセージにenumマッピングを返した "スニッファ"関数を使用し、そのenumをswitch/caseブロックで使用して、std :: unique_ptrを返す適切なファクトリ関数を呼び出します。解析に失敗すると、nullptrでunique_ptrを返すのではなく、例外がスローされます。 – Eljay

+0

@Eljay Factoryファンクションは正しいタイプのポインタを返すか、例外をスローします。 "base_class"オブジェクトのリストはありませんか?私は各工場ファンクションにJSONを必要とするか、後でそれを養うことができます。簡単な解決策のように見えますが、私はおそらくそれをあまりにもダイナミックにしようとしました。 – rXp

答えて

4

私はPeterに同意します。

おそらく、メッセージの関連タイプにJSONをマッピングするenum class JTypeを返した「スニッファ」機能を使用していました。

次に、switch/caseブロックのJType列挙型を使用して、std :: unique_ptrを返す適切なファクトリ関数を呼び出します。

解析に失敗すると、nullptrでunique_ptrを返すのではなく、例外がスローされます。

  • 関連するクラスタイプごとに1つのファクトリがあります。
  • JSONがどのような型を表しているかを判断するスニッファ関数を使用して、列挙型を返します。
  • ハッピーパスはJType e = sniff(message);なり、工場から例外をスローif (e == JType::Foo) std::unique_ptr<Foo_t> foo = FooFactory(message);
  • のみメッセージであるべきもののようなメッセージや工場不一致の例外的な場合に生じます。

base_classオブジェクトのリストはありませんが、enumクラスJTypeはクラスへの1:1マッピングを持ちます。

JSONを状態情報「脱水」と考えると、ファクトリ関数は状態データを新しいオブジェクトに「再水和」します。ファクトリ関数は、クラスの一部としての静的なクラス関数でも、フリースタンドバイ関数でもかまいません。

階層構造は多型であり、これはそのような状況ではありません。

+0

ありがとうございました。清潔でシンプル。私はいつもあまりにも複雑で無駄に行きます。 – rXp

関連する問題