疯狂java


您现在的位置: 疯狂软件 >> 新闻资讯 >> 正文

Java重构笔记引入外加函数


 

   

  本文将介绍“引入外加函数”这种重构手法。

  下面让我们来学习这种重构手法吧。

  开门见山

  发现:你需要为提供服务的类增加一个函数,但你无法修改这个类。

  解决:在客户类中建立一个函数,并以第一参数形式传入一个服务器类实例。

  //before

  Date newStart = new Date(previous.getYear(),

  previous.getYear(),previous.getYear() + 1);

  //after

  Date newStart = nextDay(previous);

  private static Date nextDay(Date date){

  //......

  return new Date(date.getYear(),date.getMonth(),date.getDate() + 1)

  }

  动机

  你经常会遇到这样的事情:你正在使用一个类,它很好,为你提供了很多需要的服务。而后,你又需要增加一项新服务,这个类却无法供应。于是你开始咒骂:为什么不能做这件事情呢?如果可以修改源码,你便可以自行增加一个新函数;如果不能,你就得在客户端编码,补足你要的那个函数。

  如果只需要使用这个功能一次,那么额外的编码也没什么大不了的,甚至可能不需要原本提供服务的那个类。然而,如果需要多次使用这个函数,就不得不重复代码了。切记:重复代码是软件万恶之源。这些重复的代码应该被抽取出来放到同一个函数中。进行该项重构时,如果以外加函数实现一项功能,那就是一个明确信号:这个函数原本应该在提供服务的类中实现。

  如果发现为一个服务类建立了大量外加函数,或者发现有许多类都需要同样的外加函数,就不应该再使用本项重构,而应该使用“引入本地扩展”。但是不要忘记:外加函数终归是权宜之计。如果有可能的话,应该将这些函数搬移到它们的理想家园。由于代码所有权的原因使你无法做这样的搬移,就把外加函数交给服务类,请它帮忙在服务类中实现这个函数。

  做法

  (1)在客户类中建立一个函数,用来提供你需要的功能。(这个函数不应该调用客户类的任何特性。如果它需要一个值,把该值当做参数传递给它)

  (2)以服务类实例作为该函数的第一个参数。

  (3)将该函数注释为:“外加函数。应在服务类实现”(这样一旦后续有变更,可以轻松找出这些函数)

  示例

  程序中,需要跨过一个收费周期。原本代码像这样:

  Date newStart = new Date(previous.getYear(),

  previous.getYear(),previous.getYear() + 1);

  可以将赋值运算右侧代码提炼到一个独立函数中。这个函数就是Date类的一个外加函数:

  Date newStart = nextDay(previous);

  private static Date nextDay(Date date){

  //......

  return new Date(date.getYear(),date.getMonth(),date.getDate() + 1)

  }