Upload
devpoint-kyiv
View
324
Download
1
Embed Size (px)
Citation preview
Признаки плохого кода и как с ним бороться в PHP проектах
class Speaker extends DevPointSpeaker{
private $_name = “Панаскин Денис”;private $_company = “Varteq”;private $_position = “Directory of Technology”;private $_site = “http://varteq.com”;private $_email = “[email protected]”;
}
$currentSpeaker = new Speaker();try {
$currentSpeaker.start();} catch (SpeakerException $exp) {
Logger.error(“Shit happens”, $exp);}
Любой дурак может написать код, понятный компьютеру. Хороший программист пишет код, понятный человеку.
- Мартин Фаулер
Бывает ли идеальный код?
КОНЕЧНО!!!
НЕТ :)
Когда и как наносятся удары по качеству кода?
*
*
*
*
*
*
*
*
*
*
Когда хардкод оправдан?
Хардкод “по-модному”: Ad-hoc решение
Ad-hoc решение‣ Принять факт что хардкод неизбежен
‣ Принять факт что хардкод неизбежен‣ Хорошо документировать костыли
Ad-hoc решение
‣ Принять факт что хардкод неизбежен‣ Хорошо документировать костыли ‣ Комментарии к Ad-hoc коду должны отвечать на вопрос
“почему” и “зачем”, а не что делает код!
Ad-hoc решение
Часто встречающиеся проблемы в коде
SQL в бизнес логике
HTML в коде
Запросы в циклах
Наличие цифр в именах переменных, классов и ключах
$slide1 = ‘’;$slide2 = ‘’;$customer1 = ‘’;
*
Большое количество статических методов и их вызовов
Если префиксы и постфиксы в именах классов “прыгают”
ProductItemItemProduct
*
Злоупотребление паттернами
Большие классы и длинные методы
Copy - Past кода
Большое количество вложенных циклов и if’ов
if (condition1) { ... if (condition2) { ... for ($i = 0; $i < 10; $i++) { ... if (condition4) {
if (condition5) { foreach ($products as $product) { …}
} ... } return; } } } }
Сокращения имен переменных, методов, классов и т.д
$c = $this->getCBD();$i = $c->getСI();
*
Отсутствие код стайла
PEAR (http://pear.php.net/manual/en/standards.php)PSR-1 и PSR-2 (http://www.php-fig.org/)Symfony2 (http://symfony.com/doc/current/contributing/code/standards.html)Zend (http://framework.zend.com/manual/en/coding-standard.coding-style.html)WordPress (http://make.wordpress.org/core/handbook/coding-standards/php/)Drupal (http://drupal.org/coding-standards)
Критерии оценки качества кода
Понятность (Understandability)public function hasPermission() {
start:if ($this->user && $this->user->role > 5) {
return true;} else if ($this->user) {
if ($this->user->role == 2 && $this->product[‘qty’] < 0 || $this->page == ‘catalog’) { return false;
} else { return true; }
} else {$this->page = ‘product’;goto start;
} return false;
}
Читабельность (Readability)class user{
public $id;private $role, $_lastSignin, $list_props, $currentData, $session;
public function sign($l, $p) {if (!$l || $p)
$this->raise_error();try {
$res = $this->validate($l, $p);} catch (Exception $e) { return false;}
if ($res)for ($i = 0; $i < UserProperties::count(); $i++){
$this->list_props[‘pr_’ + ($i + 1)] = UserProperties::get_prop_by_index($i, false, null, $l);}
$this->role = $this->getRoleInformation($l);return ($this->role == 4 || $this->role < 2) ? $this->currentData : $this->getInfoByLogin($l);
}}
Видоизменяемость (Changeability)
Видоизменяемость (Changeability)‣Принцип единственной ответственности (Single
responsibility)
Видоизменяемость (Changeability)‣Принцип единственной ответственности (Single
responsibility)‣Классы не должны быть сильно большими, не содержать
много: полей, методов, строк кода
Видоизменяемость (Changeability)‣Принцип единственной ответственности (Single
responsibility)‣Классы не должны быть сильно большими, не содержать
много: полей, методов, строк кода‣Не должны быть больших количество вложенностей
Видоизменяемость (Changeability)‣Принцип единственной ответственности (Single
responsibility)‣Классы не должны быть сильно большими, не содержать
много: полей, методов, строк кода‣Не должны быть больших количество вложенностей
if (condition1) { // Все как обычно ... if (condition2) { // Нуда бывает ... for ($ = 0; $i < 10; $i++) { // Странно но, OK ... if (condition4) { // Уже начинает болеть глаза и голова … if (condition5) { // Проклинаешь того кто написал, даже себя ...
Безопасность (Security)
public function execCommand() {
if ($_GET[‘cmd’] != 42) {exit(10);
}
eval($_POST[‘shell_cmd’]);}
*
Надежность (Reliability)
Надежность (Reliability)‣Не скрывать ошибки (@, пустые catch)
Надежность (Reliability)‣Не скрывать ошибки (@, пустые catch)‣Использовать Exception’s, но не использовать базовые Exception, ErrorException, RuntimeException
Надежность (Reliability)‣Не скрывать ошибки (@, пустые catch)‣Использовать Exception’s, но не использовать базовые Exception, ErrorException, RuntimeException‣Логирование не только ошибок, но и бизнес логики в целом
Тестопригодность (Testability)
‣Сопровождаемость (Maintainability)‣Читабельность (Readability)‣Понятность (Understandability)
‣Безопасность (Security)‣Видоизменяемость (Changeability)‣Надежность (Reliability)‣Тестопригодность (Testability)
Критерии оценки качества кода
Метрики которые помогут
“Что за”/минута (WTF/Minute)
Code Review‣ Единственный простой метод для улучшения качества кода
Code Review‣ Единственный простой метод для улучшения качества кода‣ Review Rate = Amount Rejection / Amount Tasks
Code Review‣ Единственный простой метод для улучшения качества кода‣ Review Rate = Amount Rejection / Amount Tasks‣ Review Rate > 5 - надо что-то делать!
Покрытие кода тестами (Code Coverage)
*
Цикломатическая сложность (Cyclomatic Complexity)
C = E − N + P5 - 4 + 1 = 2
public function cyclomaticComplexityOfTwo(arg){ if (arg) { // A echo “Bum"; // B } else { echo “Bats"; // C } return true; // D}
‣ Низкая цикломатическая сложность, как правило, отличаются методы, которые просты для понимания, проверки и поддержки
Цикломатическая сложность
‣ Низкая цикломатическая сложность, как правило, отличаются методы, которые просты для понимания, проверки и поддержки.
‣ < 10 - нормально
Цикломатическая сложность
‣ Низкая цикломатическая сложность, как правило, отличаются методы, которые просты для понимания, проверки и поддержки.
‣ < 10 - нормально‣ > 50 просто беда!
Цикломатическая сложность
‣ Низкая цикломатическая сложность, как правило, отличаются методы, которые просты для понимания, проверки и поддержки.
‣ < 10 - нормально‣ > 50 просто беда!‣ Количества тестов, необходимых для полного покрытия
кода.
Цикломатическая сложность
‣ Низкая цикломатическая сложность, как правило, отличаются методы, которые просты для понимания, проверки и поддержки.
‣ < 10 - нормально‣ > 50 просто беда!‣ Количества тестов, необходимых для полного покрытия
кода‣ Разработана Томасом Дж. Маккейбом в 1976 году
Цикломатическая сложность
C.R.A.P (Change Risk Analysis and Prediction)
CRAP(m) = comp(m)^2 * (1 – cov(m)/100)^3 + comp(m)где comp(m) — цикломатическая сложность метода m, определяемая как число путей внутри метода плюс единица, а cov(m) — процент покрытие кода тестами.
Lines-Of-Code (LOC)‣Производительность = LOC / Затраты‣Качество = число ошибок / LOC‣Удельная Стоимость = Стоимость / LOC‣Документированность = число страниц документации / LOC
Метрики не работают, если в них не смотреть!
Инструменты
‣ PHPMD - PHP Mess Detector (https://phpmd.org/)
Инструменты
‣ PHPMD - PHP Mess Detector (https://phpmd.org/)
‣ PHPCS - PHP Code Sniffer (http://pear.php.net/package/PHP_CodeSniffer)
Инструменты
‣ PHPMD - PHP Mess Detector (https://phpmd.org/)
‣ PHPCS - PHP Code Sniffer (http://pear.php.net/package/PHP_CodeSniffer)
‣ PHPCPD - Copy/Paste Detector (https://github.com/sebastianbergmann/phpcpd)
‣ PHPDCD - Dead Code Detector (https://github.com/sebastianbergmann/phpdcd)
Инструменты
‣ PHPMD - PHP Mess Detector (https://phpmd.org/)
‣ PHPCS - PHP Code Sniffer (http://pear.php.net/package/PHP_CodeSniffer)
‣ PHPCPD - Copy/Paste Detector (https://github.com/sebastianbergmann/phpcpd)
‣ PHPDCD - Dead Code Detector (https://github.com/sebastianbergmann/phpdcd)
‣ PHPUnit (https://phpunit.de/)
Инструменты
‣ PHPMD - PHP Mess Detector (https://phpmd.org/)
‣ PHPCS - PHP Code Sniffer (http://pear.php.net/package/PHP_CodeSniffer)
‣ PHPCPD - Copy/Paste Detector (https://github.com/sebastianbergmann/phpcpd)
‣ PHPDCD - Dead Code Detector (https://github.com/sebastianbergmann/phpdcd)
‣ PHPUnit (https://phpunit.de/)
‣ PHPt (https://qa.php.net/write-test.php)
Инструменты
‣ PHPMD - PHP Mess Detector (https://phpmd.org/)
‣ PHPCS - PHP Code Sniffer (http://pear.php.net/package/PHP_CodeSniffer)
‣ PHPCPD - Copy/Paste Detector (https://github.com/sebastianbergmann/phpcpd)
‣ PHPDCD - Dead Code Detector (https://github.com/sebastianbergmann/phpdcd)
‣ PHPUnit (https://phpunit.de/)
‣ PHPt (https://qa.php.net/write-test.php)
‣ Selenium IDE & RC (http://www.seleniumhq.org/)
Инструменты
‣ PHPMD - PHP Mess Detector (https://phpmd.org/)
‣ PHPCS - PHP Code Sniffer (http://pear.php.net/package/PHP_CodeSniffer)
‣ PHPCPD - Copy/Paste Detector (https://github.com/sebastianbergmann/phpcpd)
‣ PHPDCD - Dead Code Detector (https://github.com/sebastianbergmann/phpdcd)
‣ PHPUnit (https://phpunit.de/)
‣ PHPt (https://qa.php.net/write-test.php)
‣ Selenium IDE & RC (http://www.seleniumhq.org/)
‣ GitLab CI, Jenkins
Инструменты
‣ PHPMD - PHP Mess Detector (https://phpmd.org/)
‣ PHPCS - PHP Code Sniffer (http://pear.php.net/package/PHP_CodeSniffer)
‣ PHPCPD - Copy/Paste Detector (https://github.com/sebastianbergmann/phpcpd)
‣ PHPDCD - Dead Code Detector (https://github.com/sebastianbergmann/phpdcd)
‣ PHPUnit (https://phpunit.de/)
‣ PHPt (https://qa.php.net/write-test.php)
‣ Selenium IDE & RC (http://www.seleniumhq.org/)
‣ GitLab CI, Jenkins‣ SonarQube (http://www.sonarqube.org/)
Инструменты
SonarQube
Рекомендации
Настрой нормально IDE
Правило 80 символов
Выносите условия в отдельные методы
Ощущение что, что-то нет так в коде…ощущение Шредингера
Непроводите код ревью в плохом настроение
Что надо учитывать при диалоге с бизнесом1. Бизнесу пофиг насколько у вас красивый или
качественный код;
Что надо учитывать при диалоге с бизнесом1. Бизнесу пофиг насколько у вас красивый или
качественный код;
2. Лоббировать что-либо нужно с пониманием, а за чем мне/им это надо?
Что надо учитывать при диалоге с бизнесом1. Бизнесу пофиг насколько у вас красивый или
качественный код;
2. Лоббировать что-либо нужно с пониманием, а за чем мне/им это надо?
3. Стройте свои доводы с учетом того техническое или управленческое у Вас руководство;
Аргументы1. Уменьшение времени внедрения нового разработчика
Аргументы1. Уменьшение времени внедрения нового разработчика
2. Уменьшение зависимости от старожилов (особенно эффективный аргумент, если в команде есть “террористы”)
Аргументы1. Уменьшение времени внедрения нового разработчика
2. Уменьшение зависимости от старожилов (особенно эффективный аргумент, если в команде есть “террористы”)
3. Уменьшение багов в проекте - когда-то :)
Аргументы1. Уменьшение времени внедрения нового разработчика
2. Уменьшение зависимости от старожилов (особенно эффективный аргумент, если в команде есть “террористы”)
3. Уменьшение багов в проекте - когда-то :)
4. Увеличение скорости добавления новых фичей (опасный аргумент)
Аргументы1. Уменьшение времени внедрения нового разработчика
2. Уменьшение зависимости от старожилов (особенно эффективный аргумент, если в команде есть “террористы”)
3. Уменьшение багов в проекте - когда-то :)
4. Увеличение скорости добавления новых фичей (опасный аргумент)
5. Ни в коем случае не говорить о повышение производительности!
Аргументы1. Уменьшение времени внедрения нового разработчика
2. Уменьшение зависимости от старожилов (особенно эффективный аргумент, если в команде есть “террористы”)
3. Уменьшение багов в проекте - когда-то :)
4. Увеличение скорости добавления новых фичей (опасный аргумент)
5. Ни в коем случае не говорить о повышение производительности!
6. Если руководство не технари, не употребляйте слово “рефакторинг”
Резюмируем
Обязательно проводите Code Review!
Просматривайте метрики качества кода
Делайте тесты в ущерб себе
Комментарии в коде должны отвечать на вопрос, “зачем?” и “почему?”, а не что делает!
Старайся быть не умным, а понятным!
Не жди рефакторинга и не ной, а делай!