# Заміна алгоритму

Також відомий як: 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. Коли всі тести почнуть проходити, остаточно видаліть старий алгоритм.