Как найти вонючие части вашего кода [Часть XIV]

Как найти вонючие части вашего кода [Часть XIV]

24 февраля 2022 г.

Бесконечный код пахнет!


Мы видим несколько симптомов и ситуаций, которые заставляют усомниться в качестве нашего развития.


Давайте рассмотрим некоторые возможные решения.


Большинство этих запахов — просто намеки на то, что что-то может быть не так. Это не жесткие правила.


Предыдущие части


[Часть I] (https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-i-xqz3evd)


[Часть II] (https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-ii-o96s3wl4)


[Часть III] (https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-iii-t7h3zkv)


[Часть IV] (https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-iv-7sc3w8n)


[Часть V] (https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-v-evj3zs9)


[Часть VI] (https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-vi-cmj31om)


[Часть VII] (https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-vii-8dk31x0)


[Часть VIII] (https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-viii-8mn3352)


[Часть IX] (https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-ix-7rr33ol)


[Часть X] (https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-x-i7r34uj)


[Часть XI] (https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xi-sit35t1)


[Часть XII] (https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xii)


[Часть XIII] (https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xiii)


Давай продолжим...


Code Smell 66 - Хирургия дробовиком


Скажи это только один раз


Проблемы


  • Плохие обязанности

  • Дублирование кода

  • Ремонтопригодность

  • [Единая ответственность] (https://en.wikipedia.org/wiki/Единая ответственность_принцип) Нарушение.

  • Скопированный код.

Решения


  1. Рефакторинг

Образец кода


Неправильно


```php


конечный класс Социальная сеть {


функция postStatus (строка $ newStatus) {


если (!$user->isLogged()) {


выдать новое исключение («Пользователь не зарегистрирован»);


функция uploadProfilePicture (изображение $ newPicture) {


если (!$user->isLogged()) {


выдать новое исключение («Пользователь не зарегистрирован»);


функция sendMessage(Пользователь $recipient, Сообщение $messageSend) {


если (!$user->isLogged()) {


выдать новое исключение («Пользователь не зарегистрирован»);


Верно


```php


конечный класс Социальная сеть {


функция postStatus (строка $ newStatus) {


$this->assertUserIsLogged();


функция uploadProfilePicture (изображение $ newPicture) {


$this->assertUserIsLogged();


функция sendMessage(Пользователь $recipient, Сообщение $messageSend) {


$this->assertUserIsLogged();


функция assertUserIsLogged() {


если (!$this->user->isLogged()) {


выдать новое исключение («Пользователь не зарегистрирован»);


//Это просто упрощение, чтобы показать запах кода


//Операции должны быть определены как объекты с предусловиями и т.д.


Обнаружение


Некоторые современные линтеры могут обнаруживать повторяющиеся шаблоны (а не только повторяющийся код), а также при выполнении проверки кода мы можем легко обнаружить эту проблему и запросить рефакторинг.


Теги


  • Дублирование кода

Заключение


Добавление новой функции должно быть простым, если наша модель соответствует 1:1 реальному миру, а наши обязанности находятся в правильных местах.


Мы должны быть готовы к небольшим изменениям, затрагивающим несколько классов.


Больше информации


Википедия


Гуру рефакторинга


[Блог NDpend] (https://blog.ndepend.com/shotgun-surgery)


[Дзона] (https://dzone.com/articles/code-smell-shot-surgery)


Кредиты


Фото Уильям Истед на Unsplash


Дублирование — главный враг хорошо спроектированной системы.


Роберт Мартин


Код Запах 67 - Посредник


Давайте нарушим Закон Деметры.



Проблемы


  • Ненужная косвенность

  • Пустые классы

  • Читабельность

Решения


  1. Удалите посредника.

Образец кода


Неправильно


```java


клиент открытого класса {


Адресный адрес;


общедоступный почтовый индекс zipCode () {


обратный адрес.zipCode();


Адрес публичного класса {


частный почтовый индекс zipCode;


общедоступный почтовый индекс zipCode () {


вернуть новый ZipCode('CA90210');


Приложение открытого класса {


ZipCode zipCode = client.zipCode();


Верно


```java


клиент открытого класса {


Адресный адрес;


// теперь клиент должен указать свой адрес


публичный адресс() {


обратный адрес;


Адрес публичного класса {


частный почтовый индекс zipCode;


общедоступный почтовый индекс zipCode () {


вернуть новый ZipCode('CA90210');


Приложение открытого класса {


ZipCode zipCode = client.address().zipCode();


Обнаружение


То же, что и его [противоположный запах] (https://maximilianocontieri.com/code-smell-08-long-chains-of-collaborations). Мы можем обнаружить это маленькое с помощью разбора деревьев.


Теги


  • Связь

  • Декларативный

  • Читабельность

Заключение


Это прямо противоположно [цепочке сообщений] (https://maximilianocontieri.com/code-smell-08-long-chains-of-collaborations). Мы делаем явной цепочку сообщений.


Связи


[Code Smell 08 — Длинные цепочки сотрудничества] (https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-ii-o96s3wl4)


[Код Запах 114 - Пустой класс] (https://maximilianocontieri.com/code-smell-114-empty-class)


Больше информации


[Гуру рефакторинга] (https://refactoring.guru/smells/middle-man)


[Refactoring.com] (https://refactoring.com/catalog/removeMiddleMan.html)


[Вики C2] (https://wiki.c2.com/?MiddleMan)


JetBrains


[Википедия] (https://en.wikipedia.org/wiki/Law_of_Demeter)


Кредиты


Фото Дэн Коунселл на Unsplash


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


Мартин Фаулер


Код Запах 68 - Добытчики


  • Получение вещей широко распространено и безопасно. Но это очень плохая практика.*


Проблемы


  • Именование

  • Сокрытие информации

  • Связь

  • Нарушение инкапсуляции

  • Изменчивость

  • Анемичные модели

Решения


  1. Избегайте добытчиков

  1. Вместо этого используйте доменные имена

  1. Защитите свои решения по внедрению.

Образец кода


Неправильно


```php


<?php


конечное окно класса {


публичная ширина $;


публичная высота $;


общественные $дети;


публичная функция getWidth() {


вернуть $this->width;


публичная функция getArea() {


вернуть $this->width * $this->height;


публичная функция getChildren() {


вернуть $this->children;


Верно


```php


<?php


конечное окно класса {


частная $ ширина;


частная высота $;


частные $дети;


ширина публичной функции () {


вернуть $this->width;


область общественных функций () {


вернуть $this->height * $this->width;


общедоступная функция addChildren ($ aChild) {


// не раскрывать внутренние атрибуты


вернуть $this->children[] = $aChild;


Обнаружение


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


getColor() нарушает биекцию, поскольку она реализуема и не имеет реального аналога в наших сопоставителях.


Большинство линтеров могут предупредить нас, если обнаружат анемичные модели с геттерами и сеттерами.


Теги


  • Сокрытие информации

Заключение


Геттеры и сеттеры - плохая устоявшаяся практика. Вместо того, чтобы сосредоточиться на поведении объекта (важно), мы отчаянно пытаемся узнать сущность объекта (случайно) и нарушаем его реализацию.


Связи


[Код Запах 28 - Сеттеры] (https://maximilianocontieri.com/code-smell-28-setters)


[Код Запах 01 - Модели с анемией] (https://maximilianocontieri.com/code-smell-01-anemic-models)


[Код Запах 64 - Неуместная близость] (https://hackernoon.com/nude-models-part-ii-getters-sjo3ua2)


Больше информации


Обнаженные модели - Часть II Геттеры


Кредиты


Фото Видар Нордли-Матисен на Unsplash


Ценность прототипа заключается в обучении, которое он дает, а не в самом коде.


Алан Купер


Code Smell 69 - Большой взрыв (JavaScript Ridiculous Castings)


Этот удобный оператор создает проблемы.



TL;DR: не смешивайте логические значения с небулевыми.


Проблемы


  • Не декларативный код

  • Трудно отлаживать

  • Магические отливки

  • Случайная сложность

Решения


  1. Будьте откровенны

  1. Не смешивайте булевы значения с небулевыми.

  1. [Fail Fast] (https://maximilianocontieri.com/fail-fast)

  1. Будьте умнее своего компилятора.

  1. Оставайтесь верны биекции.

[Единственный принцип проектирования программного обеспечения] (https://hackernoon.com/the-one-and-only-software-design-principle-1x983ylp)


Образец кода


Неправильно


```javascript


!true // возвращает ложь


!false // возвращает истину


Актив = Истина


!isActive // ​​возвращает ложь


возраст = 54


!age // возвращает ложь


массив = []


!массив // возвращает ложь


obj = новый объект;


!obj // возвращает ложь


!!true // возвращает истину


!!false // возвращает ложь


!!isActive // ​​возвращает истину


!!возраст // возвращает истину


!!массив // возвращает истину


!!obj // возвращает истину


Верно


```javascript


!true // возвращает ложь


!false // возвращает истину


Актив = Истина


!isActive // ​​возвращает ложь


возраст = 54


!age // должно возвращать несоответствие типов (или факториал 54!)


массив = []


!array // должен возвращать несоответствие типов


obj = новый объект;


!obj // должен возвращать несоответствие типов (что означает отрицание объекта в реальном домене?)


!!true // возвращает true - это идемпотент


!!false // возвращает false - это идемпотент


!!isActive // ​​возвращает true - это идемпотент


!!возраст // вздор


!!массив // бессмыслица


!!obj // бред


Обнаружение


Поскольку это «функция» в некоторых языках, ее будет трудно протестировать. Мы можем установить политики программирования или выбрать больше [строгих языков] (https://dev.to/tmaximini/typescript-bang-operator-considered-harmful-3hhi).


Мы должны обнаруживать использование ! !! в небулевых объектах и ​​предупреждать наших программистов.


Теги


  • Кастинг

  • Принуждение

  • Джаваскрипт

Заключение


Такие языки, как JavaScript, делят всю свою вселенную на значения true или false. Это решение скрывает ошибки при работе с небулевыми значениями.


Мы должны быть очень строгими и держать логические значения (и их поведение) подальше от небулевых значений.


Связи


[Code Smell 24 — Boolean Coercions] (https://maximilianocontieri.com/code-smell-24-boolean-coercions)


[Code Smell 06 — Too Clever Programmer] (https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-ii-o96s3wl4)


Больше информации


Reddit


[Bennadel.com] (https://www.bennadel.com/blog/3858-the-double-bang-operator-and-a-misunderstanding-of-how-javascript-handles-truthy-falsy-values.htm)


[Mozilla] (https://developer.mozilla.org/en-US/docs/Glossary/Truthy)


Кредиты


Фото Грега Ракози на Unsplash


Легче написать неправильную программу, чем понять правильную.


Алан Джей Перлис


Code Smell 70 - Анемичные генераторы моделей



TL;DR: не создавайте анемичных объектов. Гораздо меньше с автоматическими инструментами.


Проблемы


  • Анемичные объекты

  • Связь с реализацией

  • Сложнее отлаживать

Решения


  1. Создайте свои объекты вручную.

  1. Сосредоточьтесь на важном поведении вместо случайного хранения данных.

Образец кода


Неправильно


```php


AnemicClassCreator::create(


'Работник',


новый AutoGeneratedField('id', '$validators->getIntegerValidator()'),


новый AutoGeneratedField('имя', '$validators->getStringValidator()'),


новое AutoGeneratedField('currentlyWorking', '$validators->getBooleanValidator()')


класс Сотрудник расширяет AutoGeneratedObjectEmployee {


// У нас есть магические сеттеры и геттеры


//getId(), setId(), getName()


//Проверка не является неявной


//Класс загружается через автозагрузчик


$john = новый сотрудник;


$джон->setId(1);


$john->setName('Джон');


$john->setCurrentlyWorking(true);


$john->getName(); //возвращает 'Джон'


Верно


```php


последний класс Сотрудник {


личное $имя;


частный $рабочийстатус;


общедоступная функция __construct (строка $ имя, рабочее состояние $ рабочее состояние) {


имя публичной функции(): строка {


вернуть $это->имя;


// Это не геттер. Сотрудник обязан сообщить нам свое имя.


//У нас нет магических сеттеров и геттеров


//все методы настоящие и могут быть отлажены


//Проверки неявные


$john = новый сотрудник('Джон', новый HiredWorkingStatus());


$джон->имя(); //возвращает 'Джон'


Обнаружение


Часто анемичные модели создаются с помощью [метапрограммирования] (https://maximilianocontieri.com/laziness-i-meta-programming).


Нам нужно отслеживать эти волшебные [генераторы кода] (https://maximilianocontieri.com/lazyness-ii-code-wizards).


Теги


  • Анемичный

Заключение


Мастера кода, метапрограммирование и анемичные модели — все это запахи кода.


Нам нужно избегать этих темных методов.


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


Связи


[Код Запах 01 - Модели с анемией] (https://maximilianocontieri.com/code-smell-01-anemic-models)


Больше информации


[Лень I — Метапрограммирование] (https://hackernoon.com/laziness-chapter-i-meta-programming-6s4l300e)


[Лень II - Мастера кода] (https://hackernoon.com/lazyness-chapter-ii-code-wizards-3i9x3xtr)


Кредиты


Фото Ленни Куне на Unsplash


Лучшие запахи легко заметить, и в большинстве случаев они приводят к действительно интересным проблемам. Классы данных (классы со всеми данными и без поведения) являются хорошими примерами этого. Вы смотрите на них и спрашиваете себя, какое поведение должно быть в этом классе.


Мартин Фаулер


И это пока все…


Следующая статья объяснит еще 5 запахов кода!



Оригинал
PREVIOUS ARTICLE
NEXT ARTICLE