Here's the thing. When you see
switch (status) {
case 1:
case 2:
case 3:
case 4:
default:
}
what do you know? What does case 1
mean? Is 1
even a sensible status
?
The same thing applies with
status = 1;
status = 2;
status = 3;
status = 4;
It's just not a meaningful thing to write.
There's also:
public static final int fizz = 3;
public static final int buzz = 5;
Although this kind of makes sense, it doesn't really make sense. Fizz isn't 3. 3 is just the factor that triggers "Fizz" in the output.
You should really be encapsulating the state not over the result (FizzBuzz
/Fizz
/Buzz
/n
) but over the input (Fiz
/Not Fizz
, Buzz
/Not Buzz
). Java doesn't have tuples, so let's use javafx.util.Pair<Boolean, Boolean>
, and give it a loose abstraction:
public static class IsFizzOrBuzz extends Pair<Boolean, Boolean> {
public IsFizzOrBuzz(boolean isFizz, boolean isBuzz) {
super(isFizz, isBuzz);
}
public boolean isFizz() { return getKey(); };
public boolean isBuzz() { return getValue(); };
}
Unfortunately you can't do case
on objects, so the de-facto alternative is a hash map
static public Map<IsFizzOrBuzz, String> responses;
static {
responses = new HashMap<IsFizzOrBuzz, String>();
responses.put(new IsFizzOrBuzz(true, true), "FizzBuzz");
responses.put(new IsFizzOrBuzz(true, false), "Fizz");
responses.put(new IsFizzOrBuzz(false, true), "Buzz");
responses = Collections.unmodifiableMap(responses);
}
Then the proper abstraction looks like
public static int FIZZ_FACTOR = 3;
public static int BUZZ_FACTOR = 5;
public static IsFizzOrBuzz classify(int n) {
return new IsFizzOrBuzz(n % FIZZ_FACTOR == 0, n % BUZZ_FACTOR == 0);
}
public static String getResponse(int n, IsFizzOrBuzz classification) {
if (responses.containsKey(classification)) {
return responses.get(classification);
}
return String.valueOf(n);
}
public static void main(String[] args) {
for (int i = 1; i <= 100; i++) {
System.out.println(getResponse(i, classify(i)));
}
}
I'm going to be honest, though. Although this works quite well in a concise language:
fizz_factor = 3
buzz_factor = 5
responses = {
(True, True): "FizzBuzz",
(True, False): "Fizz",
(False, True): "Buzz"
}
def classify(n):
return (n % fizz_factor == 0, n % buzz_factor == 0)
def get_response(n, classification):
return responses.get(classification, str(n))
def main():
for i in range(1, 101):
print(get_response(i, classify(i)))
main()
in Java can you really call this worthwhile? You end up fighting the language most of the time. A simple
class FizzBuzz {
public static int FIZZ_FACTOR = 3;
public static int BUZZ_FACTOR = 5;
public static String getFizzBuzzResponse(int n) {
if ((n % FIZZ_FACTOR == 0) && (n % BUZZ_FACTOR == 0)) {
return "FizzBuzz";
}
if (n % FIZZ_FACTOR == 0) {
return "Fizz";
}
if (n % BUZZ_FACTOR == 0) {
return "Buzz";
}
return String.valueOf(n);
}
public static void main(String[] args) {
for (int i = 1; i <= 100; i++) {
System.out.println(getFizzBuzzResponse(i));
}
}
}
is easy enough. YAGNI.
switch
"... Don't have time to write up an answer now, though maybe later tonight if no one has since added one \$\endgroup\$