小さなペイント アプリケーションで元に戻す/やり直しを実装したいと考えています。コマンド パターンは用途に適しているようですが、最適な実装方法がわかりません。
パターンを理解しているので、各コマンドに含める必要があります。
- やり直しのためのペイント操作の詳細 (例: 線 -> 始点と終点、自由形式の線 ->
GeneralPath
) - 元に戻す変更前のコンポーネントの状態。この場合、それはコマンドの影響を受ける領域の小さなスナップショット イメージになります。
それに基づく私の理解は、各コマンドは「アトミック」または自己完結型である必要があり、その操作を元に戻す/やり直すために必要なすべての情報を備えているということです。
残念ながら、最初に予想したよりも多くの情報を保存する必要があります。線については、 なども考慮する必要がありColor
、最初に線を描画するために使用されますStroke
。RenderingHints
これにより、私の「単純な小さなコマンド」が何かに変わります..メモリが大きくなり、ボイラープレートコードが増えます(それぞれがシリアル化可能なBeanになります1)。
メモリ節約の理由から (ほとんどの場合)、コマンドの仕様を「チート」したかったのです。おそらく、100 回の更新ごとに描画領域全体のバックアップを取りますが、それ以外の場合は、変更されたイメージの一部を保存せず、新しいペイント操作ごとに最後の (最大で) 100 個のコマンドを単純に再構築します。しかし、Graphics
各部分をペイントする前にオブジェクトの状態が正しいことを確認するには問題があるようです。この部分には行が必要になる場合がありますが、RenderingHints
は 4 コマンド前にColor
変更され、 は 98 コマンド前に変更されましたがStroke
、 は最後のコマンドと同じままです。 227 コマンド。
よりメモリ効率の高いコマンドを追求すると、「アトミック」であるという点でパターンが窓の外に投げ出されるようです。その結果、レンダリングに影響を与える可能性のある最初のコマンドを特定することが困難になります。
するべきか:
- 新しいパターンをお探しですか?
- パターンを微調整して、私の固有のニーズを実装しようとしていますか?
- これらすべてを時期尚早の最適化としてゴミ箱に捨て、定義されたコマンド パターンに固執する最も単純な (そして最もメモリを消費する) 方法でコーディングしますか?
アップデート
- 「それぞれがシリアライズ可能な Bean になります」 2 回目の考えでは、いいえ。
Graphics2D
a (描画時に使用される多くのパラメーターをきちんとカプセル化したもの) がシリアライズ可能でないことを確認するために、ドーム チェックを行いました。さらに、 aBasicStroke
はシリアライズ可能ですが、ストロークの太さは保存されません。多くの属性のシリアル化可能なバージョンを作成できましたが、コードがさらに多くなるように思われるため、その仕様を放棄します。同じように。BufferedImage
実行時に a への参照のみを保存しようとします。