Я не хочу повторяться (СУХОЙ), но у меня не может быть ни одного куска кода.Например, вот код, повторенный 3 раза с одной и той же ошибкой:
class StarWars : Movie
{
//Calculate "base ^ exponent"
public float Power(float base, float exponent)
{
return (base * exponent);
}
}
class Customer: Object
{
//Calculate "base ^ exponent"
public float Exponential(float base, float exponent)
{
return (base ^ exponent);
}
}
class Student: Person
{
//Calculate "base ^ exponent"
public float CalculateExpoential(float base, float exponent)
{
return CalculateExponential(2.7182818, exponent * Ln(base));
}
}
Теперь в идеале я бы извлек эту общую функцию в собственный помощник где-нибудь:
class LibraryOfHelperCode
{
public static float Exponentiation(float base, float exponent)
{
return Exp(2.71828183, base * Ln(exponent));
}
}
И преобразовал существующийкод для его использования:
class StarWars : Movie
{
//Calculate "base ^ exponent"
public float Power(float base, float exponent)
{
return LibraryOfHelperCode.Exponentiation(base, exponent);
}
}
class Customer: Object
{
//Calculate "base ^ exponent"
public float Exponential(float base, float exponent)
{
return LibraryOfHelperCode.Exponentiation(base, exponent);
}
}
class Student: Person
{
//Calculate "base ^ exponent"
public float CalculateExpoential(float base, float exponent)
{
return LibraryOfHelperCode.Exponentiation(base, exponent);
}
}
Значение в том, что теперь я извлек повторный код из
- Мощность
- Экспоненциальная
- CalculateExpoential
в одну функцию.Это означает, что если есть какие-либо ошибки, их нужно исправить только один раз.Что хорошо в этом случае, потому что - это ошибка:
public float CalculateExpoential(float base, float exponent)
{
//19971012: Oops, should be natrual log of base, not exponent
return Exp(2.71828183, exponent * Ln(base));
}
и несколько лет спустя:
public float CalculateExpoential(float base, float exponent)
{
//19990321: Oops, need to handle when exponent is zero
if (exponent == 0)
return 1.0;
//19971012: Oops, should be natrual log of base, not exponent
return Exp(2.71828183, exponent * Ln(base));
}
и позже:
public float CalculateExpoential(float base, float exponent)
{
//19990321: Oops, need to handle when exponent is zero
if (exponent == 0)
return 1.0;
//20040523: Another special case
if (Base = 0.0) && (Exponent > 0.0) then
return 0.0; // 0**n = 0, n > 0
//19971012: Oops, should be natrual log of base, not exponent
return Exp(2.71828183, exponent * Ln(base));
}
и наконец:
public float CalculateExpoential(float base, float exponent)
{
//20101027: Microsoft just release a method in .NET framework 4.0 that does
//what we need. Use it:
return Math.Pow(base, exponent);
}
И каждый получает исправления.С другой стороны, я не могу гарантировать, что любое из этих исправлений инкремента не сломает существующий код.
Представьте себе , который звонил парень:
char ps = Math.Trunc(Exponential(ProblemSize, ProblemComplexity));
и никогда не ожидал, что значение будет больше 128. Он ошибся.И хотя код был неправильным все это время: случилось сработало.
Теперь я пришел и исправил вещи, и вдруг кодпроисходит сбой из-за переполнения и / или переноса.
Проблема, с которой я сталкиваюсь сегодня, заключается в том, что изменение в общем коде DRY влияет везде, где он используется.Единственное приемлемое (политическое) решение - сохранить копию библиотечного класса для каждого исполняемого файла / модуля / пространства имен / класса, который его использует.
Отмена любой СУХОСТИ.
Есть ли выход?этого беспорядка?Когда я не могу повторить себя, но продолжаю получать исправления и улучшения по мере их добавления в один код DRY?
я имею в виду ... должен ли я иметь общий код, но ветвить его при каждом выпуске?Но проблема в том, что никто не хочет, чтобы код каждого был обратно интегрирован.