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