2018-02-09 可以降低圈复杂度的10种重构技术

2018-02-09  本文已影响0人  宇文vss

Composing Methods(重新组织你的函数)

1.Extract Method(提炼函数)

代码段可被组织在一起并独立出来

void printOwing(double previousAmount)
{
  Enumeration e = _orders.elements();
  double outstanding = previousAmount * 1.2;

  // print banner
  System.out.println ("* * * * * * * * * * * * * * * * * * * * * * *");
  System.out.println ("Customer Owes ");
  System.out.println (" * * * * * * * * * * * * * * * * * * * * * * *");

  // calculate outstanding
  while (e.hasMoreElements())
  {
    Order each = (Order) e.nextElement();
    outstanding += each.getAmount();
  }

  //print details
  System.out.println ("name:" +_name);
  System.out.println ("amount" + outstanding)
}

将这段代码放进一个独立函数中,并让函数名称解释该函数的用途

void printOwing(double previousAmount)
{
  printBanner();
  double  outstanding  =  getOutsta nding(previousAmount  *  1.2);
  printDetads(outstanding);
}

void printBanner0
{
   // print banner
.....
}

double getOutstanding(double initialValue)
{
  double result = initialValue;
  Enumeration e =  orders.elements();
  while (e.hasMoreElements())
  {
    Order each = (Order) e.nextElement();
     result += each.getAmount();
  }
  return result;
}

void printDetails (double outstanding)
 {
  //print details
...
}

2.Substitute Algorithm(替换你的算法)

把某个算法替换为另一个更清晰的算法

String foundPerson(String[] people)
{
  for (int i = 0; i < people.length; i++)
  {
      if (people[i].equals ("Don"))
       return "Don";
      if (people[i].equals ("John"))
       return "John";
      if (people[i].equals ("Kent"))
       return "Kent";
  }
  return "";
}

将函数本体替换为另一个算法

String foundPerson(String[] people)
{
   List candidates = Arrays.asList(new String[]{"Don", "John","Kent"});
   for (int i=0; i<people.length; i++)
      if (candidates.contains(people[i]))
         return people[i];
  return "";
}

Simplifying Conditional Expressions(简化条件表达式)

3. Decompose Conditional(分解条件式)

你有一个复杂的条件语句,从if、else段落中分别提炼出独立函数

if (date.before (SUMMER_START)  || date.after(SUMMER_END))
  charge = quantity * _winterRate  + winterServiceCharge;
else
  charge = quantity * _summerRate;

修改成

if (notSummer(date))
  charge = winterCharge(quantity);
else
  charge = summerCharge (quantity);

4.Consolidate Conditional Expression(合并条件式)

你有一系列条件判断,都得到相同结果,将这些判断合并为一个条件式,并将条件式提炼成为独立函数。

double disabilityAmount()
{
   if (_seniority < 2) return 0;
   if (_monthsDisabled > 12) return 0;
   if (_isPartTime) return 0;
   // compute the disability amount
...
}

修改成

double disabilityAmount()
{
   if (isNotEligableForDisability()) return 0;
   // compute the disability amount
...
}

5.Consolidate Duplicate Conditional Fragments(合并重复的条件片断)

在条件式的每个分支上有着相同的一段代码, 将这段重复代码搬移到条件式之外。

if (isSpeciaIDeal())
  {
     total = price * 0.95
     send();
  }
else
  {
     total = price* 0.98
     send();
  }

修改成

if (isSpeciaIDeal())
   total = price * 0.95
else
   total = price * 0.98
send();

6.Remove Control Flag(移除控制标记)

在一系列布尔表达式种,某个变量带有【控制标记】的作用,以break和return取代控制标记

void checkSecurity(String[] people) {
  boolean found = false;
  for (int i = 0; i < people.length; i++) {
      if (l found) {
         if (people[i].equals ("Don")){
          sendAlert();
           found = true;
       }
         if (people[i].equals ("John")){
           sendAlert();
             found = true;
       }
     }
  }
}

变成

void checkSecurity(String[] people) {
  for (int i = 0; i < people.length; i++) {
      if (people[i].equals ("Don")){
       sendAlert();
       break;
     }
      if (people[i].equals ("John")){
       sendAlert();
       break;
     }
  }
}

Making Method Calls Simpler(简化函数调用)

7.Separate Query from Modifier(将查询函数和修改函数分离)

某个函数既返回对象状态值,又修改对象状态。 建立两个不同的函数, 其中一个负责查询,另一个负责修改

Customer::getTotalOutstandingAndSetReadyForSummaries(...)
{
...
}

分成两个函数

Customer::getTotalOutstanding(...)
{
...
}
Customer::SetReadyForSummaries(...)
{
...
}

8.Parameterize Method(令函数携带参数)

若干函数做了类似的工作,但在函数本体中却包含了不同的值。建立单一函数,以参数表达那些不同的值

Dollars baseCharge0
 {
   double result = Math.min(lastUsage(),l00) * 0.03;
   if (lastUsage() > 100) {
     result += (Math.min (lastUsage(),200) - 100) * 0.05;
  };
   if (lastUsage() > 200) {
     result += (lastUsage() - 200)*0.07;
  };
  return new Dollars (result);
}

修改成

Dollars baseCharge()
{
   double result = usagelnRange(0, 100)* 0.03;
   result += usagelnRange (100,200) * 0.05;
   result += usagelnRange (200, Integer.MAX  VALUE) * 0.07
  return new Dollars (result);
}
int usagelnRange(int start, int end)
{
   if (lastUsage() > start)
     return Math.min(lastUsage(),end) -start
   else
     return 0;
}

9.Replace Parameter with Explicit Methods(以明确函数取代参数)

函数实现完全取决于参数值而采取不同反应,针对该参数的每一个可能值,建立一个独立函数

void setValue (String name, int value)
{
   if (name.equals("height"))
      _height = value;
   if (name.equals("width"))
      _width = value;
  Assert.shouldNeverReachHere();
}

改成

void setHeight(int arg)
{
  _height = arg;
}
void setWidth (int arg)
{
  _width = arg;
}

10.Replace Conditional with Polymorphism(以多态取代条件式)

你手上有个条件式,它根据对象类型的不同而选择不同的行为。那么,将整个条件式的每个分支放进子类的重载方法中, 然后将原始函数声明为抽象方法

double getSpeed()
{
   switch (_type) {
     case EUROPEAN:
       return getBaseSpeed();
     case AFRICAN:
      return getBaseSpeed() - getLoadFactor() *_numberOfCoconuts;
     case NORWEGIAN_BLUE:
       return (isNailed)  ? 0 : getBaseSpeed(_voltage);
    }
  throw new RuntimeException ("Should be unreachable");
}

修改成


image.png
上一篇下一篇

猜你喜欢

热点阅读