1


0

私はネットワークアプリを書いていて、それはたくさんの異なる種類のバイナリパケットを送受信します、そして私は私のアプリに新しい種類のパケットを追加することをできるだけ簡単にしようとしています。

今のところ、私は `Packet`クラスを作りました、そして私はそれぞれの異なる種類のパケットのためにそれのサブクラスを作ります。 しかし、見かけほどきれいではありません。私はこのようなコードになってしまいました:

静的クラスItemDescは、Packet {public final int item_id;}を拡張します。 public final int desc_type; public final Stringファイル名。 public final String buf;

public ItemDesc(タイプt、int型item_id、int型desc_type、文字列ファイル名、文字列buf){super(t); //パケットヘッダで使用するタイプを設定しますthis.item_id = item_id; this.desc_type = desc_type; this.filename = filename; this.buf = buf; }

public ItemDesc(InputStream i)はIOException {super(i);}をスローします。 //パケットヘッダを読み込み、this.inputを設定しますitem_id = input.readInt(); desc_type = input.readByte(); filename = input.readStringWithLength(); buf = input.readStringWithLength(); }

public void writeTo(OutputStream o)IOExceptionがスローされます。{MyOutputStream dataOutput = new MyOutputStream();} dataOutput.writeInt(item_id); dataOutput.writeByte(desc_type); dataOutput.writeStringWithLength(filename); dataOutput.writeStringWithLength(buf); super.write(dataOutput.toByteArray()、o); }}

このアプローチに私を悩ませているのはコードの繰り返しです - 私は4回パケット構造を繰り返します。 これを避けてよかったと思いますが、それを単純化するための合理的な方法はわかりません。

私がPythonで書いていたならば、私はすべての可能なフィールドタイプの辞書を作成し、そしてこのように新しいパケットタイプを定義するでしょう:

ItemDesc = [( 'item_id'、 'int')、( 'desc_type'、 'byte')、...]

私はどんな機能的な言語でも同様のことができると思います。 しかし、このアプローチをJavaに取り入れる方法が見当たりません。

(たぶん私はあまりにもペダペすぎ、または関数型プログラミングとコードを書くコードを書くのに慣れてきたので、繰り返しを避けることができました:)

何か提案がありましたら宜しくお願いします。

3 Answer


1


あなたの現在のコードが良い解決策であることに@silkyに同意します。 IMOでは、(重複してはいませんが)少し反復するコードを作成しても問題ありません。

もっとPython風のソリューションを望んでいるのなら、

  1. ItemDescのメンバ属性をある種の順序を保存するマップ構造に置き換え、マップを反復処理する一般的な `writeTo`メソッドを使ってシリアル化を行います。 また、属性ごとにゲッターを追加し、既存のフィールドのすべての用途を置き換える必要があります。

  2. メンバー属性をPropertiesオブジェクトで置き換え、バイナリ書き込みの代わりにPropertiesシリアライゼーションを使用してください。

  3. Javaリフレクションを使ってメンバーの属性とその型にアクセスし、それらを直列化する一般的な `writeTo`メソッドを書きます。

しかし、3つの場合すべてにおいて、コードは現在の「醜い」コードより遅く、より複雑になり、そして潜在的により脆弱になります。 私はしません。


0


私には大丈夫そうです。 パケットの「一般的な」部分を継承チェーンまで抽象化したいだけなので、それらを読む必要はありませんが、フォーマットを変更するのは理にかなっています。コンストラクタからrawを読み込み、ストリームから読み込み、書き込みを行う場合。 私はそれについて何も問題ないと思います。


0


私はあなたがJavaでこれを行うことができるかどうかわからないが、多分あなたはctorsの1つを再利用することができます:

public ItemDesc(InputStream i)はIOException {super(i);}をスローします。 //パケットヘッダを読み込みthis.inputを設定する

this(input.readInt()、input.readByte()、input.readStringWithLength()、input.readStringWithLength()); }

構文がどのようなものであっても、「これ」はこのクラスコントローラへの呼び出しを意味します。