Чистый код

Презентация:



Advertisements
Похожие презентации
EXtreme Programming XP Тема 3. XP Пусть есть некоторая информационная система для банков. В качестве основной валюты для расчетов используется доллар,
Advertisements

Д.з Язык С++ - занятие 31. Задача 1: 1/1 + 1/3 + 1/5 … #include using namespace std; int main() { int n; cin >> n; double sum = 0;// Сумма for.
Делегаты Как созданные объекты могут посылать сообщения тем объектам, которые их породили? При программировании под Windows на С и C++ основное средство.
Стиль программирования Андрей Свердлов. Введение Или как мы учились писать код вместе.
Виталий Хить, Абсолютист.
Программирование на языке высокого уровня Лекция 2. Метод. Алгоритм. Программа. Кафедра АСОИУ ОмГТУ, 2012 Богатов Р.Н.
Перегрузка операторов x = a + b результат 1-й операнд2-й операнд оператор По количеству операндов операторы делятся на: унарные (один операнд) бинарные.
Php Что такое php? PHP – это высокоуровневый язык программирования для WEB работающий по принципу транслирующего интерпретатора.
Встроенная документация Java Андрей Дмитриев Инженер-программист Sun Microsystems Февраль 2008.
ОБЪЕКТНО- ОРИЕНТИРОВАННОЕ ПРОГРАММИРОВАНИЕ (ООП) 1.
АССОЦИАТИВНЫЕ КОЛЛЕКЦИИ Лекция 6 1. Отличие от последовательных 2 В последовательной коллекции каждый элемент ассоциируется с номером, начиная с 0. В.
Виталий Хить (well). Виджеты Примеры кода Собственное обучение.
Преобразования типов В языке C/C++ имеется несколько операций преобразования типов. Они используются в случае, если переменная одного типа должна рассматриваться.
Программная инженерия Андрей Дмитриев ©
Практическое программирование на Java к.ф.-м.н. Козлов Дмитрий Дмитриевич Кафедра АСВК, Лаборатория Вычислительных комплексов.
Ассоциативные списки Поиск данных происходит не по индексу или положению объекта, а по его ассоциативной связи: public interface Map { // Доступ к объектам.
Высокоуровневые методы информатики и программирования Лекция 14 Интерфейсы.
Лекция 4 Объекты. Типы объектов ТипПример Источник реализации Регламентирующи й стандарт Пользовательский Определенные пользователем объекты Student или.
ДЕЛЕГАТЫ Лекция 7 1. Зачем нужны делегаты 2 И данные, и код располагаются в памяти компьютера по определенным адресам. Передача адресов данных в C# происходит.
Основы ООП и C# Работа с объектами и классами. Классы Класс специальный тип данных для описания объектов. Он определяет данные и поведение типа. Определение.
Транксрипт:

Чистый код Глотова Марина Начальник отдела информационных разработок

2 2. Как загрязняется код

3 3. Как загрязняется код

4 4. Код-монстр

Зачем нужен чистый код?

6 6. Несколько фактов а разработке

7 Над чтением кода мы проводим в 10 раз больше времени, чем над его написанием 7. Несколько фактов а разработке

8 Над чтением кода мы проводим в 10 раз больше времени, чем над его написанием 8. Несколько фактов а разработке Чем больше загрязняется наш код, тем больше мы теряем в производительности время производительность

9 9. Что даёт чистый код?

Что даёт чистый код? Быстрое чтение и понимание кода.

Что даёт чистый код? Быстрое чтение и понимание кода. Уменьшение количества багов.

Что даёт чистый код? Быстрое чтение и понимание кода. Уменьшение количества багов. Простые модульные тесты.

Стандарты оформления кода

Стандарты оформления кода PSR (PHP Standards Recommendations):

Стандарты оформления кода PSR (PHP Standards Recommendations): PSR-2

Стандарты оформления кода PSR (PHP Standards Recommendations): PSR-2 PSR-4

Стандарты оформления кода PSR (PHP Standards Recommendations): PSR-2 PSR-4 PSR-5

Стандарты оформления кода PSR (PHP Standards Recommendations): PSR-2 PSR-4 PSR-5 phpDocumentor

Рефакторинг

Архитектура кода MVC

Тонкий и толстый контроллер

Тонкий и толстый контроллер protected function actionDelete() { if (!Request::isAjaxRequest()) { $this->renderError(); } $payment_id = Request::getInt('id', $_POST); if (!$payment_id) { $this->returnJsonResponse(['success' => false, 'msg' => 'Платёж не найден']); } $payment = PaymentModel::model(false)->findByPk($payment_id); if (null === $payment) { $this->returnJsonResponse(['success' => false, 'msg' => 'Платёж не найден']); } $result = $payment->deletePayment(); if ($result) { PaymentsHelper::i()->updateFirmProperties((int)$payment->firm_id); $this->returnJsonResponse(['success' => true, 'msg' => 'Платёж удалён']); } $this->returnJsonResponse(['success' => false, 'msg' => 'Ошибка удаления платежа']); }

Дублирование кода public function transferToOrganizer(int $firm_id): bool { какая-то логика….. $result = $this->getFund($firm_id) ->spend($this->getComment(Trade::COMMENT_TO_ORGANIZER)); какая-то логика….. } public function transferToParticipant(int $firm_id): bool { какая-то логика….. $result = $this->getFund($firm_id) ->spend($this->getComment(Trade::COMMENT_TO_PARTICIPANT)); какая-то логика….. }

Дублирование кода public function transfer (int $firm_id, int $comment_type): bool { какая-то логика….. $result = $this->getFund($firm_id) ->spend($this->getComment($comment_type)); какая-то логика….. }

Длинный метод, класс

Длинный метод, класс Умеет делать всё

Длинный метод, класс Умеет делать всё Часто содержит дублирование кода

Длинный метод, класс Умеет делать всё Часто содержит дублирование кода Разбиваем

Много параметров public function transfer (int $firm_id, int $comment_type, ….): bool { какая-то логика….. $result = $this->getFund($firm_id) ->spend($this->getComment($comment_type)); какая-то логика….. }

Много параметров class Operation { private $firm_id; public function setFirmId(int $firm_id): self { $this->firm_id = $firm_id; return $this; } private function getFirmId() { return $this->firm_id; } public function transfer(int $comment_type): bool { //какая - то логика….. $result = $this->getFund($this->getFirmId()) ->spend($this->getComment($comment_type)); //какая - то логика….. }

Завистливые функции public function transfer(Comment $comment): bool { //какая - то логика… $result = $this->getFund($this->getFirmId()) ->spend($this->getComment($comment_type)); $notification = new Notification(); $notification->date = time(); $notification->text = 'some text'; $notification->to_whom = $this->getFirm()->getMainUser(); $notification->send(); }

Завистливые функции public function transfer(Comment $comment): bool { //какая - то логика… $result = $this->getFund($this->getFirmId()) ->spend($this->getComment($comment_type)); $notification = new Notification(); $notification->date = time(); $notification->text = 'some text'; $notification->to_whom = $this->getFirm()->getMainUser(); $notification->send(); } public function transfer(Comment $comment): bool { //какая - то логика… $result = $this->getFund($this->getFirmId()) ->spend($this->getComment($comment_type)); $notification = (new Notification()) ->setText('some text') ->setUserId($this->getFirm()->getMainUser()) ->send(); }

Метод возвращает несколько типов public function getActivePaymentIds(): ?array { $all_payments = $this->getAllPayments(); if (empty($all_payments)) { return null; } $active_payments = []; foreach ($all_payments as $payment) { //выбираем активные платежи } return $active_payments; }

Метод возвращает несколько типов public function getActivePaymentIds(): ?array { $all_payments = $this->getAllPayments(); if (empty($all_payments)) { return null; } $active_payments = []; foreach ($all_payments as $payment) { //выбираем активные платежи } return $active_payments; } public function getActivePaymentIds(): array { $all_payments = $this->getAllPayments(); if (empty($all_payments)) { return []; } $active_payments = []; foreach ($all_payments as $payment) { //выбираем активные платежи } return $active_payments; }

Область видимости свойств и методов Делайте публичными методы, а не данные для работы этих методов: class Button() { private $is_enabled = true; public function setEnabled(bool $is_enabled): self { $this->is_enabled = $is_enabled; return $this; }

Область видимости свойств и методов Делайте публичными методы, а не данные для работы этих методов: class Button() { private $is_enabled = true; public function setEnabled(bool $is_enabled): self { $this->is_enabled = $is_enabled; return $this; } class Button() { private $is_enabled = true; public function enable() { $this->is_enabled = true; return $this; } public function disable() { $this->is_enabled = false; return $this; }

//TODO // todo этот метод немного вводит в ступор, // т.к. есть метод getConcludedStatuses /** * Список статусов для подписанного документа array */ public static function getSignedStatuses() { return [ self::STATUS_SIGNED_BY_PARTICIPANT, self::STATUS_SUSPENDED, self::STATUS_SIGNED_BY_BOTH_SIDES, ]; }

Что ухудшает читаемость кода?

Плохое именование методов и переменных ТРУДНЕЕ ПРИДУМЫВАНИЯ НАЗВАНИЯ ПЕРЕМЕННОЙ ЯВЛЯЕТСЯ ТОЛЬКО ПРИДУМЫВАНИЕ НАЗВАНИЯ ДЛЯ КОММИТА

Основные принципы именования сущностей Используем английский язык, нет транслитерации.

Основные принципы именования сущностей Используем английский язык, нет транслитерации. Стиль переменной свободный ($snake_case, $camelCase, $StudlyCase). Для метода это camelCase, для класса – StudlyCase.

Основные принципы именования сущностей Используем английский язык, нет транслитерации. Стиль переменной свободный ($snake_case, $camelCase, $StudlyCase). Для метода это camelCase, для класса – StudlyCase. Переменные – это существительные $user, методы – глаголы updateUserPermissions().

Основные принципы именования сущностей Используем английский язык, нет транслитерации. Стиль переменной свободный ($snake_case, $camelCase, $StudlyCase). Для метода это camelCase, для класса – StudlyCase. Переменные – это существительные $user, методы – глаголы updateUserPermissions() Переменная: одна сущность – единственное число $user, набор сущностей – множественное число $users.

Основные принципы именования сущностей Используем английский язык, нет транслитерации. Стиль переменной свободный ($snake_case, $camelCase, $StudlyCase). Для метода это camelCase, для класса – StudlyCase. Переменные – это существительные $user, методы – глаголы updateUserPermissions() Переменная: одна сущность – единственное число $user, набор сущностей – множественное число $users. Конкретика: да - $current_user, нет - $user.

Основные принципы именования сущностей Используем английский язык, нет транслитерации. Стиль переменной свободный ($snake_case, $camelCase, $StudlyCase). Для метода это camelCase, для класса – StudlyCase. Переменные – это существительные $user, методы – глаголы updateUserPermissions() Переменная: одна сущность – единственное число $user, набор сущностей – множественное число $users. Конкретика: да - $current_user, нет - $user. Является – isActive(), имеет – hasPermissions(), может – canUpload().

Основные принципы именования сущностей Используем английский язык, нет транслитерации. Стиль переменной свободный ($snake_case, $camelCase, $StudlyCase). Для метода это camelCase, для класса – StudlyCase. Переменные – это существительные $user, методы – глаголы updateUserPermissions() Переменная: одна сущность – единственное число $user, набор сущностей – множественное число $users. Конкретика: да - $current_user, нет - $user. Является – isActive(), имеет – hasPermissions(), может – canUpload(). Позитивный смысл: да – isActive(), нет – isNotActive().

Основные принципы именования сущностей Используем английский язык, нет транслитерации. Стиль переменной свободный ($snake_case, $camelCase, $StudlyCase). Для метода это camelCase, для класса – StudlyCase. Переменные – это существительные $user, методы – глаголы updateUserPermissions() Переменная: одна сущность – единственное число $user, набор сущностей – множественное число $users. Конкретика: да - $current_user, нет - $user. Является – isActive(), имеет – hasPermissions(), может – canUpload(). Позитивный смысл: да – isActive(), нет – isNotActive(). Возвращает – getUser(), устанавливает – setUser().

Основные принципы именования сущностей Используем английский язык, нет транслитерации. Стиль переменной свободный ($snake_case, $camelCase, $StudlyCase). Для метода это camelCase, для класса – StudlyCase. Переменные – это существительные $user, методы – глаголы updateUserPermissions() Переменная: одна сущность – единственное число $user, набор сущностей – множественное число $users. Конкретика: да - $current_user, нет - $user. Является – isActive(), имеет – hasPermissions(), может – canUpload(). Позитивный смысл: да – isActive(), нет – isNotActive(). Возвращает – getUser(), устанавливает – setUser(). Не сокращать: да - $number, нет - $num.

Основные принципы именования сущностей setDefaultAttributes() checkUserAndInitializeHisSession()

Основные принципы именования сущностей setDefaultAttributes() checkUserAndInitializeHisSession() checkUser() initializeUserSession()

Избыточные комментарии Когда писать комментарии: Краткое описание метода (по мере необходимости). Документация к методу.

Избыточные комментарии Когда писать комментарии: Краткое описание метода (по мере необходимости). Документация к методу. Пояснение нетривиальной бизнес-логики.

Избыточные комментарии Когда писать комментарии: Краткое описание метода (по мере необходимости). Документация к методу. Пояснение нетривиальной бизнес-логики. Пояснение параметров к методу (по мере необходимости).

Магия

Ранний выход из if foreach ($firms as $firm) { if ($firm->isActive()) { $result = $firm->updateStatus(); if ($result) { $this->registerEvent(); }

Ранний выход из if foreach ($firms as $firm) { if ($firm->isActive()) { $result = $firm->updateStatus(); if ($result) { $this->registerEvent(); } foreach ($firms as $firm) { if (!$firm->isActive()) { continue; } if ($firm->updateStatus()) { $this->registerEvent(); }

if-else-return if ($stuff === $another_stuff) { return true; } else { return false; }

if-else-return if ($stuff === $another_stuff) { return true; } else { return false; } return ($stuff === $another_stuff);

Инструменты

Инструменты Анализаторы кода: PhpInspector

Инструменты Анализаторы кода: PhpInspector Код-ревью: коммиты, phabricator, upsource

62 b2b-center.ru/jobs

Спасибо за внимание! Глотова Марина