Pull to refresh

Клиентский код. Пространство имен

Level of difficultyEasy
Reading time3 min
Views1.2K

Привет, Хабр!

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

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

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

Удачно получилось что тема пересекается с моей статьей. Может если это будет серия статьей с пометкой Клиентский код, то мне получится лучше донести что же все-таки это за код такой.

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

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

<?php
  
namespace Index;
use TestNamespace;

//\TestNamespace - это используемое пространство имен (через директиву use)
$MyVar = new TestNamespace\MyClass();

Файл с тестовым классом:

<?php

namespace TestNamespace

class MyClass {

  public function __construct() {
    echo 'test';
  }
  
}

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

Например (из документации):

<?php
    spl_autoload_extensions(".php");
    spl_autoload_register();
?>

При такой реализации автозагрузки классов точка входа в приложение (index.php) должна располагаться вверху иерархии папок проекта. Этот пример я увидел при изучении документации когда писал код своей реализации пространства имен. Если честно размещение точки входа рядом с кодом приложения меня немного смущает с точки зрения безопасности, поэтому моя реализация приведена ниже.

Моя реализация:

class Init {

  private string $RootPath = '..' . 
    DIRECTORY_SEPARATOR . '..' . 
    DIRECTORY_SEPARATOR . '..' . 
    DIRECTORY_SEPARATOR . '..' . 
    DIRECTORY_SEPARATOR . '..' . 
    DIRECTORY_SEPARATOR;

public function __construct(
  private array $NamespacePath
    ) 
  {
    spl_autoload_register(function ($ClassName) use ($NamespacePath) {
  
      $PartialPath = strrpos($ClassName, '\\');
      $PathBefore = substr($ClassName, 0, $PartialPath);
      $FileName = substr(strrchr($ClassName, '\\'), 1);
  
      while($PartialPath !== false) {
  
        if(!empty($NamespacePath[$PathBefore])){
          $ClassNameToPath = str_replace('\\', DIRECTORY_SEPARATOR, $ClassName);
          include $this->RootPath . $ClassNameToPath . '.php';
          break;
        }
  
        $PartialPath = strrpos($PathBefore, '\\');
        $PathBefore = substr($ClassName, 0, $PartialPath);
  
      }
    });
  }
}

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

Хочется отметить что такой подход к организации проекта дает нам следующие плюсы:

  • Каждый файл названием соответствует классу который в нем описан

  • С помощью пространства имен легче представить что делают классы, если хотя-бы минимально погрузиться в логику расположения классов по пространствам имен

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

  • С помощью пространства имен, клиентский код ограничен своими возможностями, что-бы "ленивый" программист не пытался реализовать что либо в обход заданной парадигмы.

  • При правильном подходе подталкивает программиста к стилю написания кода в проекте

Tags:
Hubs:
Rating0
Comments19

Articles