如何在不复制太多代码的情况下重构此代码?
Posted
技术标签:
【中文标题】如何在不复制太多代码的情况下重构此代码?【英文标题】:How to restructure this code without duplicating too much code? 【发布时间】:2021-08-18 21:14:06 【问题描述】:class
public:
void func(const int val, const bool flag)
if(flag)
while(!lower.empty() && val <= lower.top())
// do a bunch of stuff with lower
else
while(!higher.empty() && val >= higher.top())
// do a bunch of stuff with higher, but it's the same stuff as would've done
// for lower
private:
std::stack<int> lower;
std::stack<int> higher;
我正在尝试找出一种更好的方法来编写子句,因为目前我在这两个子句中都有很多重复的代码。唯一的区别是一个子句在lower
上运行,另一个在higher
上运行,第一个子句中的<=
在第二个子句中更改为>= higher
。
我可以将子句包装在一个辅助函数中并在每个子句中调用它(并将lower
和higher
作为参数传入),例如,
class
public:
void func(const int val, const bool flag)
if(flag)
helper(lower, comparer);
else
helper(lower, comparer);
void helper(std::stack<int> &st)
// do a bunch of stuff with st
private:
std::stack<int> lower;
std::stack<int> higher;
我不确定这是否是个好主意,如果是,我不确定如何绕过>=
与<=
。希望大家对我的设计提出建议!
【问题讨论】:
提取一个获取栈的方法? @DaveNewton 你能详细说明这意味着什么吗?是不是像我在第二个sn-p中描述的辅助函数? 这应该没问题;事实上,它经常在标准库中完成。通常,您将参数设为模板参数。不确定这是否是计划,因为辅助函数目前只接受一个参数。template<typename ComparerType> void Helper(std::stack<int>& st, int val, ComparerType compare) while(!st.empty() && compare(val, st.top()) ...
Helper(lower, val, [](int a, int b) return a <= b; );
@f*** 代替 lambdas,可以使用std::less_equal
和std::greater_equal
,例如:Helper(lower, val, std::less_equal);
Helper(higher, val, std::greater_equal);
@RemyLebeau 啊,我现在明白了。该注释中的Helper(lower, val, [](int a, int b) return a <= b; )
部分实际上是显示函数的调用方式。
【参考方案1】:
您可以执行以下操作:
class
public:
void func(const int val, const bool flag)
std::stack<int> *st;
bool (*compare)(int, int);
if (flag)
st = &lower;
compare = [](int a, int b) return a <= b; ;
else
st = &higher;
compare = [](int a, int b) return a >= b; ;
while (!st->empty() && compare(val, st->top()))
// do a bunch of stuff with *st
private:
std::stack<int> lower;
std::stack<int> higher;
另外,使用助手当然也可以:
class
public:
void func(const int val, const bool flag)
if (flag)
func_helper(lower, val, std::less_equal);
else
func_helper(higher, val, std::greater_equal);
private:
std::stack<int> lower;
std::stack<int> higher;
template<typename Comparer>
void func_helper(stack<int> &st, const int val, Comparer compare)
while (!st.empty() && compare(val, st.top()))
// do a bunch of stuff with st
【讨论】:
【参考方案2】:这样的事情怎么样
class
public:
void func(const int val, const bool flag)
int sign = 1;
std::stack<int>* higher_or_lower = &higher;
if(flag)
higher_or_lower = &lower;
sign = -1;
while(!higher_or_lower->empty() && sign*val >= sign*higher_or_lower->top())
// do a bunch of stuff with higher_or_lower
private:
std::stack<int> lower;
std::stack<int> higher;
higher_or_lower
涵盖两个堆栈,sign
负责处理小于与大于。
【讨论】:
这个标志的想法很有趣,但我想也许它对某人来说不太清楚?当然更短!【参考方案3】:或者更紧凑一点:
class C
public:
void func(const int val, const bool flag)
const std::stack<int>* st[] = &lower, &higher;
bool (*compare[])(int, int) = [](int a, int b) return a <= b; , [](int a, int b) return a >= b; ;
while (!st[flag]->empty() && compare[flag](val, st[flag]->top()))
// do a bunch of stuff with *st
private:
std::stack<int> lower;
std::stack<int> higher;
;
【讨论】:
以上是关于如何在不复制太多代码的情况下重构此代码?的主要内容,如果未能解决你的问题,请参考以下文章
重构 PHP OOP - 如何在不传递参数的情况下获取对象?
如何在不重构的情况下发布两个具有相同源代码但不同包名的 android 应用程序
我的客户如何在不访问源代码的情况下上传 ios 应用程序? [复制]