5

純粋な OOD の概念を理解するには、まだ少し問題があります。

クラス Human があり、人間が歩く (脳が足を制御する) ときもあれば、木が消え (人間がそれに気付く) ときもある 世界に住んでいるとしましょう。

最初の 2 つのケースは本当に簡単です。

class Tree {
  private:
    void disappear()
    {
       // call onTreeDisappeared() for all human observers
    }
};

class Human {
  public:
    // The human notices that a tree disappeared
    void onTreeDisappeared();
  private:
    int x, y, z;
    // Human wants to walk forward
    void moveForward();
    // Hit another human, possibly causing him to fall down
    void hit(Human &target);
};

今、私はヒットメソッドで本当に悪い問題を抱えています. もちろん言っていただけると嬉しいです

anna.hit(bob);

ここまでは、いい (何か悪いことがあれば文句を言ってください) し、散文のように読めると思います (良い OOP コードはそうあるべきです)。しかし、どうやってヒットを OOP に移すのでしょうか? アンナがボブにぶつかり、ボブが倒れた場合、転倒の直接の原因はアンナでもボブでもない。これは、ヒット、バランスの喪失、および物理学によって引き起こされます。

この場合の選択肢は 2 つしかわかりませんが、どういうわけか、どちらもダメだと思います。

public: void fallDown()
{ z = 0; }

public: void hit(Human &target)
{
  bool targetFallsDown = true; // could be random or any algorithm you like
  if(targetFallsDown)
  { target.fallDown(); }
}

この場合、アンナはボブに「倒れます」。しかし、これではまったく意味がありません。アンナがボブの体をつかんで地面に向かって動かすわけではありません。しかし、別のオプションがあります:

private: void fallDown()
{ z = 0; }

public: void onHitCausesMeToFallDown()
{ fallDown(); }

public: void hit(Human &target)
{
  bool targetFallsDown = true; // could be random or any algorithm you like
  if(targetFallsDown)
  { target.onHitCausesMeToFallDown(); }
}

この場合、ボブの体は、ヒットによって地面に倒れていることに「気づき」、地面に「移動」します。これは最初のオプションよりも優れていると思いますが、それでもどうもうまくいきません。

ですから、賢明な OOP 関係者の皆さん、私に説明してください。現実の世界では A が B の状態を変更するのに、OOP の世界では B だけが B の状態を変更する必要がある場合をどのように処理しますか?

4

2 に答える 2

10

あなたは、デザインの目的を持たずにクラスで「現実の」世界をモデル化しようとするという罠に陥っていると思います。

あなたのプログラムは何をすることになっていますか?それを解決したら、現実世界のどの側面をモデル化したいか、現実世界のどの部分が問題ではなく、モデル化する必要がないかを設計し始めることができます。簡単に視覚化できるという理由だけで、具体的な実世界のオブジェクト タイプにクラス マップを作成することは、多くの場合、間違いです。プログラムにとって重要な概念のみをモデル化する必要があります。

OOD とは、抽象化やポリモーフィズムなどの手法を使用して、オブジェクトが互いの実装を知らなくても相互にやり取りできるようにすることです。

実装では、モデル化する動作と、各オブジェクトが必要とする知識を決定する必要があります。たとえば、殴られた強さに基づいて、人間が倒れたいかどうかを判断することができます。

void Human::receiveHit(Hit hit)
{
    if (hit.IsBigForThisWeight(this->weight))
        this->fallDown();
}

私を襲ったものは、それが私に与える影響を知る必要も、気にする必要もないことに注意してください。それがヒットに対する私の反応です。私のプログラムにとって意味があるので、「ヒット」オブジェクトもモデル化しました。Hitオブジェクトを作成し、それを受け取るようにすることで、何でも私を襲うことができます。将来、クラスを変えずにバスや電車にひかれる可能性があります。

于 2011-04-23T14:46:42.370 に答える
1

時間の経過をモデル化していないため、ジレンマが生じると思います。すると、すべてが一度に起こりますanna.hit(bob)

独自のステート マシンを実行するようにエンティティをモデル化すると、物事がより現実に近くなり始めます。

  1. anna.hit(bob) により、bob の状態が に変わりfallingます。

  2. 次の数サイクルの間、ボブは彼の状態で急落し続けfallingます。

  3. 最終的にボブの状態は に変わりますon_ground

  4. 次に、ボブの状態が に変わりますcries_for_mommy

OO 言語で開始チャートを実装する方法については、状態設計パターンを参照してください。「Gang of Four's」のDesign Patterns本では、このトピックが取り上げられています。

于 2011-04-23T14:40:49.300 に答える