понедельник, 2 марта 2015 г.

[prog] Яркая демонстрация того, почему я предпочитаю сначала писать код на бумаге

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

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

Итак, вот код некоторой функции, который получился при записи своих пока еще сумбурных мыслей, что называется "в лоб":

void
try_to_push_message_to_agent(
   so_5::rt::agent_t & receiver,
   const so_5::rt::message_limit::control_block_t * limit,
   unsigned int overlimit_reaction_deep,
   mbox_id_t mbox_id,
   const std::type_index & msg_type,
   const message_ref_t & message )
{
   if( !limit )
      agent_t::call_push_event( receiver, mbox_id, msg_type, message );
   else
   {
      auto current = limit->m_count.load( std::memory_order::acquire );
      if( limit->m_limit > current )
      {
         current = ++(limit->m_count);
         if( limit->m_limit < current )
         {
            --(limit->m_count);
            do_overlimit_reaction(
                  limit,
                  overlimit_reaction_deep,
                  msg_type,
                  message );
         }
         else
            agent_t::call_push_event( receiver, mbox_id, msg_type, message );
      }
      else
         do_overlimit_reaction(
               limit,
               overlimit_reaction_deep,
               msg_type,
               message );
   }
}

А вот что из него же получилось буквально через пять минут пристрастного разглядывания:

void
try_to_push_message_to_agent(
   so_5::rt::agent_t & receiver,
   const so_5::rt::message_limit::control_block_t * limit,
   unsigned int overlimit_reaction_deep,
   mbox_id_t mbox_id,
   const std::type_index & msg_type,
   const message_ref_t & message )
{
   if( limit )
   {
      auto current = ++(limit->m_count);
      if( limit->m_limit < current )
      {
         --(limit->m_count);
         do_overlimit_reaction(
               limit,
               overlimit_reaction_deep,
               msg_type,
               message );

         return;
      }
   }

   agent_t::call_push_event( receiver, mbox_id, msg_type, message );
}

Это всего лишь наброски, компиляцию они не проходили. Но, думаю, особых проблем быть не должно. Кроме того, сильно подозреваю, что и второй вариант еще можно покурить в плане сокращения и упрощения.

И не просто подозреваю, а так и есть :)

void
try_to_push_message_to_agent(
   so_5::rt::agent_t & receiver,
   const so_5::rt::message_limit::control_block_t * limit,
   unsigned int overlimit_reaction_deep,
   mbox_id_t mbox_id,
   const std::type_index & msg_type,
   const message_ref_t & message )
{
   if( limit && ( limit->m_limit < ++(limit->m_count) ) )
   {
      --(limit->m_count);
      do_overlimit_reaction(
            limit,
            overlimit_reaction_deep,
            msg_type,
            message );
   }
   else
      agent_t::call_push_event( receiver, mbox_id, msg_type, message );
}

PS. Не агитирую за программирование на бумаге тех, кто слышал про этот способ и сознательно его не использует. А вот тем, кто никогда не слышал, можно и попробовать :) Поскольку, если вы, как и я, не можете сразу же написать настолько лаконичный код, как в третьем варианте, то программирование на бумаге -- это вполне работающий способ довольно быстро придти от откровенного говнокода к чему-то более-менее вменяемому. Проверено на себе :))

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