Fizz Buzz interview question code Reading Jeff Atwood's "Why Can't Programmers.. Program?" led me to think that almost all of the solutions would not be something I would want in my own code-base.  The Fizz Buzz program specification from Imran is here which says:


  Write a program that prints the numbers from 1 to 100. But for
  multiples of three print “Fizz” instead of the number and for the
  multiples of five print “Buzz”. For numbers which are multiples of
  both three and five print “FizzBuzz”.


Implementing my solution differently than almost everyone else - I would like to put my solution up for review (as everyone doing it differently must think that my solution is not the best).

Could you please review my approach.  Is it overkill to suggest such a solution?  Under what conditions would you split it into a Model and Views?  Are there any issues with the code?

For a start, I don't think a language agnostic definition of the problem can fully describe the best solution.  In an interview I would find out by asking questions what was expected of the Fizz Bang code.  Probable questions and my assumed answers are:


Whether any changes were likely to be made in the future? (such as
new words, different rules other than 'Fizz' on multiples of 3 and 'Bang' on 5). &nbsp;&nbsp;&nbsp;Yes
Whether the existing code-base was procedural or OO? &nbsp;&nbsp;&nbsp;OO


I have decided to split the model and view components so that different output formats could be easily implemented.

Model:

class Model_Fizz_Buzz
{
   private $fizzBuzz;

   /** Construct the Fizz Buzz game model.
    *  @param fizzBuzz \Array The list of period =&gt; text for the game.  If the
    *  number is a multiple of the period then the text should be used.
    */
   public function __construct(Array $fizzBuzz=array())
   {
      $this-&gt;fizzBuzz = $fizzBuzz;
   }

   /** Get the Fizz_Buzz game numbers.
    *  @param start \int The number to start from (defaults to 1).
    *  @param end   \int The number to finish with (defaults to 100).
    */
   public function get($start=1, $end=100)
   {
      $data = array();

      for ($num = $start; $num &lt;= $end; $num++)
      {
         $data[$num] = '';

         foreach ($this-&gt;fizzBuzz as $period =&gt; $text)
         {
            if ($num % $period === 0)
            {
               $data[$num] .= $text;
            }
         }

         if (empty($data[$num]))
         {
            $data[$num] = $num;
         }
      }

      return $data;
   }
}


View:

class View_Text_Lines
{
   /** Write the data values separated by newlines.
    *  @param data \array The data to be written.
    */
   public function write(Array $data)
   {
      foreach ($data as $val)
      {
         echo $val . PHP_EOL;
      }
   }
}


Usage would be:

$fizzView = new View_Text_Lines();

echo PHP_EOL . '-- Standard Fizz Buzz' . PHP_EOL;
$fizzBuzz = new Model_Fizz_Buzz(array(3 =&gt; 'Fizz',
                                      5 =&gt; 'Buzz'));
$fizzView-&gt;write($fizzBuzz-&gt;get());

echo PHP_EOL . '-- Three Buzz Bang' . PHP_EOL;
$threeBuzz = new Model_Fizz_Buzz(array(3 =&gt; 'Three',
                                       4 =&gt; 'Buzz',
                                       5 =&gt; 'Bang'));
$fizzView-&gt;write($threeBuzz-&gt;get(30, 61));
Is it overkill to suggest such a solution? 


Yes, I think so :-)


  Under what conditions would you split it into a Model and Views? 


If you need more than one view. For example, if the specification says that the program should be able to write the results to the screen, a CSV/PDF file, a network socket, a web service etc.


  Are there any issues with the code?


It's fine, just three issues:


Naming: I'd rename $data to $result.
Input checks: 


What should happen when $start &gt; $end? (Check and throw an exception.)
What should happen when $period is not a number? (Throw an exception in the constructor.)

Unit tests are missing.



  Whether any changes were likely to be made in the future?


I would not try predicting it. If there are some change requests refactor it. The tests will show whether there is a regression or not. On Programmers.SE there are same questions about it:


Design for future changes or solve the problem at hand
Future proofing code