1、 前言
在软件工程中,一个众所周知的问题就是,不管做什么,用户的需求肯定会变。比方说,有个应用程序是帮助农民了解自己的库存的。这位农民可能想有一个查找库存中所有绿色苹果的功能。但到了第二天,他可能会告诉你:“其实我还想找出所有重量超过150克的苹果。”又过了两天,农民又跑回来补充道:“要是我可以找出所有既是绿色,重量也超过150克的苹果,那就太棒了。”要如何应对这样不断变化的需求?理想的状态下,应该把工作量降到最少。此外,类似的新功能实现起来还应该很简单,而且易于长期维护。
2、应对不断变化的需求
编写能够应对变化的需求的代码并不容易。让我们来看一个例子,我们会逐步改进这个例子,以展示一些让代码更灵活的最佳做法。就农场库存程序而言,必须实现一个从列表中筛选绿苹
果的功能。
2.1 小试牛刀,筛选苹果
假设有一个Apple类,它有一个getColor方法,还有一个变量inventory保存着一个Apples的列表。可能想要选出所 有的绿苹果,并返回一个列表。通常我们用筛选(filter)一词来表达这个概念,可能会写这样一个方法filterGreenApples:
public static List<Apple> filterGreenApples(List<Apple> inventory) {
List<Apple> result = new ArrayList<>();
for (Apple apple : inventory) {
if ("green".equals(apple.getColor())) {
result.add(apple);
}
}
return (result);
}
但是现在农民改主意了,他还想要筛选红苹果。该怎么做呢?简单的解决办法就是复制这个方法,把名字改成filterRedApples,然后更改if条件来匹配红苹果。然而,要是农民想要筛选多种颜色:浅绿色、暗红色、黄色等,这种方法就应付不了了。一个良好的原则是在编写类似的代码之后,尝试将其抽象化。
2.2 再展身手:把颜色作为参数
一种做法是给方法加一个参数,把颜色变成参数,这样就能灵活地适应变化了:
public static List<Apple> filterApplesByColor(List<Apple> inventory, String color) {
List<Apple> result = new ArrayList<Apple>();
for (Apple apple : inventory) {
if (apple.getColor().equals(color)) {
result.add(apple);
}
}
return result;
}
现在,只要像下面这样调用方法,农民朋友就会满意了:
List<Apple> greenApples = filterApplesByColor(inventory, "green");
List<Apple> redApples = filterApplesByColor(inventory, "red");
...
<