Разработка сайтов в Москве. Как обеспечить гибкий, многоразовый PHP-код с помощью Insphect

 
 

Inspect — это инструмент, который я написал как часть своего докторского проекта. Он сканирует код на предмет методов объектно-ориентированного программирования, которые препятствуют повторному использованию и гибкости кода.

Почему?

Позвольте мне начать с двух приземленных наблюдений:

Требования бизнеса со временем меняются.

Программисты не ясновидящие.

Запуск новых продуктов, правила экстренной блокировки, выход на новые рынки, экономические факторы, обновленные законы о защите данных: существует множество потенциальных причин, по которым программное обеспечение для бизнеса нуждается в обновлении.

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

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

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

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

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

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

Некоторые приемы программирования ведут к подходу «корабль в бутылке» и затрудняют изменение и адаптацию кода.

Осмотреть

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

Он оценивает ваш код в зависимости от его гибкости и выделяет области, где гибкость можно улучшить.

Что ищет Inspect?

В настоящее время Insphect ищет следующее:

тесная связь

жестко заданная конфигурация

одиночки

инъекция сеттера

используя newключевое слово в конструкторе

сервисные локаторы

наследование

статические методы

глобальное состояние

файлы, которые имеют более одной роли (например, определение класса и запуск некоторого кода)

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

Взгляните на образец отчета здесь.

В настоящее время Inspect находится на стадии тестирования, и мне бы очень помогло продвижение моего исследования, если бы вы могли проверить его и заполнить опрос в разделе «Оставьте свой отзыв» на сайте.

Фон

Но так ли плохи эти плохие практики?

Это была одна из самых сложных частей фонового исследования, и вы можете подробно прочитать о том, как это было сделано, на сайте Insphpect.

Однако это можно резюмировать так:

Мнения о каждой плохой практике были собраны у 100 авторов каждой практики.

Мнение автора о практике оценивалось по шкале от 1 до 5.

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

Затем они были построены, как на графике ниже:

Результаты одноэлементного шаблона

Каждая горизонтальная линия представляет собой статью, а левая (оранжевая) полоса для каждой статьи — это рекомендация, начиная с 5 — Избегайте этой практики любой ценой (крайняя левая) — до 1 — Предпочитайте эту практику альтернативам.

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

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

Прохождение

В настоящее время Insphpect позволяет загружать код через URL-адрес репозитория Git или ZIP-файл.

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

Мы будем использовать https://github.com/Level-2/Transphform в качестве примера проекта.

Это достаточно хороший пример, потому что он имеет очень высокий балл в другом инструменте проверки качества кода Scrutinizer.

Во-первых, введите URL-адрес git https://github.com/Level-2/Transphpormв текстовое поле в верхней части домашней страницы и нажмите «Перейти». Это займет от нескольких секунд до минут, в зависимости от размера проекта, и будет создан отчет, который выглядит примерно так:

Отчет о трансформации

Как только вы окажетесь на странице отчета, вверху вы увидите сводку с общей оценкой из 100, где 100 — очень хорошо, а 0 — очень плохо.

Под сводкой вы увидите список всех классов в проекте, каждый со своей оценкой.

Не беспокойтесь, если ваш код не получит высший балл. Маловероятно, что будет. Помните, Insphpect — это инструмент, который определяет гибкость вашего кода. В вашем коде есть части (например, точка входа), где гибкость не гарантируется.

Для Transphform он выделил проблемы в семи классах.

Давайте посмотрим на некоторые из них. Прокрутите вниз Transphporm\Parser\CssToXpathи нажмите на ссылку. Вы увидите оценку для этого конкретного класса и список проблем, которые были выявлены.

В данном случае он идентифицировал статическую переменную и статический метод. Нажав на одну из красных линий, вы увидите объяснение, почему линия была отмечена флажком.

Например, щелчок по строке 12 даст объяснение, почему статические переменные менее гибкие, чем переменные экземпляра.

Отчет по одному классу

Хотя в отчете есть более подробное объяснение проблем, вызванных статическими свойствами, в качестве быстрого освежения информации статические переменные имеют одно значение, которое является общим для всех экземпляров класса.

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

Например, рассмотрим следующее:

class User {

public static $db;

public $id;

public $name;

public $email;

public function save () {

$stmt = self: $db→prepare ('REPLACE INTO user (id, name, email) VALUES (: id,: name,: email)') ;

$stmt→execute ([

'id’ => $this→id,

'name’ => $this→name.

'email’ => $this→email

]) ;

}

}

Поскольку $dbон статичен, каждый экземпляр этого класса использует один и тот же $dbэкземпляр, и записи всегда будут вставляться в одну и ту же базу данных.

Хотя это звучит разумно, позвольте мне привести пример из реальной жизни.

В реальном мире

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

Наш клиент спросил нас следующее:

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

Достаточно простой запрос. Запустите запрос на вставку в две разные базы данных.

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

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

Помните, вы не ясновидящая, и невозможно предугадать, какая гибкость может понадобиться в будущем.

Решение

Как предложил Insphpect, решение этой проблемы заключается в использовании переменных экземпляра:

class User {

private $db;

public $id;

public $name;

public $email;

public function __construct (\PDO $db) {

$this→db = $db;

}

public function save () {

$stmt = self: $db→prepare ('REPLACE INTO user (id, name, email) VALUES (: id,: name,: email)') ;

$stmt→execute ([

'id’ => $this→id,

'name’ => $this→name.

'email’ => $this→email

]) ;

}

}

Теперь Userэкземпляр можно использовать с разными экземплярами базы данных:

new User ($database1) ;

new User ($database2) ;

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

Использование нового в конструкторе

Давайте взглянем на один из других классов: Transphporm\Builder.

Отчет класса строителя

Это имеет нулевой балл, что довольно плохо. Подробно изучив отчет, Inspect трижды обнаружил одну и ту же проблему: использование newключевого слова в конструкторе.

Тренер по программированию Google Миско Хевери отлично объясняет, почему это плохая практика программирования, но вот простой пример из результатов Inspect:

class Car {

private $engine;

public function __construct () {

$this→engine = new PetrolEngine () ;

}

}

Здесь всякий раз, когда создается экземпляр Car, создается экземпляр PetrolEngine. Это делает его очень негибким, потому что нет возможности сконструировать двигатель Carс другим типом двигателя. Каждый автомобиль, смоделированный в этой системе, должен иметь файл PetrolEngine.

Вместо этого мы можем использовать внедрение зависимостей:

class Car {

private $engine;

public function __construct ($engine) {

$this→engine = $engine;

}

}

Различные автомобили могут быть созданы с экземпляром двигателя PetrolEngine, DieselEngine, или любого другого типа двигателя ElectricEngine, JetEngineсуществующего в проекте.

Чтобы исправить эту ошибку в Transphporm\Builder, все переменные, которые в настоящее время имеют жестко закодированные имена классов, должны вместо этого использовать аргументы конструктора.

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

За кулисами

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

Баллы предназначены для сравнения одного проекта/класса с другим.

Общий балл проекта — это просто среднее значение всех классов в проекте. Это было реализовано, потому что проект с двумя проблемами в 1000 классах в целом намного лучше, чем проект с двумя проблемами в двух классах.

Каждая неправильная практика оценивается в зависимости от того, препятствует ли она гибкости всего класса или только гибкости метода.

Вывод

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

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

Каковы результаты вашего проекта или любимой библиотеки? Обязательно заполните опрос, так как он предоставит ценные данные для моего докторского проекта и поможет улучшить инструмент!

3D-печать5GABC-анализAndroidAppleAppStoreAsusCall-центрChatGPTCRMDellDNSDrupalExcelFacebookFMCGGoogleHuaweiInstagramiPhoneLinkedInLinuxMagentoMicrosoftNvidiaOpenCartPlayStationPOS материалPPC-специалистRuTubeSamsungSEO-услугиSMMSnapchatSonyStarlinkTikTokTwitterUbuntuUp-saleViasatVPNWhatsAppWindowsWordPressXiaomiYouTubeZoomАвдеевкаАктивные продажиАкцияАлександровск ЛНРАлмазнаяАлчевскАмвросиевкаАнализ конкурентовАнализ продажАнтимерчандайзингАнтрацитАртемовскАртемовск ЛНРАссортиментная политикаБелгородБелицкоеБелозерскоеБердянскБизнес-идеи (стартапы)БрендБрянкаБукингВахрушевоВендорВидеоВикипедияВирусная рекламаВирусный маркетингВладивостокВнутренние продажиВнутренний маркетингВолгоградВолновахаВоронежГорловкаГорнякГорскоеДебальцевоДебиторкаДебиторская задолженностьДезинтермедитацияДзержинскДивизионная система управленияДизайнДимитровДирект-маркетингДисконтДистрибьюторДистрибьюцияДобропольеДокучаевскДоменДружковкаЕкатеринбургЕнакиевоЖдановкаЗапорожьеЗимогорьеЗолотоеЗоринскЗугрэсИжевскИловайскИрминоКазаньКалининградКировскКировскоеКомсомольскоеКонстантиновкаКонтент-маркетингКонтент-планКопирайтингКраматорскКрасноармейскКрасногоровкаКраснодарКраснодонКраснопартизанскКрасный ЛиманКрасный ЛучКременнаяКураховоКурскЛисичанскЛуганскЛутугиноМакеевкаМариупольМаркетингМаркетинговая информацияМаркетинговые исследованияМаркетинговый каналМаркетинг услугМаркетологМарьинкаМедиаМелекиноМелитопольМенеджментМерчандайзерМерчандайзингМиусинскМолодогвардейскМоскваМоспиноНижний НовгородНиколаевНиколаевкаНишевой маркетингНовоазовскНовогродовкаНоводружескНовосибирскНумерическая дистрибьюцияОдессаОмскОтдел маркетингаПартизанский маркетингПервомайскПеревальскПетровскоеПлата за кликПоисковая оптимизацияПопаснаяПравило ПаретоПривольеПрогнозирование продажПродвижение сайтов в ДонецкеПроизводство видеоПромоПромоушнПрямой маркетингРабота для маркетологаРабота для студентаРазработка приложенийРаспродажаРегиональные продажиРекламаРеклама на асфальтеРемаркетингРетро-бонусРибейтРитейлРовенькиРодинскоеРостов-на-ДонуРубежноеСамараСанкт-ПетербургСаратовСватовоСвердловскСветлодарскСвятогорскСевастопольСеверодонецкСеверскСедовоСейлз промоушнСелидовоСимферопольСинергияСколковоСлавянскСнежноеСоздание сайтов в ДонецкеСоледарСоциальные сетиСочиСтаробельскСтаробешевоСтахановСтимулирование сбытаСуходольскСчастьеТелемаркетингТельмановоТираспольТорговый представительТорезТрейд маркетингТрейд промоушнТюменьУглегорскУгледарУкраинскХабаровскХарцызскХерсонХостингЦелевая аудиторияЦифровой маркетингЧасов ЯрЧелябинскШахтерскЮжно-СахалинскЮнокоммунаровскЯндексЯсиноватая