Skip to content

Instantly share code, notes, and snippets.

@frsyuki
Created September 25, 2010 07:11
Show Gist options
  • Save frsyuki/596574 to your computer and use it in GitHub Desktop.
Save frsyuki/596574 to your computer and use it in GitHub Desktop.
// MessagePackerインタフェース
public interface MessagePacker {
public void pack(Packer into, Object target) throws IOException;
}
// MessageConverterインタフェース
public interface MessageConverter {
public void convert(Object into, MessagePackObject from) throws TypeException;
}
// カスタムシリアライザを登録しておく
public class CustomPacker {
static void register(Class target, MessagePacker packer);
static boolean isRegistered(Class target);
static MessagePacker getRegistered(Class target);
}
// カスタム型変換を登録しておく
public class CustomConverter {
static void register(Class target, MessageConverter converter);
static boolean isRegistered(Class target);
static MessageConverter getRegistered(Class target);
}
// @MessagePackMessageアノテーション
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MessagePackMessage { }
// @MessagePackDelegate("memberName")アノテーション
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MessagePackDelegate { }
// @MessagePackOrdinalEnumアノテーション
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MessagePackOrdinalEnum { }
// リフレクション+コード生成でシリアライズするMessagePackerを作成するクラス
public abstract MessagePackMessagePacker implements MessagePacker {
public static MessagePackMessagePacker createPacker(Class target);
}
// シリアライズをメンバメソッドに委譲するMessagePackerを作成するクラス
public abstract DelegatePacker implements MessagePacker {
public static DelegatePacker createPacker(Class target);
}
// ordinal()でシリアライズするMessagePackerを作成するクラス
public abstract OrdinalEnumPacker implements MessagePacker {
public static OrdinalEnumPacker createPacker(Class target);
}
// MessagePackableインタフェース
public interface MessagePackable {
public void messagePack(Packer into) throws IOException;
}
// MessageConvertableインタフェース
public interface MessageConvertable {
public void messageConvert(MessagePackObject from) throws TypeException;;
}
// Packerクラス
public class Packer {
public void pack(Object obj) {
if(/*プリミティブ型なら*/) {
// プリミティブ型
// ほげほげする(実装済み)
} else if(obj instanceof MessagePackable) {
// MessagePackableなオブジェクト
// ユーザーが自前でカスタムシリアライザを実装したクラスや、newEnhancedIntance()で作ったオブジェクトは、ここで引っかかる
// キャストしてシリアライズ
((MessagePackable)obj).messagePack(this);
} else if(CustomPacker.isRegistered(obj.getClass())) {
// カスタムシリアライザが登録されているクラス
CustomPacker.getRegistered(obj.getClass()).pack(this, obj);
} else if(/*@MessagePackMessageアノテーションが付いているなら*/) {
// MessagePackMessagePackerを作成
MessagePacker packer = MessagePackMessagePacker.createPacker(obj.getClass());
CustomPacker.register(obj.getClass(), packer); // 作成したpackerはキャッシュ -> 以後は「カスタムシリアライザが登録されているクラス」に引っかかる
packer.pack(this, obj);
} else if(/*@MessagePackDelegateアノテーションが付いているなら*/) {
// DelegatePackerを作成
MessagePacker packer = DelegatePacker.createPacker(obj.getClass());
CustomPacker.register(obj.getClass(), packer); // 作成したpackerはキャッシュ -> 以後は「カスタムシリアライザが登録されているクラス」に引っかかる
packer.pack(this, obj);
} else if(/*@MessagePackOrdinalEnumアノテーションが付いているなら*/) {
// OrdinalEnumPackerを作成
MessagePacker packer = OrdinalEnumPacker.createPacker(obj.getClass());
CustomPacker.register(obj.getClass(), packer); // 作成したpackerはキャッシュ -> 以後は「カスタムシリアライザが登録されているクラス」に引っかかる
packer.pack(this, obj);
} else {
// エラー
}
}
}
//
// 使い方:
//
//
// ・自分で定義したクラスをシリアライズしたい
// 1. @MessagePackMessageアノテーションを付ける
//
// ・自分で定義したクラスをシリアライズしたい(独自のシリアライズ方法で)
// 1. MessagePackableインタフェースをimplementsする
//
// ・自分で定義したクラスをシリアライズしたい(メンバ変数1つを直接シリアライズするように委譲)
// 1. @MessagePackaDelegate("memberName")アノテーションを付ける
//
//
// ・他人が定義したクラスをシリアライズしたい
// 1. CustomPacker.register(ThatClass.class, MessagePackMessagePacker.createPacker(ThatClass.class)); を実行する
//
// ・他人が定義したクラスをシリアライズしたい(独自のシリアライズ方法で)
// 1. MessagePackerインタフェースをimplementsしたクラスを作る
// 2. CustomPacker.register(ThatClass.class, new YourPackerClass()); を実行する
//
// ・他人が定義したクラスをシリアライズしたい(メンバ変数1つを直接シリアライズするように委譲)
// 2. CustomPacker.register(ThatClass.class, DelegatePacker.createPacker(ThatClass.class)); を実行する
//
//
// ・自分で定義したEnumをシリアライズしたい
// 1. enumの定義で、値を表現するメンバ変数を持たせる
// 2. @MessagePackDelegate("memberName")アノテーションを付ける
//
// ・自分で定義したEnumをシリアライズしたい(宣言する順番が変えたときに互換性が無くなってもいいよ)
// 1. @MessagePackOrdinalEnumアノテーションを付ける
//
//
// ・他人が定義したEnumをシリアライズしたい
// 1. enumの定義で、値を表現するメンバ変数を持っていることを確認する
// 2. CustomPacker.register(ThatEnum.class, DelegatePacker.createPacker(ThatEnum.class, "memberName")); を実行する
//
// ・他人が定義したEnumをシリアライズしたい(宣言する順番が変えたときに互換性が無くなってもいいよ)
// 1. CustomPacker.register(ThatEnum.class, OrdinalEnumPacker.createPacker(ThatEnum.class)); を実行する
//
// 所感:全般に命名が良く無いので要検討。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment