アプリケーションのXML/JSON/バイナリシリアル化の違いをカプセル化するように設計されたシリアル化インターフェイスがあります。これは次のようになります。
interface Serialization {
bool isObject();
int opApply(int delegate(string member, Serialization value) del); //iterate object
...
int toInt(); //this part is ugly, but without template member overloading, I
long toLong(); //figure out any way to apply generics here, so all basic types
... //have a toType primitive
string toString();
}
class JSONSerialization : Serialization {
private JSON json;
...
long toLong() {
enforce(json.type == JSON_TYPE.NUMBER, SerializationException.IncorrectType);
return cast(long)json.toNumber();
}
...
}
したがって、次に設定するのは、タイプデシリアライザーを登録して呼び出すためのテンプレートのセットです。
...
registerTypeDeserializer!Vec3(delegate Vec3(Serialization s) {
return Vec3(s[0].toFloat, s[1].toFloat, s[2].toFloat);
});
...
auto v = parseJSON("some file").deserialize!Vec3;
...
registerTypeDeserializer!Light(delegate Light(Serialization s) {
return new Light(s["intensity"].toFloat, s["position"].deserialize!Vec3);
});
これは構造体と単純なクラスでうまく機能し、新しいパラメーター識別子のタプルとパラメーターのデフォルト値のタプルを使用すると、自動デシリアライザー生成を追加することもできます。ただし、基本型とユーザー定義型の不一致はあまり好きではありません。さらに重要なことに、複雑な型は参照を取得するためにグローバル状態に依存する必要があります。
static MaterialLibrary materials;
registerTypeDeserializer!Model(delegate Model(Serialization s) {
return new Model(materials.borrow(s["material"].toString), ...);
});
それは本当にバラバラになるところです。(レジスタデシリアライザー関数の急増なしに)他のパラメーターをデシリアライザーに渡すことができないため、醜いグローバルファクトリーを回避するのに苦労しています。デシリアライズテンプレートを削除し、ユーザー定義型ごとにデシリアライズ関数(複数のパラメーターを受け入れることができる)を要求することを考えましたが、POD構造体などでは多くの作業のようです。
では、どうすればこの設計を簡素化し、ボイラープレートデシリアライザーを大量に回避しながら、オブジェクトファクトリをグローバルに割り当てるのではなく、適切に注入できるようにすることができますか?