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). Yes
Whether the existing code-base was procedural or OO? 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 => 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->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 <= $end; $num++)
{
$data[$num] = '';
foreach ($this->fizzBuzz as $period => $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 => 'Fizz',
5 => 'Buzz'));
$fizzView->write($fizzBuzz->get());
echo PHP_EOL . '-- Three Buzz Bang' . PHP_EOL;
$threeBuzz = new Model_Fizz_Buzz(array(3 => 'Three',
4 => 'Buzz',
5 => 'Bang'));
$fizzView->write($threeBuzz->get(30, 61));