Algo sobre el espacio de nombres

Estoy programando en PHP . Y un poco sobre JS . Una vez que programé en Java , incluso antes, en LotusScript . Probé un poco de python y dart . Basic , Fortran , Pascal , Prolog , VisualBasic , ++ / , perl : en todo esto también retraté algo ejecutable. Los lenguajes de programación me interesan en términos de creación de aplicaciones informáticas. Aplicaciones web. Aplicaciones web sofisticadas. Los que escriben personas que no están familiarizadas entre sí. Más precisamente, no están familiarizados personalmente: se conocen entre sí mediante firmas en los compromisos del repositorio común y por apodos en los rastreadores de errores. No soy demasiado inteligente para programar en / ++ para varios sistemas operativos y, por lo tanto, estoy programando en PHP para Magento .


Entonces, volviendo al tema del artículo, puedo decir que el espacio de nombres es uno de los pilares muy importantes en los que escribir aplicaciones web complejas se basa en un grupo de desarrolladores que no están familiarizados entre sí.


En este texto, por espacio de nombres, me refiero al espacio de nombres desde el punto de vista de PHP , no al espacio de nombres desde el punto de vista de python :


 <?php namespace Vendor\Project\Module\Component\Unit; 

Por primera vez, me encontré con un espacio de nombres al aprender Java , cuando traté de entender el secreto de la directiva " paquete ":


 package com.sun.source.util; 

El propósito de esta directiva no estaba claro, y qué debería indicarse exactamente en ella, si se pudiera indicar alguna línea. La recomendación de los autores del lenguaje para usar como parte del nombre del paquete registrado en su dominio (en su empresa) parecía algo extravagante. Ahora todos, todos, cualquiera tiene su propio dominio, y tal recomendación no es muy vergonzosa, y hace 15-20 años pensé mucho en qué dominio usar como nombre para mi primer paquete y qué podría afectar en el futuro. Solo más tarde, cuando construí aplicaciones usando maven , aprecié la idea de esta recomendación.


Gerentes de dependencia


Los administradores de dependencias me ayudaron a comprender el significado del espacio de nombres. Si su código usa código de terceros, que depende de otros paquetes que dependen de terceros, es muy difícil mantener el orden en ese volcado. Sin embargo, precisamente debido a la regla de dominio posterior para nombrar paquetes en un montón de JAR apilados en un directorio (por ejemplo, en WEB-INF/lib ), es bastante fácil navegar:


imagen


Comparar con npm ( JavaScript ):


imagen


En Java desarrolladores han adoptado el nombre de " back-domain " de los paquetes (como resultado de los módulos) ampliamente, mientras que en JS han hecho. Como resultado, en Java puede crear de forma independiente una gran cantidad de paquetes (módulos) libres de conflictos sin acordar explícitamente sus nombres como grupos de desarrollo independientes, y en JS debe usar explícitamente el registro npm . Sí, en Java , el registro de dominio global está implícitamente involucrado en la resolución de conflictos, pero cualquier comunidad, no solo los codificadores Java , puede usar la misma regla de nomenclatura.


En PHP , el administrador de dependencias del composer crea una estructura de directorio de dos niveles: ./company/module :


imagen


lo que brinda cierta ventaja en la navegación de dependencia sobre la asignación de un solo nivel.


Aquí están las estadísticas de los repositorios de paquetes centrales para Java / JS / PHP :


https://mvnrepository.com/repos/central - 3 358 578 frascos indexados
https://www.npmjs.com/ - 872 459 paquetes
https://packagist.org/statistics - 207 560 paquetes (1,472,944 versiones)


Lo más probable para maven todas las versiones de los módulos se tengan en cuenta en las estadísticas, mientras que los módulos se tengan en cuenta en npm y composer .


¿Para qué es el espacio de nombres?


La respuesta principal es evitar conflictos entre varios elementos de código (constantes, funciones, clases, ...) que tienen el mismo nombre pero están en módulos diferentes. Los espacios de nombres de Python hacen frente con éxito a esto. Pero todavía tomaría el "espacio de nombres" aquí entre comillas, porque en esencia, está más cerca del alcance .


El espacio de nombres de acuerdo con las versiones de Java ( package ) y PHP ( namespace ) permite, en primer lugar, abordar de manera inequívoca un elemento de código específico en la comunidad agregada. Y esta es una propiedad del espacio de nombres (agrupación lógica) que permite crear sistemas de software más complejos por grupos de desarrolladores menos conectados.


Abordar elementos de software


En PHP la clase \Doctrine\DBAL\Schema\Column se aborda de forma única, sin importar cómo se conecte el código fuente al proyecto. El IDE puede formar fácilmente esta dirección. En PhpStorm, esto se hace así (haga clic derecho en un elemento de código):


imagen


El mismo PhpStorm se pierde si aplica una técnica similar al código JS (donde no hay espacio de nombres). Intentemos formar la dirección para el enlace a la función de query JS de esta manera:


imagen


El resultado es module.query , que no es lo suficientemente informativo.


Para abordar la función de query en la documentación (correspondencia, rastreador de errores, etc.), debe consultar una línea de código específica en el archivo:


imagen


Resultado: ./node_modules/express/lib/middleware/query.js:25


Por supuesto, al cambiar el número de líneas en un archivo o mover / renombrar un archivo, tendremos en la documentación una dirección desactualizada del elemento del programa que nos interesa.


Por lo tanto, el uso del espacio de nombres permite que los enlaces a varios elementos del código del proyecto sigan siendo relevantes durante mucho más tiempo que los enlaces a una línea en un archivo.


Detectar versiones conflictivas de código


Las aplicaciones complejas modernas no se pueden desarrollar sin administradores de dependencias ( maven , composer , npm , ...). Al mismo tiempo, nuestras dependencias extraen sus dependencias, que extraen las suyas propias, etc., lo que como resultado puede generar conflictos de versión para el mismo paquete extraído a través de diferentes dependencias ( jar hell ).


En JS esto no ocurre debido a la falta de namespace'ov. Yo mismo me encontré con una situación en la que, al instalar módulos adicionales en Magento número de versiones diferentes de la biblioteca jQuery cargadas por ellos superaba los 5-6. Por un lado, este comportamiento da mayor libertad a los propios desarrolladores, por otro lado, más libertad exige más requisitos. Bueno, la búsqueda de errores en un tal fideo de dependencias de múltiples versiones: las calificaciones son un orden o dos más altas que las calificaciones para crear estos mismos errores.


El uso del espacio de nombres en PHP facilita la detección de tales conflictos en el nivel IDE (por ejemplo, hice un segundo archivo con un duplicado de la clase dentro):


imagen


Por lo tanto, la tarea de detectar elementos de código duplicados en un proyecto se vuelve bastante fácil de lograr.


Inicio de código


La función spl_autoload_register en PHP permite al desarrollador no molestarse exactamente con la ubicación de los archivos con las fuentes de sus clases. En cualquier proyecto, puede anular esta función e implementar su propio algoritmo de carga de scripts por nombre de clase. Sin el uso de un espacio de nombres, era necesario escribir nombres bastante rizados para las clases a fin de garantizar su singularidad dentro de un proyecto complejo (especialmente teniendo en cuenta las bibliotecas de terceros). En Zend1 adaptador abstracto para trabajar con la base de datos se definió de la siguiente manera:


 abstract class Zend_Db_Adapter_Abstract {} 

Para garantizar la unicidad, era necesario, en esencia, agregar espacio de nombres al nombre de la clase. Por supuesto, cuando se usan dichos nombres de clase en el código, debe hacer que sus ojos se amplíen más a lo largo de las líneas.


En Zend2 , donde ya se usan espacios de nombres, una definición de clase similar se ve así:


 namespace Zend\Db\Adapter; class Adapter implements ... {} 

El código eventualmente se vuelve más legible, pero el resultado más significativo del uso del espacio de nombres es la posibilidad de unificar la funcionalidad del cargador de clases con el enlace de la jerarquía lógica de clases a la estructura de archivos. Aquí hay un extracto del archivo ./vendor/composer/autoload_namespaces.php que el composer crea en PHP para que ./vendor/autoload.php cargador ./vendor/autoload.php :


 <?php $vendorDir = dirname(dirname(__FILE__)); $baseDir = dirname($vendorDir); return array( 'Zend_' => array($vendorDir . '/magento/zendframework1/library'), 'Yandex' => array($vendorDir . '/allure-framework/allure-codeception/src', $vendorDir . '/allure-framework/allure-php-api/src', $vendorDir . '/allure-framework/allure-php-api/test'), 'Prophecy\\' => array($vendorDir . '/phpspec/prophecy/src'), 'PhpOption\\' => array($vendorDir . '/phpoption/phpoption/src'), 'PhpCollection' => array($vendorDir . '/phpcollection/phpcollection/src'), 'PHPMD\\' => array($vendorDir . '/phpmd/phpmd/src/main/php'), 'OAuth\\Unit' => array($vendorDir . '/lusitanian/oauth/tests'), 'OAuth' => array($vendorDir . '/lusitanian/oauth/src'), ... 

Se puede ver que las fuentes en diferentes bibliotecas se pueden ubicar de diferentes maneras (diferentes estructuras intramódulo), y el composer al formar el proyecto, crea un mapa de superposición de la jerarquía lógica de clases en el sistema de archivos. Y los espacios de nombres juegan un papel importante en esta superposición.


Para evaluar esta función, es suficiente tratar de dividir algunos módulos npm en varios módulos más pequeños y reconstruir su proyecto para usar dos módulos nuevos en lugar de uno grande. Por cierto, la presencia de clases en ES6 y la falta de un espacio de nombres en el sentido de agrupación lógica de código probablemente conducirá a la aparición de nombres similares a los de Zend1 ( Module_Path_To_Class ) en grandes proyectos de ES6 .


IoC


El identificador de objetos en contenedores IoC es una cadena (al menos en PHP ). En ejemplos simples, los identificadores como dbAdapter , dbAdapter , serviceB , etc. son perfectamente aceptables. Pero cuanto más grande es el proyecto, más difícil es searchFilterList dónde se crea el objeto con el identificador, por ejemplo, searchFilterList y dónde se usa. La salida lógica es usar nombres de clase como identificadores para objetos. En este caso, la lógica de crear objetos por el contenedor se vuelve predecible, y el código fuente y los lugares de uso están determinados principalmente por el IDE. El espacio de nombres le permite organizar todas las clases de proyecto en una estructura lógica y usar las rutas apropiadas al crear objetos con un contenedor.


Resumen


A la luz de lo anterior, creo que los lenguajes de programación que usan espacios de nombres de forma nativa para estructurar el código fuente usando la agrupación lógica de sus elementos permiten construir aplicaciones más complejas con menos costo que los lenguajes que no tienen una agrupación lógica. En consecuencia, los desarrolladores con las mismas calificaciones en JavaScript / Python / C / ... no pueden lograr la máxima complejidad de las aplicaciones que se pueden crear en Java / PHP / C++ / ...

Source: https://habr.com/ru/post/es434968/


All Articles