编写灵活的prettyPrintApple方法
编写一个prettyPrintApple方法,它接受一个Apple的List,并可以对它参数化,以 多种方式根据苹果生成一个String输出(有点儿像多个可定制的toString方法)。例如,你 可以告诉 prettyPrintApple 方法,只打印每个苹果的重量。此外,你可以让 prettyPrintApple方法分别打印每个苹果,然后说明它是重的还是轻的。解决方案和我们 前面讨论的筛选的例子类似。为了帮你上手,我们提供了prettyPrintApple方法的一个粗 略的框架:
public static void prettyPrintApple(List<Apple> inventory, ???){
for(Apple apple: inventory) {
String output = ???.???(apple);
System.out.println(output);
}
}
答案如下。
首先,你需要一种表示接受Apple并返回一个格式String值的方法。前面我们在编写 ApplePredicate接口的时候,写过类似的东西:
public interface AppleFormatter{ String accept(Apple a); }
现在你就可以通过实现AppleFormatter方法,来表示多种格式行为了:
public class AppleFancyFormatter implements AppleFormatter{ public String accept(Apple apple){ String characteristic = apple.getWeight() > 150 ? "heavy" : "light"; return "A " + characteristic + " " + apple.getColor() +" apple"; } } public class AppleSimpleFormatter implements AppleFormatter{ public String accept(Apple apple){ return "An apple of " + apple.getWeight() + "g"; } }
最后,你需要告诉prettyPrintApple方法接受AppleFormatter对象,并在内部使用 它们。你可以给prettyPrintApple加上一个参数:
public static void prettyPrintApple(List<Apple> inventory,AppleFormatter formatter){ for(Apple apple: inventory){ String output = formatter.accept(apple); System.out.println(output); } }
搞定啦!现在你就可以给prettyPrintApple方法传递多种行为了。为此,你首先要实 例化AppleFormatter的实现,然后把它们作为参数传给prettyPrintApple:
prettyPrintApple(inventory, new AppleFancyFormatter());
这将产生一个类似于下面的输出:
A light green apple
A heavy red apple
…
或者试试这个:
prettyPrintApple(inventory, new AppleSimpleFormatter());
这将产生一个类似于下面的输出:
An apple of 80g
An apple of 155g
…
你已经看到,可以把行为抽象出来,让你的代码适应需求的变化,但这个过程很啰嗦,因为 你需要声明很多只要实例化一次的类。让我们来看看可以怎样改进。