适用范围:根据类型做单次切换是可行的,如果switch太多,在添加新类型时如果忘记更新现有隐藏类型中的所有switch,会导致bug出现,8thlight博客关于这种情况有详细描述。
  解决方案: 使用多态,添加新类型时大家都不会忘记添加相关行为。
  注意:上例为了简洁只写了一个方法,但在有多个switch时更有用。
  public abstract class Bird {
  public abstract double getSpeed();
  protected double getLoadFactor() {
  return 3;
  }
  protected double getBaseSpeed() {
  return 10;
  }
  }
  public class EuropeanBird extends Bird {
  public double getSpeed() {
  return getBaseSpeed();
  }
  }
  public class AfricanBird extends Bird {
  public double getSpeed() {
  return getBaseSpeed() - getLoadFactor();
  }
  }
  public class NorwegianBird extends Bird {
  private boolean isNailed;
  public double getSpeed() {
  return isNailed ? 0 : getBaseSpeed();
  }
  }
  模式3:NullObject/Optional
  背景: 当外部请求理解代码库的主要用途时,回答“查一下null的情况”。
  public void example() {
  sumOf(null);
  }
  private int sumOf(List numbers) {
  if(numbers == null) {
  return 0;
  }
  return numbers.stream().mapToInt(i -> i).sum();
  }
  模式4:将内联语句(Inline statements)转为表达式
  背景: 在计算布尔表达式时,包含if语句树。
  public boolean horrible(boolean foo, boolean bar, boolean baz) {
  if (foo) {
  if (bar) {
  return true;
  }
  }
  if (baz) {
  return true;
  } else {
  return false;
  }
  }
  问题: 这种代码会导致开发者必须用大脑来模拟计算机对方法的处理。
  适用范围:很少有不适用的情况,像这样的代码可以合成一行,或者拆成不同的部分。
  解决方案: 将if语句树合成单个表达式。
  public boolean horrible(boolean foo, boolean bar, boolean baz) {
  return foo && bar || baz;
  }
  模式5:给出应对策略
  背景:在调用一些其他代码时,无法确保路径是成功的。
  public class Repository {
  public String getRecord(int id) {
  return null; // cannot find the record
  }
  }
  public class Finder {
  public String displayRecord(Repository repository) {
  String record = repository.getRecord(123);
  if(record == null) {
  return "Not found";
  } else {
  return record;
  }
  }
  }
  问题: 这类if语句增加了处理同一个对象或者数据结构的时间,其中包含隐藏耦合——null的情况。其它对象可能会返回其他代表没有结果的Magic value。
  适用范围:好将这类if语句放在一个地方,由于不会重复,我们能将为空对象的magic value删除。
  解决方案:针对被调用代码,给出应对策略。Ruby的Hash#fetch是很好的案例,Java也用到了类似的方法。这种模式也可以用在删除例外情况时。
  private class Repository {
  public String getRecord(int id, String defaultValue) {
  String result = Db.getRecord(id);
  if (result != null) {
  return result;
  }
  return defaultValue;
  }
  }
  public class Finder {
  public String displayRecord(Repository repository) {
  return repository.getRecord(123, "Not found");
  }
  }
  祝探索愉快
  希望这些模式对你现在处理的问题有帮助。我在重构代码增进理解时,发现这些方法都很有用。要记得并非所有if语句都是魔鬼,不过现代编程语言还有很多功能值得我们探索并使用。