C++ 如何将代码重构为子例程,但允许提前退出?
在这段代码中有一个非常明显的重构机会C++ 如何将代码重构为子例程,但允许提前退出?,c++,refactoring,C++,Refactoring,在这段代码中有一个非常明显的重构机会 bool翻译::兼容代码(常量规则和规则, 常数标准::向量和尼科德斯) { bool包含=错误; //循环通过ni代码。 对于(std::vector::const_迭代器iter=nicodes.begin(); iter!=nicodes.end(); ++国际热核聚变实验堆(iter) { //与规则的ni代码匹配 if(rule.get_ni1()==*iter) { //如果存在匹配项,请检查它是否标记为包含或排除 const std::stri
bool翻译::兼容代码(常量规则和规则,
常数标准::向量和尼科德斯)
{
bool包含=错误;
//循环通过ni代码。
对于(std::vector::const_迭代器iter=nicodes.begin();
iter!=nicodes.end();
++国际热核聚变实验堆(iter)
{
//与规则的ni代码匹配
if(rule.get_ni1()==*iter)
{
//如果存在匹配项,请检查它是否标记为包含或排除
const std::string flag=rule.get_op1();
//如果包含,则包含代码,除非稍后的规则将其排除
如果(flag==“INCLUDE”){INCLUDE=true;}
//如果排除,则明确排除代码
else if(flag==“EXCLUDE”){return false;}
}
if(rule.get_ni2()==*iter)
{
const std::string flag=rule.get_op2();
如果(flag==“INCLUDE”){INCLUDE=true;}
else if(flag==“EXCLUDE”){return false;}
}
if(rule.get_ni3()==*iter)
{
const std::string flag=rule.get_op3();
如果(flag==“INCLUDE”){INCLUDE=true;}
else if(flag==“EXCLUDE”){return false;}
}
if(rule.get_ni4()==*iter)
{
const std::string flag=rule.get_op4();
如果(flag==“INCLUDE”){INCLUDE=true;}
else if(flag==“EXCLUDE”){return false;}
}
if(rule.get_ni5()==*iter)
{
const std::string flag=rule.get_op5();
如果(flag==“INCLUDE”){INCLUDE=true;}
else if(flag==“EXCLUDE”){return false;}
}
}
包括退货;
}
我想把它变成这样:
bool Translations::compatibleNICodes(const Rule& rule,
const std::vector<std::string>& nicodes)
{
bool included = false;
// Loop through the ni codes.
for(std::vector<std::string>::const_iterator iter = nicodes.begin();
iter != nicodes.end();
++iter)
{
// Match against the ni codes of the rule
included |= matchNICode(rule.get_ni1(), rule.get_op1);
included |= matchNICode(rule.get_ni2(), rule.get_op2);
included |= matchNICode(rule.get_ni3(), rule.get_op3);
included |= matchNICode(rule.get_ni4(), rule.get_op4);
included |= matchNICode(rule.get_ni5(), rule.get_op5);
}
return included;
}
bool Translations::matchNICode(const std::string& ni,
const std::string& op)
{
if(ni == *iter)
{
if(op == "INCLUDE"){ return true; }
else if(op == "EXCLUDE"){ /*Return worse than false*/ }
}
return false;
}
bool翻译::兼容代码(常量规则和规则,
常数标准::向量和尼科德斯)
{
bool包含=错误;
//循环通过ni代码。
对于(std::vector::const_迭代器iter=nicodes.begin();
iter!=nicodes.end();
++国际热核聚变实验堆(iter)
{
//与规则的ni代码匹配
included |=匹配代码(rule.get_ni1(),rule.get_op1);
included |=匹配代码(rule.get_ni2(),rule.get_op2);
included |=匹配代码(rule.get_ni3(),rule.get_op3);
included |=匹配代码(rule.get_ni4(),rule.get_op4);
included |=匹配代码(rule.get_ni5(),rule.get_op5);
}
包括退货;
}
bool翻译::matchNICode(const std::string和ni,
const std::string和op)
{
如果(ni==*iter)
{
if(op==“INCLUDE”){return true;}
else if(op==“EXCLUDE”){/*返回比false更差的值*/}
}
返回false;
}
问题是,如果是exclude语句,我无法回避我希望提前退出的问题
请注意,我无法更改规则类的结构
有什么建议吗?显然,如果您可以循环遍历
ni
和op
规则的成员,代码会更干净、更简单。如果你不能重构规则
,也许你可以围绕它创建一个包装器来实现这个目标
如果您有一个使用这种代码的方法,我就不麻烦了。在我看来,只有通过几种类似的方法消除重复的代码,这才会有回报。显然,如果您可以循环遍历ni
和op
规则的成员,代码会更干净、更简单。如果你不能重构规则
,也许你可以围绕它创建一个包装器来实现这个目标
如果您有一个使用这种代码的方法,我就不麻烦了。在我看来,只有用几种类似的方法消除重复的代码,这才会有回报。下面是一种可能的重构,但我不确定这是否值得
定义NIU子句(ID)\
if(rule.get#ni#ID()==*iter)\
{ \
const std::string flag=rule.get#u op#ID()\
如果(flag==“INCLUDE”){INCLUDE=true;}\
else if(flag==“EXCLUDE”){return false;}\
}
bool翻译::兼容代码(常量规则和规则,
常数标准::向量和尼科德斯)
{
bool包含=错误;
//循环通过ni代码。
对于(std::vector::const_迭代器iter=nicodes.begin();
iter!=nicodes.end();
++国际热核聚变实验堆(iter)
{
第(1)条
第(2)条
第(3)条
第(4)条
第(5)条
}
包括退货;
}
下面是一种可能的重构,但我不确定这是否值得
定义NIU子句(ID)\
if(rule.get#ni#ID()==*iter)\
{ \
const std::string flag=rule.get#u op#ID()\
如果(flag==“INCLUDE”){INCLUDE=true;}\
else if(flag==“EXCLUDE”){return false;}\
}
bool翻译::兼容代码(常量规则和规则,
常数标准::向量和尼科德斯)
{
bool包含=错误;
//循环通过ni代码。
对于(std::vector::const_迭代器iter=nicodes.begin();
iter!=nicodes.end();
++国际热核聚变实验堆(iter)
{
第(1)条
第(2)条
第(3)条
第(4)条
第(5)条
}
包括退货;
}
bool Translations::compatibleNICodes(常量规则和规则),
常数标准::向量和尼科德斯)
{
bool包含=错误;
结构
{
规则(你得到)(你得到);;
规则_GET_OP GET_OP;
}方法tbl[]=
{
{&Rule::get_ni1,&Rule::get_op1},
{&Rule::get_ni2,&Rule::get_op2},
{&Rule::get_ni3,&Rule::get_op3},
{&Rule::get_ni4,&Rule::get_op4},
{&Rule::get_ni5,&Rule::
bool Translations::compatibleNICodes(const Rule& rule,
const std::vector<std::string>& nicodes)
{
bool included = false;
// Loop through the ni codes.
for(std::vector<std::string>::const_iterator iter = nicodes.begin();
iter != nicodes.end();
++iter)
{
// Match against the ni codes of the rule
included |= matchNICode(rule.get_ni1(), rule.get_op1);
included |= matchNICode(rule.get_ni2(), rule.get_op2);
included |= matchNICode(rule.get_ni3(), rule.get_op3);
included |= matchNICode(rule.get_ni4(), rule.get_op4);
included |= matchNICode(rule.get_ni5(), rule.get_op5);
}
return included;
}
bool Translations::matchNICode(const std::string& ni,
const std::string& op)
{
if(ni == *iter)
{
if(op == "INCLUDE"){ return true; }
else if(op == "EXCLUDE"){ /*Return worse than false*/ }
}
return false;
}
#define NI_CLAUSE(ID) \
if(rule.get_ni ## ID() == *iter) \
{ \
const std::string flag = rule.get_op ## ID(); \
if(flag == "INCLUDE"){ included = true; } \
else if(flag == "EXCLUDE"){ return false; } \
}
bool Translations::compatibleNICodes(const Rule& rule,
const std::vector<std::string>& nicodes)
{
bool included = false;
// Loop through the ni codes.
for(std::vector<std::string>::const_iterator iter = nicodes.begin();
iter != nicodes.end();
++iter)
{
NI_CLAUSE(1)
NI_CLAUSE(2)
NI_CLAUSE(3)
NI_CLAUSE(4)
NI_CLAUSE(5)
}
return included;
}
bool Translations::compatibleNICodes(const Rule& rule,
const std::vector<std::string>& nicodes)
{
bool included = false;
struct
{
RULE_GET_NI get_ni;
RULE_GET_OP get_op;
} method_tbl[] =
{
{ &Rule::get_ni1, &Rule::get_op1 },
{ &Rule::get_ni2, &Rule::get_op2 },
{ &Rule::get_ni3, &Rule::get_op3 },
{ &Rule::get_ni4, &Rule::get_op4 },
{ &Rule::get_ni5, &Rule::get_op5 },
};
// Loop through the ni codes.
for(std::vector<std::string>::const_iterator iter = nicodes.begin();
iter != nicodes.end();
++iter)
{
for(size_t n = 0; n < 5 /* I am lazy here */; ++n)
{
if((rule.*(method_tbl[n].get_ni))() == *iter)
{
// If there's a match, check if the rule is include or exclude
const std::string flag = (rule.*(method_tbl[n].get_op))();
// If include, code is included unless a later rule excludes it
if(flag == "INCLUDE"){ included = true; }
// If exclude, code is specifically excluded
else if(flag == "EXCLUDE"){ return false; }
}
}
}
return included;
}
bool Translations::compatibleNICodes(const Rule& rule,
const std::vector<std::string>& nicodes)
{
bool included = false;
try
{
// Loop through the ni codes.
for(std::vector<std::string>::const_iterator iter = nicodes.begin();
iter != nicodes.end();
++iter)
{
// Match against the ni codes of the rule
included |= matchNICode(rule.get_ni1(), rule.get_op1);
included |= matchNICode(rule.get_ni2(), rule.get_op2);
included |= matchNICode(rule.get_ni3(), rule.get_op3);
included |= matchNICode(rule.get_ni4(), rule.get_op4);
included |= matchNICode(rule.get_ni5(), rule.get_op5);
}
return included;
}
catch (WorseThanFalseException& ex)
{
return false; // Or whatever you have to do and return
}
}
bool Translations::matchNICode(const std::string& ni,
const std::string& op)
{
if(ni == *iter)
{
if(op == "INCLUDE"){ return true; }
else if(op == "EXCLUDE"){ throw WorseThanFalseException(); } // Whatever this is
}
return false;
}
struct FUNCTOR : std::unary_function<bool, std::string const &>
{
public:
FUNCTOR(Rule const &r) : included(false), rule(r)
{
}
// returns true if exluded
bool operator()(std::string const &s)
{
static METHODS methods[] =
{
{ &Rule::get_ni1, &Rule::get_op1 },
{ &Rule::get_ni2, &Rule::get_op2 },
{ &Rule::get_ni3, &Rule::get_op3 },
{ &Rule::get_ni4, &Rule::get_op4 },
{ &Rule::get_ni5, &Rule::get_op5 },
};
return(std::find_if(&methods[0], &methods[5], FUNCTOR2(rule, s, included)) != &methods[5]);
}
operator bool()
{
return(included);
}
private:
struct METHODS
{
std::string (Rule::*get_ni)() const;
std::string (Rule::*get_op)() const;
};
struct FUNCTOR2 : std::unary_function<bool, METHODS>
{
public:
FUNCTOR2(Rule const &r, std::string const &s, bool &incl) : rule(r), str(s), included(incl)
{
}
// return true if exluded
bool operator()(METHODS m)
{
if((rule.*m.get_ni)() == str)
{
// If there's a match, check if the rule is include or exclude
const std::string flag = (rule.*m.get_op)();
// If include, code is included unless a later rule excludes it
if(flag == "INCLUDE")
included = true;
// If exclude, code is specifically excluded
else if(flag == "EXCLUDE")
{
included = false;
return(true);
}
}
return(false);
}
private:
Rule const &rule;
std::string const &str;
bool &included;
};
Rule const &rule;
bool included;
};
bool Translations::compatibleNICodes(const Rule& rule,
const std::vector<std::string>& nicodes)
{
FUNCTOR f(rule);
std::find_if(nicodes.begin(), nicodes.end(), f);
return(f);
}
class TriState
{
public:
TriState(): mState(KO) {}
bool isValid() const { return mState != FATAL; }
bool ok() const { return mState == OK; }
void update(std::string const& value,
std::string const& reference,
std::string const& action)
{
if (mState == FATAL) return;
if (value == reference)
{
if (action == "INCLUDE") mState = OK;
else if (action == "EXCLUDE") mState = FATAL;
}
}
private:
typedef enum { OK, KO, FATAL } State_t;
State_t mState;
};
TriState state;
for (const_iterator it = nicodes.begin(), end = nicodes.end();
it != end && state.isValid(); ++it)
{
state.update(*it, rule.get_ni1(), rule.get_op1);
state.update(*it, rule.get_ni2(), rule.get_op2);
state.update(*it, rule.get_ni3(), rule.get_op3);
state.update(*it, rule.get_ni4(), rule.get_op4);
state.update(*it, rule.get_ni5(), rule.get_op5);
}
return state.ok();
class Wrapper
{
public:
Wrapper(Rule const& rule): mRule(rule) {}
std::string const& get_ni(size_t i) const { switch(i) { ... } }
std::string const& get_action(size_t i) const { switch(i) { ... } }
private:
Rule const& mRule;
};
void update(std::string const& value, Wrapper wrapper, size_t index)
{
if (mState == FATAL) return;
if (value == wrapper.get_ni(index))
{
if (wrapper.get_action(index) == "INCLUDE") mState = OK;
else if (wrapper.get_action(index) == "EXCLUDE") mState = FATAL;
}
}
TriState state;
Wrapper wrapper(rule);
for (const_iterator it = nicodes.begin(), end = nicodes.end();
it != end && state.isValid(); ++it)
{
for (size_t index = 1; index != 6 && state.isValid(); ++index)
state.update(*it, wrapper, index);
}
return state.ok();
bool Translations::compatibleNICodes(const Rule& rule,
const std::vector<std::string>& nicodes)
{
bool included = false;
// Loop through the ni codes.
for(std::vector<std::string>::const_iterator iter = nicodes.begin();
iter != nicodes.end();
++iter)
{
// Match against the ni codes of the rule
if (!matchNICode(rule.get_ni1(), rule, &Rule::get_op1, included)) return false;
if (!matchNICode(rule.get_ni2(), rule, &Rule::get_op2, included)) return false;
if (!matchNICode(rule.get_ni3(), rule, &Rule::get_op3, included)) return false;
if (!matchNICode(rule.get_ni4(), rule, &Rule::get_op4, included)) return false;
if (!matchNICode(rule.get_ni5(), rule, &Rule::get_op5, included)) return false;
}
return included;
}
bool Translations::matchNICode(const std::string& ni, const Rule& rule,
std::string (Rule::* const opfn)(), bool& included)
{
if (ni == *iter) {
const std::string& op = (rule.*opfn)();
if (op == "INCLUDE") {
included = true;
}
else if (op == "EXCLUDE") {
return false;
}
}
return true;
}