次のCharacter
、Potion
、およびPotionType
クラスがあるとします。
_class Player:
def __init__(self, name: str, health: int, mana: int):
self._name = name
self._attributes: Dict[PotionType,int] = {}
self._attributes[PotionType.Health] = health
self._attributes[PotionType.Mana] = mana
def replenish(self, potion):
if potion.type in self._attributes:
self._attributes[potion.type] = potion.amount
class PotionType(Enum):
Health = 1
Mana = 2
class Potion:
def __init__(self, amount : int, type: PotionType):
self.amount = amount
self.type = type
def refill(self, amount):
pass
_
ここでの主な関心事は、Player
クラスのreplenish(self, potion)
メソッドです。キャラクターオブジェクトが_potion.type
_と_potion.amount
_を要求するのは悪い習慣ですか?
私は Tell、Do n't Ask ガイドラインを認識していますが、作成者でさえゲッターには時間と場所があることを認めています。
Tell-dont-askで問題になるのは、すべてのクエリメソッドを削除しようとする人々がGetterEradicatorsになることを奨励していることです。しかし、情報を提供することでオブジェクトが効果的に連携する場合があります。
そしてこれ link :
しかし、ゲッターを回避するように人々に伝えるだけでは、かなり率直なツールであると私は恐れています。オブジェクトがデータを交換することによって協調する必要がある場合が多すぎて、ゲッターの真のニーズにつながります。
これは、ゲッターが本当に必要な状況の1つですか?
明らかに、Player
はPotion
を飲み、制限を超えません。これは、2つのクラス間でデータ(type
とamount
)を共有することを意味します。
ゲッターはいつ受け入れられますか?
コレクションを扱っているとき。
コレクションは通常、メモリ内のアドレス以外の内容を認識しません。これがわからないため、従来のオブジェクトよりもデータ構造が多くなります。彼らがゲッターとセッターを持っていることを決して嘆くことはありません。ブレークポイントを設定する場所があるのはいいことです。
フォローしたい場合は 教えてください、尋ねないでください ここでは、ポーションにそのタイプまたは使用の制限を明らかにさせません。プレイヤーはそれらのどちらかを知る必要はありません。続きます言ってはいけませんプレーヤーは、ポーションがプレーヤーに何かをするように伝えることができるインターフェースを提供する必要があります。
これはすべて次のようなものから始める必要があると考えるのが一般的です。
player.drink(potion);
そして、それはできます。しかし、教えてください、尋ねないでくださいとすると、次のような結果になります。
potion.affect(player);
ポーションの種類によっては、次のような結果になる可能性があります。
player.heal(MAX);
または
player.heal(HALF);
または
player.heal("1d6");
または
player.polymorph(RABID_SQUIRREL);
の要点は、尋ねないでくださいそれは polymorphism を使用する機能を維持することです。プレイヤーはこれがどんな種類のポーションであるかを知る必要はありません。ポーションは、プレーヤーの最大ヒットポイントが何であるか、プレーヤーの回復にどのようなボーナスがあるのか、またはプレーヤーが狂犬病の影響を受けないかどうかを理解する必要はありません。ポーションは、プレイヤーに何をするように伝えようとしているのかを理解するだけです。プレーヤーがそれをどのように、または行ったとしても、それはプレーヤー次第です。