Також відомий як 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 (array("Don", "John", "Kent") as $needle) {
    $id = array_search($needle, $people);
    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"]
    for i in range(len(people)):
        if people[i] in candidates:
            return people[i]
    return ""

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

  1. Поетапний рефакторинг – не єдиний варіант поліпшити програму. Іноді ви зустрічаєтеся з таким нагромадженням проблем в методі, що його набагато простіше переписати наново. З іншого боку, ви могли знайти алгоритм, який куди простіше та ефективніше за поточний. В цьому випадку потрібно просто замінити старий алгоритм новим.

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

  3. Вимоги до роботи програми можуть змінитися настільки сильно, що старий алгоритм неможливо просто «допиляти» до відповідності їм.

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

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

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

  3. Якщо результати виявилися різними, поверніть стару реалізацію і порівняйте ще раз результати. З'ясуйте, чому результати не співпадають. Іноді буває, що причиною стають помилки в старому алгоритмі, але здебільшого — не працює щось у новому.

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

Замучились читати?

Збігайте за подушкою, в нас тут контенту на 7 годин читання.

Або спробуйте наш новий інтерактивний курсу. Він набагато цікавіший за банальний тест.

Дізнатися більше...