2015-06-27 5 views
0

У меня есть следующий код:Есть ли лучший читаемый способ написать эту цепочку операторов if?

Creature::cancelWalk() 
{ 
    Player* player = getPlayer(); 

    if (!player) { 
     if (getMonster() && getMonster()->getMaster() && getMonster()->getMaster()->getPlayer()) { 
      player = getMonster()->getMaster()->getPlayer(); 
     } 
    } 

    if (player) { 
     player->sendCancelMessage(ret); 
     player->sendCancelWalk(); 
    } 
} 

После краткого анализа, можно легко понять, я хочу, чтобы достичь чего-то простое:

Если creature является сам player, то sendCancelMessage и sendCancelWalk. Иначе, если creature - это monster, у которого также есть мастер, который является player, отправьте тот же материал клиенту.

Есть ли лучший способ, чтобы написать этот код без добавления других методов на Monster, Creature и Player классов?

Monster и Player оба являются "братьями и сестрами", полученными от Creature.

+0

Предполагая, что последовательные вызовы 'getMonster() -> getMaster() -> getPlayer() 'не может возвращать разные значения, вам не нужно проверять его значение в операторе' if'. –

+0

Похож на вопрос для http://codereview.stackexchange.com. – DanielKO

ответ

0

Предполагая, что различные функции не имеют разных эффектов для нескольких вызовов, попробуйте ввести некоторые временные файлы.

Player* player = getPlayer(); 

if (!player) 
{ 
    Monster monster = getMonster(); 
    if (monster) 
    { 
     Master *master = monster->getMaster(); 
     if (master) player = master->getPlayer()) { 
    } 
} 

if (player) { 
    player->sendCancelMessage(ret); 
    player->sendCancelWalk(); 
} 

Помимо этого, возможно, вы захотите более внимательно изучить свой дизайн. Если у вас есть много вложенных указателей, которые вам нужно последовательно проверять на NULL до разыменования, возможно, стоит указать и ввести в действие инварианты, что указатели не являются NULL (это означает, что они строят только родительские объекты, если все составляющие компоненты могут быть созданы, и никогда строить объекты, если они могут быть только частично построены).

Например, если предположить, что getMonster() возвращает не-NULL, который гарантирует, что getMaster() и getPlayer() также не возвращают NULL ....

Player* player = getPlayer(); 

if (!player) 
{ 
    player = getMonster()->getMaster()->getPlayer()); 
} 

if (player) 
{ 
    player->sendCancelMessage(ret); 
    player->sendCancelWalk(); 
} 
+0

Вы предполагали, что не-NULL getMonster() подразумевает не-NULL getMaster() и getPlayer(), но ваш код не выполняет нулевую проверку на getMonster(). Кроме того, в вопросе было указано, что у монстра может быть не один хозяин, и этот мастер не может быть игроком. – pkubik

+0

Вы пропустили мою точку зрения, pkubik, которая должна быть редизайна, чтобы избежать необходимости проверки NULL. Я подберу слова, чтобы описать это. – Peter