如何通过方法链式调用重构FizzBuzz代码?
我正在尝试重构我的代码,但不知道如何实现预期效果,也不清楚这种写法的名称,因此无法通过Google检索到相关资料。
我的原始代码如下:
public void print(int from, int to) { // TODO Auto-generated method stub for(;from<=to;from++) { if(from % 3 == 0) { if(from % 5 == 0) { System.out.println("Fizz Buzz"); } else { System.out.println("Fizz"); } } else { if(from % 5 == 0) { System.out.println("Buzz"); } else { System.out.println(from); } } } }我希望将代码重构为如下形式:
print("Fizz").If(from).IsMultipleOf(3); print("Buzz").If(from).IsMultipleOf(5); print("Fizz Buzz").If(from).IsMultipleOf(3).And.IsMultipleOf(5);或者:
if(If(from).IsMultipleOf(3) && If(from).IsMultipleOf(5)) { print("Fizz Buzz"); }其中
If(from).IsMultipleOf(3)需要返回布尔值,当返回true时执行print()方法。但我不知道如何实现这种用点(".")连接方法的写法,能否有人告诉我对应的检索术语,或者提供一个实现示例?提前感谢!
Hey there! The pattern you're aiming for is called a Fluent Interface — it's a design style that chains method calls together to create readable, natural-language-like code. Let's break down how to build this for your FizzBuzz scenario step by step.
Step 1: Build a Fluent Condition Class
First, we'll create a class to handle number checks and support method chaining. This will power the If(from).IsMultipleOf(x) logic:
public class FluentCondition { private final int number; private boolean conditionResult; // Private constructor to force use of the static "If" entry point private FluentCondition(int number) { this.number = number; this.conditionResult = true; // Start with a true base for chaining } // Static entry method to kick off the fluent chain public static FluentCondition If(int number) { return new FluentCondition(number); } // Check if the number is a multiple of the given divisor, then return the instance to keep chaining public FluentCondition IsMultipleOf(int divisor) { conditionResult = conditionResult && (number % divisor == 0); return this; } // Add an "And" property for readability (just returns the current instance) public FluentCondition getAnd() { return this; } // Convert the chained condition to a boolean for standard if statements public boolean toBoolean() { return conditionResult; } }
Step 2: Create a Fluent Printer Class
Next, we'll build the print() side of things, which ties the condition check to printing your message:
public class FluentPrinter { private final String message; private FluentPrinter(String message) { this.message = message; } // Static entry method to start the print chain public static FluentPrinter print(String message) { return new FluentPrinter(message); } // Link to the FluentCondition class to add conditional logic public ConditionChecker If(int number) { return new ConditionChecker(message, number); } // Inner class to handle the condition-to-print flow public static class ConditionChecker { private final String message; private final FluentCondition condition; public ConditionChecker(String message, int number) { this.message = message; this.condition = FluentCondition.If(number); } public ConditionChecker IsMultipleOf(int divisor) { condition.IsMultipleOf(divisor); return this; } public ConditionChecker getAnd() { condition.getAnd(); return this; } // Terminal method to trigger printing if the condition is true public void execute() { if (condition.toBoolean()) { System.out.println(message); } } } }
Step 3: Use the Fluent Interface in Your FizzBuzz Logic
Now you can rewrite your code using the clean chained syntax. Here's how both of your desired approaches work:
Option 1: Direct Chained Print Calls
public void printFizzBuzz(int from, int to) { for (; from <= to; from++) { // Print "Fizz Buzz" if divisible by both 3 and 5 FluentPrinter.print("Fizz Buzz").If(from).IsMultipleOf(3).getAnd().IsMultipleOf(5).execute(); // Print "Fizz" only if not already part of "Fizz Buzz" if (!FluentCondition.If(from).IsMultipleOf(3).getAnd().IsMultipleOf(5).toBoolean()) { FluentPrinter.print("Fizz").If(from).IsMultipleOf(3).execute(); } // Print "Buzz" only if not already part of "Fizz Buzz" if (!FluentCondition.If(from).IsMultipleOf(3).getAnd().IsMultipleOf(5).toBoolean()) { FluentPrinter.print("Buzz").If(from).IsMultipleOf(5).execute(); } // Print the number if it's not Fizz/Buzz if (!FluentCondition.If(from).IsMultipleOf(3).toBoolean() && !FluentCondition.If(from).IsMultipleOf(5).toBoolean()) { System.out.println(from); } } }
Option 2: Fluent Conditions in Standard If Statements
public void printFizzBuzz(int from, int to) { for (; from <= to; from++) { boolean isFizz = FluentCondition.If(from).IsMultipleOf(3).toBoolean(); boolean isBuzz = FluentCondition.If(from).IsMultipleOf(5).toBoolean(); if (isFizz && isBuzz) { System.out.println("Fizz Buzz"); } else if (isFizz) { System.out.println("Fizz"); } else if (isBuzz) { System.out.println("Buzz"); } else { System.out.println(from); } } }
Quick Notes
- The core of a fluent interface is that each method returns an instance of the class (or a related class) to keep the chain going.
- The
getAnd()method lets you write.Andin Java (since Java uses camelCase for getters) to make the chain read more like natural language. - We added an
execute()terminal method because Java can't automatically trigger the print after the condition check — this is a necessary step to run the action when the condition passes.
内容的提问来源于stack exchange,提问作者Luké

