假设您有一个很长的方法,如下所示:
int monster()
{
int rc = 0;
// some statements ...
if (dragonSlayer.on_vacation()) {
cout << "We are screwed!\n";
if (callTheKing() == true)
return 1;
else
return 2;
} else {
cout << "We are saved!\n";
slayTheDragon();
}
// rest of long method...
return rc;
}
我正在努力捣乱代码。我想将龙屠杀部分提取到
int handleDragon() {
if (dragonSlayer.on_vacation()) {
cout << "We are screwed!\n";
if (callTheKing() == true)
return 1;
else
return 2;
} else {
cout << "We are saved!\n";
slayTheDragon();
}
return 0; // ?
}
并通过调用handleDragon()替换monster()中的代码。
但是有一个问题。该部分的中间有一个返回声明。如果我保留处理handleDragon()返回码的部分,它将把垃圾保留在大方法中。
除了使用异常之外,还有一种优雅而安全的方法可以从怪物方法中重构这段代码吗?如何处理这些类型的情况?
答案 0 :(得分:2)
如果龙杀手可用,则从handleDragon
方法返回0:
int handleDragon() {
if (dragonSlayer.on_vacation()) {
cout << "We are screwed!\n";
if (callTheKing() == true)
return 1;
else
return 2;
} else {
cout << "We are saved!\n";
slayTheDragon();
return 0;
}
}
然后返回monster
方法,如果返回值大于零,则返回该值,否则继续:
// some statements ...
int handleDragonResult = handleDragon();
if (handleDragonResult > 0) {
return handleDragonResult;
}
// rest of long method...
您还应记录handleDragon
方法,以解释返回的值。
答案 1 :(得分:1)
enum DragonHandled { DHSuccess, DHKing, DHNoKing };
inline DragonHandled askForKing()
{
if (callTheKing())
return DHKing;
else
return DHNoKing;
}
DragonHandled handleDragon()
{
if (dragonSlayer.on_vacation()) {
cout << "We are screwed!\n";
return askForKing();
}
cout << "We are saved!\n";
slayTheDragon();
return DHSuccess;
}
int monster()
{
some_statements(...);
DragonHandled handled = handleDragon();
if( handled != DHSuccess )
return handled; // enum to int is an implicit cast
return more_statements(...);
}
int
。如果结果有意义,请正确定义该含义(即:enum
)。 handle
dragon()
, {{1} } call
)。 TheKing()
不是动词,不是你可以做的事情。如果我看到标识符monsters
,我认为它是怪物的容器。 monsters
只是无用的噪音,因为if(x == true)
更简洁,更简单,也是如此。 答案 2 :(得分:0)
你不能这样做:
int handleDragon() {
int rc = 0;
if (dragonSlayer.on_vacation()) {
cout << "We are screwed!\n";
if (callTheKing() == true)
rc = 1;
else
rc = 2;
} else {
cout << "We are saved!\n";
slayTheDragon();
}
return rc;
}
然后:
int monster()
{
int rc = 0;
// some statements ...
rc = handleDragon();
// rest of long method...
return rc;
}
或者如果您想对返回码执行某些操作:
int monster()
{
int rc = 0;
// some statements ...
int handleDragonReturnCode = handleDragon();
if(handleDragonReturnCode == 0) {
// do something
}
else {
// do something else
}
// rest of long method...
return rc;
}
这是你想要的吗?一般说明,请避免使用幻数,例如1
和2
作为返回代码。使用常量#define
或enum
。
关于return
,尝试从您的函数中获取一个出口点。正如您所知,拥有多个return
语句可以使重构变得困难(以及理解逻辑,除非它真的很简单)。
答案 3 :(得分:0)
问题是关于策略所以我认为Richard Fearn的答案很好。
要使其成为重构模式,它看起来像:
上下文:提取更大方法中间的部分。
问题:该部分包含return语句。
<强>解决方案强>:
这将是主要方法。下一步,你可以将新方法的返回值重构为更有意义的东西(比如sbi的答案)。而且你必须找到一种方法来处理返回类型不是标量或简单类型的情况,返回NULL对象或其他类型。