web-dev-qa-db-ja.com

OOP:新しいオブジェクトをパラメーターとして渡すか、コンストラクター内で作成しますか?

Heroから継承する3つのサブクラスがあります。

  • Warrior
  • Magician
  • Amazon

それらの3つはWeaponを保持します。これは常に同じです。

  • Warriorは常にSwordを保持します(Weaponから継承)
  • Magicianは常にWandを保持します(Weaponから継承)
  • Amazonは常にBowを保持します(Weaponから継承)

私はいくつかの解決策を心に留めています:

  1. 武器をコンストラクターのパラメーターとして渡します(これはファクトリーから実行する必要がありますか?この場合、Warriorを作成するときは、Swordなどが既に付属している必要があります...)

  2. Heroesのそれぞれのコンストラクター内に特定の武器を作成します。

さらにテストすることを考えると、solution 1を使用すると、オブジェクトの作成時にモックされたWeaponを渡すことができます。一方、solution 2は機能せず、ユニット(my Hero)を他のコンポーネント(Weapon)から分離することで、ユニットテストの原則を満たせなくなると思います。

ここでどう思いますか?

7
charliebrownie

ソリューション2では武器のモックが許可されないため、テストの妨げになると言うのはあなたの言うとおりです。 hソリューション2のもう1つの欠点は、2つの具象クラス これは良くない の間の結合を作成することです。

コンストラクタ内で武器をインスタンス化すると、ヒーローと武器の関係が composition のいずれかになります。これは、ドメインを完全にはモデル化しません。武器はヒーローの一部ではないため、武器はヒーローと独立して存在できます。逆に。私たちはみな、神秘的な武器が休眠状態にあるか、それが「活性化」する運命にあるか、それを発見するか、または詐欺師がそれを盗んだ( 岩の上の剣 、など)、武器はヒーローとは別に存在することができます。また、たいていの場合、英雄は武器を彼らのために作っています、たとえばギリシャの神 Hephaestus は神のための鍛冶屋であり、彼らのために武器を作ったので、コンストラクターでは起こらない武器の作成ヒーローの。また、ヒーローが殺されても武器は残ります。したがって、関係は aggregation である必要があります。

したがって、IMHOオプション2はノーゴーであり、ソリューション1は進むべき道です。

5

解決策3:各ヒーローを構築できるようにするなし武器をまったく使用しない。代わりに、ヒーローに彼/彼女が持っている武器のパブリックプロパティを与え、必要に応じて外部からこのプロパティを割り当てるか、後で再割り当てします。このプロパティはnullの可能性があります。これは、現在ヒーローが武器を持っていないことを示しています。

「ヒーロー」クラスのようなエンティティークラスを作成するとき、オブジェクト内に特定のゲームメカニズムを実装することは避けます。いつ、どこで、どのように武器が作成され、渡されるかisそのメカニズムの一部なので、これをオブジェクトにハードコーディングしないことをお勧めします。

5
Doc Brown

あなたが話している違いは 集約と構成 の間です。

パーツのライフタイムがそれを含むクラスのライフタイムと同じである場合は、compositionを使用します。 HandはHumanの複合パーツです。クラス内または全体のコンストラクター内で複合パーツを作成するのが普通です。使用法を最も正確に反映するアプローチを使用してください。

逆に、小麦粉と卵は、あらかじめ存在するケーキを作るために使用されるので、それらをケーキのコンストラクターに渡します。手は人とともに成長するので、クラス内で構築します。単純な経験則は、XがYのpartである場合、構成を適用します。

パーツの寿命がコンテナの寿命によって制約されていない場合は、集計を使用します。武器の寿命は人によって異なり、変更、ピックアップ、ドロップが可能です。それは武器屋によって構築され、ヒーローによって発見され、販売されます。集約の簡単な経験則は、Xがused(または特定の動詞)でYによって使用される場合、集約を適用することです。

Class Character {
  Hand right = new Hand();
  Hand left;

  Character() {
    left = new Hand();
    }

  public equipLeft(Weapon weapon) {
    left.equipped(weapon)
    }
  }
2
Martin Spamer

これについて考えるときのもう1つの良い質問:これは1:1か1:多か?つまり、ヒーローは0個または多くの武器を運ぶことができますか?たぶんそうですよね?私のD&Dアーチャーレンジャーでさえ決して近づかないので、錆びた鈍い剣も持っています。したがって、コンストラクターで正確に1つの武器を渡すこと、または自動的に1つを作成することは、どちらも間違っています。 @Doc Brownが示唆したように、addWeapon()メソッドが必要です。そしておそらくremoveWeapon()も。

0
user949300