Тестирование - Идеальный код на PHP и Javascript

Лекция



Это окончание невероятной информации про идеальный код.

...

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

Плохой:

class  DOMTraverser  { 
  конструктор ( настройки )  { 
    это . settings  =  настройки ; 
    это . setup ( ) ; 
  }

  setup ( )  { 
    это . rootNode  =  это . настройки . rootNode ; 
    это . настройки . animationModule . setup ( ) ; 
  }

  traverse ( )  { 
    // ... 
  } 
}

const  $  =  new  DOMTraverser ( { 
  rootNode : document . getElementsByTagName ( "body" ) , 
  animationModule ( )  { }  // В большинстве случаев 
  анимация при перемещении не требуется. // ... 
} ) ;

Хороший:

class  DOMTraverser  { 
  конструктор ( настройки )  { 
    это . settings  =  настройки ; 
    это . параметры  =  настройки . варианты ; 
    это . setup ( ) ; 
  }

  setup ( )  { 
    это . rootNode  =  это . настройки . rootNode ; 
    это . setupOptions ( ) ; 
  }

  setupOptions ( )  { 
    if  ( this . options . animationModule )  { 
      // ... 
    } 
  }

  traverse ( )  { 
    // ... 
  } 
}

const  $  =  новый  DOMTraverser ( { 
  rootNode : document . getElementsByTagName ( "body" ) , 
  параметры : { 
    animationModule ( )  { } 
  } 
} ) ;

Идеальный  код на PHP и Javascript

Принцип инверсии зависимостей (DIP)

В этом принципе говорится о двух важных вещах:

  1. Модули высокого уровня не должны зависеть от модулей низкого уровня. Оба должны зависеть от абстракций.
  2. Абстракции не должны зависеть от деталей. Детали должны зависеть от абстракций.

Сначала это может быть трудно понять, но если вы работали с AngularJS, вы видели реализацию этого принципа в форме внедрения зависимостей (DI). Хотя это не идентичные концепции, DIP не дает высокоуровневым модулям знать подробности своих низкоуровневых модулей и настраивать их. Это можно сделать с помощью DI. Огромным преимуществом этого является то, что уменьшается связь между модулями. Связывание - это очень плохой шаблон разработки, потому что он затрудняет рефакторинг вашего кода.

Как указывалось ранее, у JavaScript нет интерфейсов, поэтому зависящие от него абстракции являются неявными контрактами. То есть методы и свойства, которые объект / класс предоставляет другому объекту / классу. В приведенном ниже примере неявный контракт заключается в том, что любой модуль запроса для объекта InventoryTrackerбудет иметьrequestItems метод.

Плохой:

класс  InventoryRequester  { 
  конструктор ( )  { 
    это . REQ_METHODS  =  [ "HTTP" ] ; 
  }

  requestItem ( элемент )  { 
    // ... 
  } 
}

class  InventoryTracker  { 
  конструктор ( элементы )  { 
    это . items  =  items ;

    // ПЛОХО: мы создали зависимость от конкретной реализации запроса. 
    // Нам просто нужно, чтобы requestItems зависели от метода запроса: `request` 
    this . Requester  =  новый  InventoryRequester ( ) ; 
  }

  requestItems ( )  { 
    это . предметы . Foreach ( пункт  =>  { 
      этот . запрашивающая . requestItem ( пункт ) ; 
    } ) ; 
  } 
}

const  inventoryTracker  =  new  InventoryTracker ( [ "яблоки" ,  "бананы" ] ) ; 
inventoryTracker . requestItems ( ) ;

Хороший:

class  InventoryTracker  { 
  конструктор ( элементы ,  инициатор запроса )  { 
    this . items  =  items ; 
    это . запрашивающий  =  запрашивающий ; 
  }

  requestItems ( )  { 
    это . предметы . Foreach ( пункт  =>  { 
      этот . запрашивающая . requestItem ( пункт ) ; 
    } ) ; 
  } 
}

class  InventoryRequesterV1  { 
  конструктор ( )  { 
    это . REQ_METHODS  =  [ "HTTP" ] ; 
  }

  requestItem ( элемент )  { 
    // ... 
  } 
}

class  InventoryRequesterV2  { 
  конструктор ( )  { 
    это . REQ_METHODS  =  [ "WS" ] ; 
  }

  requestItem ( элемент )  { 
    // ... 
  } 
}

// Построив наши зависимости извне и внедрив их, мы можем легко 
// заменить наш модуль запроса на новый модный, использующий WebSockets. 
const  inventoryTracker  =  new  InventoryTracker ( 
  [ "яблоки" ,  "бананы" ] , 
  new  InventoryRequesterV2 ( ) 
) ; 
inventoryTracker . requestItems ( ) ;

Идеальный  код на PHP и Javascript

Тестирование

Тестирование важнее доставки. Если у вас нет тестов или их недостаточно, то каждый раз, когда вы отправляете код, вы не будете уверены, что ничего не сломали. Решение о том, что составляет адекватную сумму, зависит от вашей команды, но наличие 100% покрытия (всех утверждений и ветвей) - это то, как вы достигнете очень высокой уверенности и спокойствия разработчика. Это означает, что помимо отличной среды тестирования вам также необходимо использовать хороший инструмент покрытия .

Нет оправдания тому, чтобы не писать тесты. Существует множество хороших фреймворков для тестирования JS , так что выберите ту, которую предпочитает ваша команда. Когда вы найдете тот, который работает для вашей команды, постарайтесь всегда писать тесты для каждой новой функции / модуля, которые вы вводите. Если ваш предпочтительный метод - разработка через тестирование (TDD), это прекрасно, но главное - просто убедиться, что вы достигли своих целей охвата, прежде чем запускать какую-либо функцию или проводить рефакторинг существующей.

Единая концепция на тест

Плохой:

импортировать  assert  из  "assert" ;

описать ( "MomentJS" ,  ( )  =>  { 
  it ( "обрабатывает границы дат" ,  ( )  =>  { 
    let  date ;

    date  =  new  MomentJS ( "01.01.2015" ) ; 
    дата . addDays ( 30 ) ; 
    утверждать . равно ( «31.01.2015» ,  дата ) ;

    date  =  new  MomentJS ( "01.02.2016" ) ; 
    дата . addDays ( 28 ) ; 
    утверждать . равно ( «29.02.2016» ,  дата ) ;

    date  =  new  MomentJS ( "01.02.2015" ) ; 
    дата . addDays ( 28 ) ; 
    утверждать . равно ( «01.03.2015» ,  дата ) ; 
  } ) ; 
} ) ;

Хороший:

импортировать  assert  из  "assert" ;

описать ( "MomentJS" ,  ( )  =>  { 
  it ( "обрабатывает 30-дневные месяцы" ,  ( )  =>  { 
    const  date  =  new  MomentJS ( "1/1/2015" ) ; 
    date . addDays ( 30 ) ; 
    assert . равный ( "31.01.2015" ,  дата ) ; 
  } ) ;

  it ( "обрабатывает високосный год" ,  ( )  =>  { 
    const  date  =  new  MomentJS ( "2/1/2016" ) ; 
    date . addDays ( 28 ) ; 
    assert . equal ( "29.02.2016" ,  date ) ; 
  } ) ;

  it ( "обрабатывает невисокосный год" ,  ( )  =>  { 
    const  date  =  new  MomentJS ( "2/1/2015" ) ; 
    date . addDays ( 28 ) ; 
    assert . equal ( "03/01/2015" ,  date ) ; 
  } ) ; 
} ) ;

Идеальный  код на PHP и Javascript

Параллелизм

Используйте обещания, а не обратные вызовы

Обратные вызовы не являются чистыми и вызывают чрезмерное количество вложений. В ES2015 / ES6 обещания являются встроенным глобальным типом. Используй их!

Плохой:

импорт  {  получить  }  из  "запроса" ; 
import  {  writeFile  }  из  "fs" ;

get ( 
  "https://en.wikipedia.org/wiki/Robert_Cecil_Martin" , 
  ( requestErr ,  response ,  body )  =>  { 
    if  ( requestErr )  { 
      console . error ( requestErr ) ; 
    }  else  { 
      writeFile ( "article.html" ,  тело ,  writeErr  =>  { 
        если  ( writeErr )  { 
          консоли . ошибка ( writeErr ) ;
        }  else  { 
          console . log ( "Файл записан" ) ; 
        } 
      } ) ; 
    } 
  } 
) ;

Хороший:

импорт  {  получить  }  из  "запрос-обещание" ; 
import  {  writeFile  }  из  "fs-extra" ;

получить ( "https://en.wikipedia.org/wiki/Robert_Cecil_Martin" ) 
  . then ( body  =>  { 
    return  writeFile ( "article.html" ,  body ) ; 
  } ) 
  . then ( ( )  =>  { 
    console . log ( "Файл записан" ) ; 
  } ) 
  . catch ( err  =>  { 
    console . error ( err ) ; 
  } ) ;

Идеальный  код на PHP и Javascript

Async / Await даже чище, чем обещания

Promises - очень чистая альтернатива обратным вызовам, но ES2017 / ES8 предлагает async и await, которые предлагают еще более чистое решение. Все, что вам нужно, это функция с префиксом в виде asyncключевого слова, и тогда вы можете писать свою логику императивно без thenцепочки функций. Используйте это, если можете воспользоваться функциями ES2017 / ES8 уже сегодня!

Плохой:

импорт  {  получить  }  из  "запрос-обещание" ; 
import  {  writeFile  }  из  "fs-extra" ;

получить ( "https://en.wikipedia.org/wiki/Robert_Cecil_Martin" ) 
  . then ( body  =>  { 
    return  writeFile ( "article.html" ,  body ) ; 
  } ) 
  . then ( ( )  =>  { 
    console . log ( "Файл записан" ) ; 
  } ) 
  . catch ( err  =>  { 
    console . error ( err ) ; 
  } ) ;

Хороший:

импорт  {  получить  }  из  "запрос-обещание" ; 
import  {  writeFile  }  из  "fs-extra" ;

асинхронная  функция  getCleanCodeArticle ( )  { 
  попробуйте  { 
    const  body  =  await  get ( 
      "https://en.wikipedia.org/wiki/Robert_Cecil_Martin" 
    ) ; 
    Await  WriteFile ( "article.html" ,  тела ) ; 
    консоль . log ( "Файл записан" ) ; 
  }  catch  ( err )  { 
    console . ошибка ( ERR ) ; 
  } 
}

getCleanCodeArticle ( )

Идеальный  код на PHP и Javascript

Обработка ошибок

Выброшенные ошибки - это хорошо! Они означают, что среда выполнения успешно определила, когда что-то в вашей программе пошла не так, и сообщает вам об этом, останавливая выполнение функции в текущем стеке, убивая процесс (в Node) и уведомляя вас в консоли с трассировкой стека.

Не игнорируйте обнаруженные ошибки

Ничего не делать с обнаруженной ошибкой, это не дает вам возможности исправить эту ошибку или отреагировать на нее. Регистрация ошибки в console ( console.log) не намного лучше, поскольку часто она может потеряться в море вещей, напечатанных на консоли. Если вы заключите какой-либо бит кода в a, try/catchэто означает, что вы думаете, что здесь может произойти ошибка, и поэтому у вас должен быть план или создать путь кода на случай, когда она произойдет.

Плохой:

попробуйте  { 
  functionThatMightThrow ( ) ; 
}  catch  ( ошибка )  { 
  console . журнал ( ошибка ) ; 
}

Хороший:

попробуйте  { 
  functionThatMightThrow ( ) ; 
}  catch  ( error )  { 
  // Один вариант (более шумный, чем console.log): 
  console . error ( ошибка ) ; 
  // Другой вариант: 
  notifyUserOfError ( error ) ; 
  // Другой вариант: 
  reportErrorToService ( error ) ; 
  // ИЛИ сделайте все три! 
}

Не игнорируйте отклоненные обещания

По той же причине не следует игнорировать ошибки, обнаруженные в файлах try/catch.

Плохой:

getdata ( ) 
  . затем ( данные  =>  { 
    functionThatMightThrow ( data ) ; 
  } ) 
  . catch ( error  =>  { 
    console . log ( error ) ; 
  } ) ;

Хороший:

getdata ( ) 
  . затем ( данные  =>  { 
    functionThatMightThrow ( data ) ; 
  } ) 
  . catch ( error  =>  { 
    // Один вариант (более шумный, чем console.log): 
    console . error ( error ) ; 
    // Другой вариант: 
    notifyUserOfError ( error ) ; 
    // Другой вариант: 
    reportErrorToService ( error ) ; 
    // ИЛИ сделать все три! 
  } ) ;

Идеальный  код на PHP и Javascript

Форматирование

Форматирование субъективно. Как и во многих других правилах, здесь нет жесткого правила, которому вы должны следовать. Главное - НЕ СПОРЯТЬ по поводу форматирования. Есть масса инструментов для автоматизации этого. Используйте один! Споры по поводу форматирования для инженеров - пустая трата времени и денег.

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

Используйте последовательные заглавные буквы

JavaScript не типизирован, поэтому использование заглавных букв многое говорит о ваших переменных, функциях и т. Д. Эти правила субъективны, поэтому ваша команда может выбирать все, что захочет. Дело в том, что независимо от того, что вы все выберете, просто будьте последовательны.

Плохой:

const  DAYS_IN_WEEK  =  7 ; 
const  daysInMonth  =  30 ;

const  songs  =  [ "Back In Black" ,  "Stairway to Heaven" ,  "Hey Jude" ] ; 
const  Artists  =  [ "ACDC" ,  "Led Zeppelin" ,  "Битлз" ] ;

function  eraseDatabase ( )  { } 
функция  restore_database ( )  { }

класс  животных  { } 
класс  Альпака  { }

Хороший:

const  DAYS_IN_WEEK  =  7 ; 
const  DAYS_IN_MONTH  =  30 ;

const  SONGS  =  [ «Снова в черном» ,  «Лестница в небеса» ,  «Привет, Джуд» ] ; 
const  ARTISTS  =  [ "ACDC" ,  "Led Zeppelin" ,  "Битлз" ] ;

function  eraseDatabase ( )  { } 
function  restoreDatabase ( )  { }

class  Animal  { } 
class  Alpaca  { }

Идеальный  код на PHP и Javascript

Вызывающие и вызываемые функции должны быть рядом

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

Плохой:

class  PerformanceReview  { 
  конструктор ( сотрудник )  { 
    это . сотрудник  =  сотрудник ; 
  }

  lookupPeers ( )  { 
    return  db . поиск ( этот . сотрудник ,  «сверстники» ) ; 
  }

  lookupManager ( )  { 
    вернуть  db . поиск ( этот . сотрудник ,  «менеджер» ) ; 
  }

  getPeerReviews ( )  { 
    const  peers  =  this . lookupPeers ( ) ; 
    // ... 
  }

  perfReview ( )  { 
    это . getPeerReviews ( ) ; 
    это . getManagerReview ( ) ; 
    это . getSelfReview ( ) ; 
  }

  getManagerReview ( )  { 
    const  manager  =  это . lookupManager ( ) ; 
  }

  getSelfReview ( )  { 
    // ... 
  } 
}

const  review  =  new  PerformanceReview ( сотрудник ) ; 
обзор . perfReview ( ) ;

Хороший:

class  PerformanceReview  { 
  конструктор ( сотрудник )  { 
    это . сотрудник  =  сотрудник ; 
  }

  perfReview ( )  { 
    это . getPeerReviews ( ) ; 
    это . getManagerReview ( ) ; 
    это . getSelfReview ( ) ; 
  }

  getPeerReviews ( )  { 
    const  peers  =  this . lookupPeers ( ) ; 
    // ... 
  }

  lookupPeers ( )  { 
    return  db . поиск ( этот . сотрудник ,  «сверстники» ) ; 
  }

  getManagerReview ( )  { 
    const  manager  =  это . lookupManager ( ) ; 
  }

  lookupManager ( )  { 
    вернуть  db . поиск ( этот . сотрудник ,  «менеджер» ) ; 
  }

  getSelfReview ( )  { 
    // ... 
  } 
}

const  review  =  new  PerformanceReview ( сотрудник ) ; 
обзор . perfReview ( ) ;

Идеальный  код на PHP и Javascript

Комментарии

Комментируйте только те вещи, которые имеют сложную бизнес-логику.

Комментарии - это извинение, а не требование. Хороший код в основном сам документирует.

Плохой:

function  hashIt ( data )  { 
  // Хеш 
  let  hash  =  0 ;

  // Длина строки 
  const  length  =  data . длина ;

  // Цикл по каждому символу в данных 
  for  ( let  i  =  0 ;  i  <  length ;  i ++ )  { 
    // Получить код символа. 
    const  char  =  данные . charCodeAt ( i ) ; 
    // Создаем хэш 
    hash  =  ( hash  <<  5 )  -  hash  +  char ; 
    // Преобразование в 32-битный целочисленный 
    хэш  & =  hash ; 
  } 
}

Хороший:

функция  hashIt ( данные )  { 
  пусть  hash  =  0 ; 
  длина константы  = данные . длина ;  

  for  ( пусть  я  =  0 ;  я  <  длина ;  я ++ )  { 
    const  char  =  data . charCodeAt ( i ) ; 
    hash  =  ( hash  <<  5 )  -  хеш  +  символ ;

    // Преобразование в 32-битный целочисленный 
    хэш  & =  hash ; 
  } 
}

Идеальный  код на PHP и Javascript

Не оставляйте закомментированный код в своей кодовой базе

Контроль версий существует не просто так. Оставьте старый код в своей истории.

Плохой:

doStuff ( ) ; 
// doOtherStuff (); 
// doSomeMoreStuff (); 
// doSoMuchStuff ();

Хороший:

doStuff ( ) ;

Идеальный  код на PHP и Javascript

Нет комментариев в журнале

Помните, используйте контроль версий! Нет необходимости в мертвом коде, закомментированном коде и особенно в журнальных комментариях. Используйте, git logчтобы получить историю!

Плохой:

/ ** 
* 2016-12-20: Удалены монады, их не понял (RM) 
* 2016-10-01: Улучшено с использованием специальных монад (JP) 
* 2016-02-03: Удалена проверка типов (LI) 
* 2015-03-14: Добавлено объединение с проверкой типов (JR) 
* / 
function  comb ( a ,  b )  { 
  return  a  +  b ; 
}

Хороший:

функция  comb ( a ,  b )  { 
  return  a  +  b ; 
}

Идеальный  код на PHP и Javascript

Избегайте позиционных маркеров

Обычно они просто добавляют шума. Пусть имена функций и переменных вместе с правильным отступом и форматированием придают визуальную структуру вашему коду.

Плохой:

////////////////////////////////////////////////// ////////////////////////////// 
// Создание экземпляра модели области 
/////////////// ////////////////////////////////////////////////// /////////////// 
$ scope . model  =  { 
  меню : "foo" , 
  nav : "bar" 
} ;

////////////////////////////////////////////////// ////////////////////////////// 
// Настройка действия 
//////////////// ////////////////////////////////////////////////// ////////////// 
const  actions  =  function ( )  { 
  // ... 
} ;

Хороший:

$ scope . model  =  { 
  меню : "foo" , 
  nav : "bar" 
} ;

const  actions  =  function ( )  { 
  // ... 
} ;

Надеюсь, эта статья была вам полезна! Я что-то упустил? Поделитесь вашим опытом!

Исследование, описанное в статье про идеальный код, подчеркивает ее значимость в современном мире. Надеюсь, что теперь ты понял что такое идеальный код и для чего все это нужно, а если не понял, или есть замечания, то не стесняйся, пиши или спрашивай в комментариях, с удовольствием отвечу. Для того чтобы глубже понять настоятельно рекомендую изучить всю информацию из категории Разработка программного обеспечения и информационных систем

Продолжение:


Часть 1 Идеальный код на PHP и Javascript
Часть 2 1. Комментарии и Документация - Идеальный код на PHP и
Часть 3 Объекты и структуры данных - Идеальный код на PHP и
Часть 4 Тестирование - Идеальный код на PHP и Javascript

создано: 2021-09-21
обновлено: 2026-07-18
0



Помог ли вам этот ответ?
Нажмите оценку и напишите коротко почему. Так мы сможем сделать следующие ответы точнее и полезнее.
Насколько вы довольны ответом?
Ваш отзыв напрямую влияет на качество следующих подсказок и ответов.


Поделиться:
Пожаловаться

Найди готовое или заработай

С нашими удобными сервисами без комиссии*

Как это работает? | Узнать цену?

Найти исполнителя
$0 / весь год.
  • У вас есть задание, но нет времени его делать
  • Вы хотите найти профессионала для выполнения задания
  • Возможно применение функции гаранта на сделку
  • Приоритетная поддержка
  • идеально подходит для студентов, у которых нет времени для решения заданий
Готовое решение
$0 / весь год.
  • Вы можете продать (как исполнитель) или купить (как заказчик) готовое решение
  • Вам предоставят готовое решение
  • Будет предоставлено в минимальные сроки т.к. задание уже готовое
  • Вы получите базовую гарантию 8 дней
  • Вы можете заработать на материалах
  • подходит как для студентов так и для преподавателей
Я исполнитель
$0 / весь год.
  • Вы профессионал своего дела
  • У вас есть опыт и желание зарабатывать
  • Вы хотите помочь в решении задач или написании работ
  • Возможно применение функции гаранта на сделку
  • подходит для опытных студентов так и для преподавателей

Комментарии

Оставить комментарий

Если у вас есть какое-либо предложение, идея, благодарность или комментарий, не стесняйтесь писать. Мы очень ценим отзывы и рады услышать ваше мнение.
To reply

Лекции и учебник по "Разработка программного обеспечения и информационных систем"

Термины: Разработка программного обеспечения и информационных систем