10

ある種のRPGのコーディングを任されているとしましょう。これは、たとえば、インテリジェンス、ダメージボーナス、ヒットポイントなどのaとその統計を追跡したいことを意味します。Character GameCharacter

プロジェクトの終わりまでに、非常に多くのフィールドを処理することになりかねないことを前向きに恐れています。それぞれについて、非常によく似た一連の制約と動作に従うようにする必要があります(たとえば、最小値と最大値の間に制限されるようにしたい;「基本値」と「一時的なボーナス」を区別できるようにしたい;セッターとゲッターを経由せずに両方をインクリメントおよびデクリメントできるようにしたい) 。突然、すべてのフィールドに1つ(2つ?)のゲッターと4つのセッター、そしておそらく2つのリセッターも必要になります。10のフィールドでも、多くのメソッドが同じように意味します。

DRYnessの場合、クラスでこれらの統計をいじるロジックをカプセル化して、 or (返される値が範囲内にあることに注意)Fieldなどのコードを記述できるようにしました。クラスを作成するために、このような長さまで行ってきました。それらのフィールドをグループ化することですが、それは今のところ重要ではありません。intelligence.applyBonus(10)hitpoints.get()

さて、私は「プラグイン」しているときにこの問題にぶつかりましたFieldGameCharacterほとんどのJava教科書では、各クラスにはパブリックゲッターとセッターを備えたプライベートフィールドが必要であると書かれています。それは理論的には良さそうです、そして私はすでにint;の周りにクラス全体を構築しました。ただし、ゲッターを呼び出して取得する場合、アイデアはそれほど堅実に聞こえません...ゲッター:

thisCharacter.getIntelligence().get() //eeek

フィールドに直接アクセスしたいです。たぶんそれは私のPython/VB [1]の「背景」ですが、私にとっては、よりクリーンで、より明確で、より単純です。

thisCharacter.intelligence.get()

パブリックフィールドの(理論上の)問題は、私がそれに対するすべての制御を放棄していることです。たとえば、コードベースの他のポイントで、不幸により、次のことが発生する可能性があります。

thisCharacter.intelligence = somethingThatReallyIsNull;

微妙なバグのように聞こえます...しかし...つまり、私は本当にそれについて心配する必要がありますか?私は直接割り当てる予定はありませんField[2]。これは実行すべきことではないことをJavadocに文書化していますが、それでも私はここで新しいので少し引き裂かれています。

それで、私はこのトピックについてのあなたの見解を聞きたいです。カプセル化の利点は非常に大きいので、先に進んでゲッターゲッターやセッターゲッターなどを用意する必要がありますか?それとも、健康的な対策でカプセル化を行い、フィールドFieldとして残す必要がありますか?public


[1]はい、わかっています。私は忘れようとしてきました。しかし、最近、C#とmanも少し見ましたが、プロパティは甘くありません。しかたがない。

[2]コンストラクターを除く!そして、ゲッターは欠陥のあるコンストラクターから私を救うことはありません。

4

10 に答える 10

8

私の経験では、多くのフィールドが必要な状況では、フィールドの数、性質、命名、およびタイプは非常に柔軟であり、プロジェクトの存続期間を通じて変更される可能性が高いため、フィールドの代わりに何らかのマップが必要になる可能性があります。 .

たとえば、キーから値への属性マップがあります。

属性を取得および設定するためのパブリック コールを提供しますが、誰もがそれらを使用できないようにします (または使用しないようにします)。代わりに、関心のある各属性を表すクラスを作成します。そのクラスは、その属性を操作するためのすべての機能を提供します。たとえば、Strength がある場合、特定の Player オブジェクトに初期化された「StrengthManipulation」クラスを作成してから、ゲッター、セッター (すべて適切な検証と例外を使用)、およびボーナスによる強度の計算などを提供することができます。 .

これの利点の 1 つは、プレイヤー クラスから属性の使用を切り離すことです。したがって、Intelligence 属性を追加すると、Strength のみを操作するすべてのものを処理して再コンパイルする必要がなくなります。

フィールドに直接アクセスすることに関しては、それは悪い考えです。VB (少なくとも古い VB) でフィールドにアクセスするときは、通常、プロパティの getter と setter を呼び出し、VB は () 呼び出しを非表示にします。私の見解では、使用している言語の慣習に適応する必要があります。C、C++、Java などでは、フィールドとメソッドがあります。メソッドの呼び出しには常に () を付けて、それが呼び出しであり、他のことが発生する可能性があることを明確にする必要があります (たとえば、例外が発生する可能性があります)。どちらにしても、Java の利点の 1 つは、より正確な構文とスタイルです。

VB から Java または C++ への変換は、大学院の科学論文へのテキスト メッセージのようなものです。

ところで: 一部のユーザビリティ調査では、コンストラクターにパラメーターを持たず、必要に応じてすべてのセッターを構築して呼び出す方がよいことが示されています。

于 2009-04-20T15:32:21.897 に答える
4

Steve Yegge は、これらの問題をカバーする非常に興味深い (長いとはいえ) ブログ記事を持っていました: The Universal Design Pattern .

于 2009-04-20T15:41:04.043 に答える
2

私には、「thisCharacter」には舞台裏のインテリジェンスを処理するための「インテリジェンス」オブジェクトが含まれているように見えますが、それを公開する必要があるかどうかは疑問です。それを処理するオブジェクトの代わりに、thisCharacter.applyInt と thisCharacter.getInt を公開する必要があります。そのような実装を公開しないでください。

于 2009-04-20T15:33:12.237 に答える
1

フィールドを非公開にしてください!API をあまり公開したくありません。将来のリリースでは、プライベートであったものをいつでもパブリックにすることができますが、その逆はできません。

それを次のMMORPGにするかのように考えてください。バグ、エラー、および不必要な悪の余地がたくさんあります。不変のプロパティが final であることを確認します。

ミニマルなインターフェイス (再生、停止、メニュー) を備えた DVD プレーヤーを考えてみてください。プログラムで重要でないものはすべて非表示にする必要があります。

于 2009-04-20T15:34:45.180 に答える
1

あなたの主な不満は、セッター/ゲッターメソッドの抽象化ではなく、それらを使用するための言語構文にあるようです。つまり、C# スタイルのプロパティのようなものが好まれます。

この場合、Java 言語が提供できるものは比較的少ないということになります。ゲッターまたはセッターに切り替える必要があるまでは、フィールドへの直接アクセスは問題ありません。その後、リファクタリングを行う必要があります (コードベース全体を制御する場合は、おそらく問題ありません)。

もちろん、Java プラットフォームが要件であるが、言語が要件でない場合は、他の選択肢があります。たとえば、Scala には非常に優れたプロパティ構文があり、そのようなプロジェクトに役立つ他の多くの機能があります。そして何よりも、JVM 上で実行されるため、Java 言語で作成した場合と同じ移植性が得られます。:)

于 2009-04-20T15:38:31.910 に答える
1

ここにあるように見えるのは、複合モデルの単一レイヤーです。

モデルを単に下位レベルのモデルのセットとして持つのではなく、モデルに抽象化を追加するメソッドを追加したい場合があります。

フィールドは final である必要があるため、公開したとしても、誤って割り当てられることはありませんnull

「get」接頭辞はすべての getter に存在するため、新しい問題というよりもおそらく初期の外観です。

于 2009-04-20T15:45:52.720 に答える
0

Eclipse の EMF などの「モデリング」フレームワークの使用を検討してください。これには、Eclipse EMF エディターなどを使用してオブジェクトを定義するか、プレーン XML で、または Rational Rose で定義する必要があります。思ったほど難しくありません。属性や制約などを定義すると、フレームワークがコードを生成します。getter メソッドや setter メソッドなど、追加した部分に @generated タグを追加します。コードをカスタマイズし、後で手動または GUI を使用して編集し、Java ファイルを再生成することができます。

于 2009-04-22T17:11:32.793 に答える