2

元に戻す/やり直しをサポートする必要があるプログラムを C# で作成しています。この目的のために、私は Command パターンに落ち着きました。tldr、ドキュメントの状態を操作するすべての操作は、ドキュメントの以前の状態と必要な変更を認識し、それ自体を実行/元に戻すことができる Command オブジェクトによって実行する必要があります。

単純な操作では問題なく機能しますが、ドキュメントの複数の部分に一度に影響を与える操作があります。同様に、Command オブジェクトは、元に戻す必要がある場合に備えて保持する必要があるすべての古い状態を認識できるほど十分にスマートでなければなりません。

問題は、パブリック インターフェイスを使用してすべての状態を公開すると、誰かがインターフェイスを直接呼び出そうとした場合に誤用される可能性があり、状態の破損につながる可能性があることです。私の直感では、これを行うための最もオブジェクト指向の方法は、特殊化された Command クラスを公開することです。ドキュメントの状態を直接操作できるようにするのではなく、そのドキュメントにアクセスできる Command オブジェクトを作成するようにドキュメントに要求するだけです。内部状態であり、元に戻す/やり直しを適切にサポートするのに十分なことが保証されています。

残念ながら、C# はフレンドの概念をサポートしていないため、ドキュメントの内部にアクセスできる Command クラスを作成することはできません。ドキュメント クラスのプライベート メンバーを別のクラスに公開する方法はありますか、または多くのドキュメントの内部を公開することなく、必要なことを行う他の方法はありますか?

4

4 に答える 4

2

ドキュメントが内部状態と対話する「内部」メソッドを宣言できるライブラリを展開している場合、これらのメソッドは Command クラスによって使用され、内部メソッドはコンパイルされたアセンブリに限定されます。

または、ドキュメントにプライベート クラスをネストして、ドキュメントの内部状態にアクセスし、パブリック インターフェイスを公開できるようにすることもできます。ドキュメントは、そのインターフェイスによって隠されているコマンド クラスを作成します。

于 2011-12-25T19:56:35.990 に答える
2

まず、C# にはinternal"friend" アクセシビリティを宣言するキーワードがあります。これにより、アセンブリ全体からのパブリック アクセスが許可されます。

次に、「フレンド」アクセシビリティは、アセンブリ属性を持つ2 番目のアセンブリに拡張できるため、コマンド用の2 番目のプロジェクトInternalsVisibleToを作成できますが、ドキュメントの内部は内部のままです。

または、コマンド オブジェクトがドキュメント クラス内にネストされている場合、それらはすべてのプライベート メンバーにアクセスできます。

最後に、複雑なコマンドを使用して、変更を加える前にドキュメントを単純に複製することもできます。あまり最適化されていませんが、これは簡単な解決策です。

于 2011-12-25T20:11:32.427 に答える
0

Type.GetField(string, BindingFlags.Private)リフレクション( &フレンズ)を介して、プライベートかどうかに関係なく、いつでもフィールドとプロパティにアクセスできます。

たぶん、各コマンドに十分な状態を取得するプロセスを自動化するために、クラス(またはフィールド/プロパティ)にカスタム属性を使用しますか?

于 2011-12-25T19:49:14.703 に答える
0

ドキュメントのさまざまな場所で変更を行うコマンドを使用する代わりに、複数ステップの操作の開始と終了をマークする 2 つのダミー コマンドを使用できます。それらを BeginCommand と EndCommand と呼びましょう。最初に、元に戻すスタックに BeginCommand をプッシュしてから、さまざまな手順を 1 つのコマンドとして実行します。それぞれの手順は、ドキュメントの 1 か所のみで変更を行います。もちろん、元に戻すスタックにもそれらをプッシュします。最後に、元に戻すスタックに EndCommand をプッシュします。

元に戻すときは、元に戻すスタックからポップされたコマンドが EndCommand であるかどうかを確認します。そうである場合は、BeginCommand に到達するまで取り消しを続けます。

これにより、マルチステップ コマンドが、作業を他のコマンドに委譲するマクロ コマンドに変わります。このマクロ コマンド自体は、元に戻すスタックにプッシュされません。

于 2011-12-25T22:44:43.577 に答える