Есть ли смысл иметь функцию, которая вызывает только другую функцию?

#c

#c

Вопрос:

Просматривая исходный код исходного порта Doom 90-х годов (в данном случае Retrodoom), я нашел это:

 void A_Detonate(mobj_t *actor, player_t *player, pspdef_t *psp)
{
    P_RadiusAttack(actor, actor->target, actor->info->damage, false);
}
  

Эта функция A_Detonate служит только в качестве вызывающей функции p_radius Attack , поэтому возникает вопрос: почему бы просто не использовать p_radius attack без «родительской» функции?

Комментарии:

1. Для лучшей читаемости.

2. потому что он вызывает P_RadiusAttack очень специфическим способом, который изменяет его на mean A_Detonate . Это дает коду больше контекста. Это абсолютно необходимо. Кроме того, представьте false , изменился ли параметр (или любые другие параметры), когда произошел «взрыв». Вам пришлось бы менять ее везде, где вы хотели выполнить «детонацию». Не могли бы вы вспомнить, где вы имели в виду «взорвать», а не другую форму «RadiusAttack»?

3. «вызывает только другую функцию?» -> ну, он уважает некоторые члены и передает константу.

Ответ №1:

Функции иногда используются для повышения удобочитаемости для разработчиков, они могут делать что-то немного медленнее, но это значительно упрощает обслуживание кода.

Функция p_radius Attack может использоваться несколькими другими функциями, представьте себе место в коде, которое вызывает 10 различных «действий», кроме detonate , и все они вызывают p_radius Attack по-разному. Было бы намного удобнее для чтения и намного проще в обслуживании иметь функции с именами действий, чем иметь 10 вызовов p_radius attack немного другими способами.

Эти функции могут выполнять больше, чем вызов p_radius attack , или они могут вызывать его с другими параметрами, таким образом, код будет совершенно неструктурированным, если вы измените только A_Detonate .

Кроме того, функция на самом деле уже что-то делает, как вы можете видеть, параметры для 2 функций разные, фактически, установка правильных параметров в нужном месте — это уже то, что сделала функция.

Комментарии:

1. Вы действительно поднимаете хороший вопрос, но не могли бы вы подробнее рассказать о том, что вы подразумеваете под своим последним абзацем «помещение правильных параметров в нужное место»? Означает ли это, что P_RadiusAttack нельзя вызвать, не вызвав сначала A_Detonate ?

Ответ №2:

Это пример отделения интерфейса от реализации. Итак, пользователи

 void A_Detonate(mobj_t *actor, player_t *player, pspdef_t *psp)
  

такие, как вы, могут продолжать использовать ту же сигнатуру функции в своем коде, когда, возможно, в будущем разработчики A_Detonate могут решить сделать что-то подобное

 void A_Detonate(mobj_t *actor, player_t *player, pspdef_t *psp)
{
    P_DiameterAttack(actor, actor->target, actor->info->damage, false);    
    P_RadiusAttack(actor, actor->target, actor->info->damage, false);
    P_DumbAttack(actor, actor->target, actor->info->damage, false);
}
  

Другими словами, реализация функции может меняться независимо, но пользователи функции находятся в блаженном неведении, как и должно быть.

Комментарии:

1. Хм, разве реализация вызовов для P_DiameterAttack и P_DumbAttack внутри функции p_radius attack не приведет к тому же? Кроме того, было бы даже хорошо, если бы пользователи не знали об изменениях в своем коде, они могут не захотеть включать вызовы для P_DiameterAttack и P_DumbAttack .

2. возможно, вы захотите ознакомиться с API -интерфейсами прикладного программирования и абстракцией. Да, это хорошо, если пользователи API не знают, как это реализовано. Всякий раз, когда вносятся изменения в реализацию API, попробуйте представить, что произойдет, если подпись API также изменится. Миллионам пользователей пришлось бы обновлять свой код, что не очень хорошо, и это только один недостаток.

Ответ №3:

Судя по аргументам, это обработчик. A_Detonate даже не использует свой объект player и psp. Существование такой функции предполагает, что где-то есть код, который работает с такой сигнатурой, либо в целях унификации, либо в качестве адаптера, либо в качестве обработчика.