# Замена алгоритма

Также известен как: Substitute Algorithm

### Проблема

Вы хотите заменить существующий алгоритм другим?

### Решение

Замените тело метода, реализующего старый алгоритм, новым алгоритмом.

До
String foundPerson(String[] people){
for (int i = 0; i < people.length; i++) {
if (people[i].equals("Don")){
return "Don";
}
if (people[i].equals("John")){
return "John";
}
if (people[i].equals("Kent")){
return "Kent";
}
}
return "";
}
После
String foundPerson(String[] people){
List candidates =
Arrays.asList(new String[] {"Don", "John", "Kent"});
for (int i=0; i < people.length; i++) {
if (candidates.contains(people[i])) {
return people[i];
}
}
return "";
}
До
string FoundPerson(string[] people)
{
for (int i = 0; i < people.Length; i++)
{
if (people[i].Equals("Don"))
{
return "Don";
}
if (people[i].Equals("John"))
{
return "John";
}
if (people[i].Equals("Kent"))
{
return "Kent";
}
}
return String.Empty;
}
После
string FoundPerson(string[] people)
{
List<string> candidates = new List<string>() {"Don", "John", "Kent"};

for (int i = 0; i < people.Length; i++)
{
if (candidates.Contains(people[i]))
{
return people[i];
}
}

return String.Empty;
}
До
function foundPerson(array \$people){
for (\$i = 0; \$i < count(\$people); \$i++) {
if (\$people[\$i] === "Don") {
return "Don";
}
if (\$people[\$i] === "John") {
return "John";
}
if (\$people[\$i] === "Kent") {
return "Kent";
}
}
return "";
}
После
function foundPerson(array \$people){
foreach (["Don", "John", "Kent"] as \$needle) {
\$id = array_search(\$needle, \$people, true);
if (\$id !== false) {
return \$people[\$id];
}
}
return "";
}
До
def foundPerson(people):
for i in range(len(people)):
if people[i] == "Don":
return "Don"
if people[i] == "John":
return "John"
if people[i] == "Kent":
return "Kent"
return ""
После
def foundPerson(people):
candidates = ["Don", "John", "Kent"]
return people if people in candidates else ""
До
foundPerson(people: string[]): string{
for (let person of people) {
if (person.equals("Don")){
return "Don";
}
if (person.equals("John")){
return "John";
}
if (person.equals("Kent")){
return "Kent";
}
}
return "";
}
После
foundPerson(people: string[]): string{
let candidates = ["Don", "John", "Kent"];
for (let person of people) {
if (candidates.includes(person)) {
return person;
}
}
return "";
}

### Причины рефакторинга

1. Поэтапный рефакторинг — не единственный способ улучшить программу. Иногда вы сталкиваетесь с таким нагромождением проблем в методе, что его гораздо проще переписать заново. С другой стороны, вы могли найти алгоритм, который куда проще и эффективнее текущего. В этом случае надо просто заменить старый алгоритм новым.

2. С течением времени ваш алгоритм может оказаться включен в набор известной библиотеки или фреймворка, и вы можете пожелать избавиться от собственной реализации, чтобы облегчить себе поддержку программы.

3. Требования к работе программы могут измениться настолько сильно, что старый алгоритм невозможно просто «допилить» до соответствия им.

### Порядок рефакторинга

1. Убедитесь, что вы по максимуму упростили текущий алгоритм. Перенесите несущественный код в другие методы с помощью извлечения метода. Чем меньше «движущихся частей» останется в исходном алгоритме, тем проще будет его заменить.

2. Создайте ваш новый алгоритм в новом методе. Замените старый алгоритм новым и запустите тесты программы.

3. Если результаты не сходятся, верните старую реализацию и сравните результаты. Выясните, почему результаты не совпадают. Нередко, причиной могут быть ошибки в старом алгоритме, но с большей вероятностью не работает что-то в новом.

4. Когда все тесты начнут проходить, окончательно удалите старый алгоритм.