У меня есть следующие два метода, которые (как Вы видите) похожи в большинстве его операторов за исключением одного (см. ниже для деталей),
unsigned int CSWX::getLineParameters(const SURFACE & surface, vector<double> & params)
{
VARIANT varParams;
surface->getPlaneParams(varParams); // this is the line of code that is different
SafeDoubleArray sdParams(varParams);
for( int i = 0 ; i < sdParams.getSize() ; ++i )
{
params.push_back(sdParams[i]);
}
if( params.size() > 0 ) return 0;
return 1;
}
unsigned int CSWX::getPlaneParameters(const CURVE & curve, vector<double> & params)
{
VARIANT varParams;
curve->get_LineParams(varParams); // this is the line of code that is different
SafeDoubleArray sdParams(varParams);
for( int i = 0 ; i < sdParams.getSize() ; ++i )
{
params.push_back(sdParams[i]);
}
if( params.size() > 0 ) return 0;
return 1;
}
Есть ли какая-либо техника, которую я могу использовать для перемещения общих строк кода этих двух методов к отдельному методу, который можно было назвать от этих двух изменений - ИЛИ - возможно комбинируют эти два метода к отдельному методу?
Следующее является ограничениями:
Я знаю, что следующее могло (возможно?) быть реализованным как решения, но действительно надеюсь, что существует лучшее решение:
Следующее не является ограничением, но было бы требованием из-за моего сопротивления товарищей по команде:
На ум приходит пара идей, но вот то, что я думаю, было бы лучше всего:
namespace detail
{
void getParameters(const SURFACE& surface, VARIANT& varParams)
{
surface->getPlaneParams(varParams);
}
void getParameters(const CURVE& curve, VARIANT& varParams)
{
curve->get_LineParams(varParams);
}
}
template <typename T>
unsigned int getParameters(const T& curve, vector<double> & params)
{
VARIANT varParams;
detail::getParameters(curve, varParams);
SafeDoubleArray sdParams(varParams);
for( int i = 0 ; i < sdParams.getSize() ; ++i )
{
params.push_back(sdParams[i]);
}
return params.size() != 0;
}
Вы делегируете задачу получения параметров какой-либо другой перегруженной функции. Просто добавьте такие функции для каждого типа, который у вас есть. (Обратите внимание, я упростил ваше выражение возврата.)
Почему бы просто не передать ВАРИАНТ varParams
в качестве параметра функции вместо КРИВОЙ
или SURFACE
?
unsigned int CSWX::getParameters(VARIANT varParams, vector<double> & params)
{
SafeDoubleArray sdParams(varParams);
for( int i = 0 ; i < sdParams.getSize() ; ++i )
{
params.push_back(sdParams[i]);
}
if( params.size() > 0 ) return 0;
return 1;
}
unsigned int CSWX::getPlaneParameters(const CURVE & curve, vector<double> & params)
{
VARIANT varParams;
curve->get_LineParams(varParams); // this is the line of code that is different
return getParameters( varParams, params );
}
Вы также можете рассмотреть (если возможно) создание этих шаблонов методов и получить output_iterator
в качестве параметра вместо вектора
. Таким образом, ваш код не зависит от типа используемой коллекции.
Метод извлечения. Все после строк, которые вы отметили как разные, идентично - поэтому извлеките их как метод, который вызывается из обоих ваших исходных методов.
Вместо передачи SURFACE или CURVE передайте ссылку на базовый класс, а также указатель на функцию метода. Тогда вызов функции surface-> getLine_parameters или curve-> getPlaneParamters будет заменен на (shape -> * getParamters) (varParams);
typedef void Baseclass::*ParamGetter(VARIANT varParams);
unsigned int CSWX::getLineParameters(const Baseclass & geometry, ParamGetter getParams
vector<double> & params)
{
VARIANT varParams;
(geometry->*getParams)(varParams); // this is the line of code that is different
SafeDoubleArray sdParams(varParams);
for( int i = 0 ; i < sdParams.getSize() ; ++i )
{
params.push_back(sdParams[i]);
}
if( params.size() > 0 ) return 0;
return 1;
}
Macro! Обычно это не лучшее решение (это макрос) и, вероятно, не самое лучшее в этом, но оно сработает.
macro_GetDakine_Params(func)
VARIANT varParams; \
curve->##func(varParams); // this is the line of code that is different \
SafeDoubleArray sdParams(varParams); \
for( int i = 0 ; i < sdParams.getSize() ; ++i ) \
{ \
params.push_back(sdParams[i]); \
} \
if( params.size() > 0 ) return 0; \
return 1; \
unsigned int CSWX::getPlaneParameters(const CURVE & curve, vector<double> & params)
{
macro_GetDakine_Params(getPlaneParams)
}
unsigned int CSWX::getLineParameters(const CURVE & curve, vector<double> & params)
{
macro_GetDakine_Params(getLineParams)
}