5

小さなペイント アプリケーションで元に戻す/やり直しを実装したいと考えています。コマンド パターンは用途に適しているようですが、最適な実装方法がわかりません。

パターンを理解しているので、各コマンドに含める必要があります。

  1. やり直しのためのペイント操作の詳細 (例: 線 -> 始点と終点、自由形式の線 -> GeneralPath)
  2. 元に戻す変更前のコンポーネントの状態。この場合、それはコマンドの影響を受ける領域の小さなスナップショット イメージになります。

それに基づく私の理解は、各コマンドは「アトミック」または自己完結型である必要があり、その操作を元に戻す/やり直すために必要なすべての情報を備えているということです。

残念ながら、最初に予想したよりも多くの情報を保存する必要があります。線については、 なども考慮する必要がありColor、最初に線を描画するために使用されますStrokeRenderingHintsこれにより、私の「単純な小さなコマンド」が何かに変わります..メモリが大きくなり、ボイラープレートコードが増えます(それぞれがシリアル化可能なBeanになります1)。

メモリ節約の理由から (ほとんどの場合)、コマンドの仕様を「チート」したかったのです。おそらく、100 回の更新ごとに描画領域全体のバックアップを取りますが、それ以外の場合は、変更されたイメージの一部を保存せず、新しいペイント操作ごとに最後の (最大で) 100 個のコマンドを単純に再構築します。しかし、Graphics各部分をペイントする前にオブジェクトの状態が正しいことを確認するには問題があるようです。この部分には行が必要になる場合がありますが、RenderingHintsは 4 コマンド前にColor変更され、 は 98 コマンド前に変更されましたがStroke、 は最後のコマンドと同じままです。 227 コマンド。

よりメモリ効率の高いコマンドを追求すると、「アトミック」であるという点でパターンが窓の外に投げ出されるようです。その結果、レンダリングに影響を与える可能性のある最初のコマンドを特定することが困難になります。

するべきか:

  • 新しいパターンをお探しですか?
  • パターンを微調整して、私の固有のニーズを実装しようとしていますか?
  • これらすべてを時期尚早の最適化としてゴミ箱に捨て、定義されたコマンド パターンに固執する最も単純な (そして最もメモリを消費する) 方法でコーディングしますか?

アップデート

  1. 「それぞれがシリアライズ可能な Bean になります」 2 回目の考えでは、いいえ。Graphics2Da (描画時に使用される多くのパラメーターをきちんとカプセル化したもの) がシリアライズ可能でないことを確認するために、ドーム チェックを行いました。さらに、 aBasicStroke シリアライズ可能ですが、ストロークの太さは保存されません。多くの属性のシリアル化可能なバージョンを作成できましたが、コードがさらに多くなるように思われるため、その仕様を放棄します。同じように。BufferedImage実行時に a への参照のみを保存しようとします。
4

2 に答える 2

3

私はコマンドパターンに固執し、最初に素朴な解決策(=最もメモリを消費する)を試します。一部のグラフィカル操作では、コマンド オブジェクトにイメージ全体のコピーを保持する必要さえある場合があります (たとえば、フィルターを考えてください)。これは、プロの画像編集アプリケーションでもよくある問題です。多くの場合、記憶されている最後のコマンドのメモリまたはステップ制限があります。また、メモリの消費量が非常に多い場合は、コマンド履歴の最も古いエントリをファイル システムにスワップすることを検討してください。変更が取り消されるまで、ユーザーは少し待っても構わないと思います。

于 2012-10-08T10:52:42.357 に答える
1

たぶん、コマンドでイメージ全体のコピーを保存するのではなく、コマンドによって変化している領域のコピーだけを保存する方がよいでしょう。もちろん、これは万能薬ではありません

于 2012-10-08T11:32:37.313 に答える