Autumn SALE

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

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