У меня все еще есть небольшая проблема с пониманием концепции чистого ООД.
Допустим, у нас есть класс Human, и мы живем в мире, где иногда люди гуляют (мозг управляет ногами), где иногда исчезают деревья (человек это замечает), а иногда люди случайно бьют друг друга.
Первые два случая действительно просты:
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);
До сих пор я думаю, что это хорошо (пожалуйста, пожаловайтесь, если что-то не так) и читается как проза (что должно быть в хорошем коде ООП). Но как перенести попадание в ООП? Если Анна бьет Боба, а Боб падает, то падение не вызвано ни Анной, ни Бобом. Это вызвано попаданием, потерей баланса и физикой.
Я знаю только 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(); }
}
В этом случае тело Боба «замечает», что удар заставляет его упасть на землю, затем он «переместится» на землю. Я думаю, что это лучше, чем первый вариант, но это все равно почему-то не так.
Так что, пожалуйста, умные люди ООП, объясните мне, как вы справляетесь со случаями, когда в реальном мире А изменяет состояние B, но в мире ООП только B должен изменять состояние B.