Hace poco terminé una serie en la que cubrí los espacios de nombres y la carga automática en WordPress. Si no está familiarizado con alguno de los términos anteriores, le recomiendo que consulte la serie..
La esencia de lo que puede esperar aprender es la siguiente:
En esta serie, analizaremos exactamente qué son los espacios de nombres de PHP, por qué son beneficiosos y cómo usarlos. Luego, veremos cómo utilizar los autocargadores para cargar automáticamente los archivos que necesitamos sin tener que cargarlos manualmente en nuestro código..
Mientras trabajaba en la serie, específicamente la del cargador automático, no pude evitar reconocer una serie de olores de código que se estaban introduciendo cuando compartía el código contigo..
Esto no quiere decir que el autocargador sea malo o que no funcione. Si ha descargado el complemento, ejecutado o seguido y escrito su propio autocargador, entonces sabe que hace de hecho trabajo.
Pero en una serie que se centra en los espacios de nombres, algo que forma parte de la programación orientada a objetos, no pude evitar sentirme incómodo al dejar el autocargador en su estado final al final de la serie..
No me malinterprete: sigo con la serie, lo que se cubrió y el resultado final de lo que produjimos. Pero desde un punto de vista orientado a objetos, hay más trabajo que se puede hacer. Así que en esta serie de seguimiento, vamos a revisar el concepto de autocargadores desde la perspectiva de la programación orientada a objetos..
Específicamente, vamos a hablar sobre el concepto de:
Espero que para cuando completemos esta serie, no solo habremos refactorizado nuestro autocargador en algo que sea más fácil de mantener y leer, sino que también se adhiere a prácticas más orientadas a objetos..
Dicho esto, vamos a empezar.
Al igual que con casi todas las publicaciones que escribo, me gusta intentar hacer dos cosas:
Antes de comenzar a escribir cualquier código, hagamos eso ahora..
En las siguientes dos publicaciones, vamos a echar un vistazo a algunos conceptos orientados a objetos que nos permitirán mejorar el complemento que construimos en la serie anterior..
Si no tiene una copia de ese complemento, puede descargar una copia del mismo; Sin embargo, compartiré ejemplos completos de código, comentarios y explicaciones a lo largo de cada tutorial..
La serie va a suponer que lo sabes. nada sobre cualquiera de los conceptos que discutiremos, así que comenzaremos desde cero. Todo lo que necesita es tener suficiente software en su máquina para obtener una copia de WordPress en funcionamiento y un editor en el que pueda editar el código..
Para empezar, necesitarás las siguientes herramientas:
Después de tener todo eso en su lugar (y sé que parece mucho, pero en realidad no se configura), deberá instalar una copia del complemento vinculado anteriormente..
Una vez hecho esto, estamos listos para comenzar a hablar sobre interfaces y el principio de responsabilidad única.
Dependiendo de su experiencia en software, cuando escuche la palabra "interfaz", puede terminar pensando en lo que el usuario realmente ve en la pantalla. Ya sabes: una interfaz de usuario.
Pero cuando se trata de diseño orientado a objetos, no estamos hablando de eso del todo. En cambio, estamos hablando de una interfaz de clase. Y esto generalmente se puede describir como la clase y los métodos públicos que expone para que otras clases se comuniquen con ella..
¿Hay una definición más formal? Por supuesto. Wikipedia ofrece uno:
En informática, una interfaz es un límite compartido a través del cual dos componentes separados de un sistema informático intercambian información.
Esto no es tan malo, en realidad. Es lo suficientemente general para aplicar a casi cualquier lenguaje de programación, y no es asi que Tecnico que no podemos entenderlo..
Por otra parte, estamos trabajando con PHP. Entonces, ¿qué tiene que ofrecer el manual de PHP sobre el tema??
Las interfaces de objetos le permiten crear código que especifica qué métodos debe implementar una clase, sin tener que definir cómo se manejan estos métodos.
En mi opinión, esta es una muy buena definición. Es sencillo. Es de lenguaje agnóstico (que yo sepa), y funciona bien en la mayoría de los lenguajes orientados a objetos (si no todos) El manual incluso continúa diciendo:
Las interfaces se definen de la misma manera que una clase, pero con la interfaz palabra clave que sustituye a la clase palabra clave y sin ninguno de los métodos que tienen sus contenidos definidos.
Todos los métodos declarados en una interfaz deben ser públicos; Esta es la naturaleza de una interfaz..
Estos son dos puntos que nosotros debe recuerde si vamos a implementar nuestras propias interfaces, especialmente cuando se trata de este complemento. Es decir, necesitamos recordar lo siguiente:
interfaz
palabra clave.protegido
o privado
) porque esto es lo que garantiza la funcionalidad a la que pueden acceder otras clases.Antes de continuar, ¿cómo podría ser una interfaz en un proyecto de WordPress? Aquí hay un ejemplo de un proyecto en el que he estado trabajando:
El código anterior debe ser claro en cuanto a qué propósito sirve, especialmente dado el comentario que se encuentra sobre la interfaz.
Como todos sabemos, WordPress puede registrar y poner en cola dos tipos de activos: hojas de estilo y archivos JavaScript.
Dado que ambos son activos, sería lógico pensar que cuando creamos clases para la gestión de hojas de estilo o JavaScript, lo generalizaríamos como una interfaz de activos,?
Además, sabemos que queremos inicializar el archivo utilizando un método de inicio para poder conectar la función de puesta en cola especificada a la función de API de WordPress adecuada. Alternativamente, puede haber algún otro trabajo que te gustaría hacer, y si ese es el caso, entonces es posible que desees agregar otra firma de método a la interfaz.
Cualquiera que sea el caso, cualquier clase que implemente esta interfaz debe Proporcionar funcionalidad para los siguientes métodos. Entonces, ¿cómo sería una clase que implementa esta interfaz??
Aquí hay un ejemplo muy simple de una clase que agrega hojas de estilo al área de administración de WordPress:
Ahora cómo Esto se crea y se implementa a través de PHP está fuera del alcance de este tutorial. Lo veremos bastante cuando comencemos a refactorizar nuestro autocargador..
Pero el punto que estoy tratando de mostrar es que una interfaz define los métodos públicos que una clase debe implementar. No define la implementación, pero garantiza que un cierto conjunto de funciones existirá y será accesible públicamente a clases de terceros..
El principio de responsabilidad única
Uno de los desafíos de hablar sobre el principio de responsabilidad única es que a menudo se malinterpreta para significar algo como:
Una clase (o función o rutina) debe hacer una y solo una cosa.Pero eso es un poco equivocado, ¿no? Quiero decir que incluso un simple for loop hace más de una cosa: inicializa un valor, se compara con los valores y luego itera el valor cuando el cuerpo del bucle se completa.
En cambio, el principio establece lo siguiente:
Una clase debe tener una sola razón para cambiar.Debido a que muchos de los desarrolladores de Google aprovechamos Google para ayudarnos en nuestro trabajo diario, creo que es importante entender la fuente de esta idea. Es decir, esto vino del tío Bob Martin, como es conocido casualmente, o Robert Martin, quien es autor de varios libros de programación de primera categoría..
La idea de que una clase tenga una sola razón para cambiar conlleva una gran cantidad de implicaciones, ¿no es así? Aquí hay un ejemplo que viene a la mente de nuestro autocargador tal como está hoy..
Revisemos el código (y sé que no es una clase, es una función, pero el principio es aplicable):
0; $ i--) // Lea el componente actual de la parte del archivo. $ current = strtolower ($ file_parts [$ i]); $ current = str_ireplace ('_', '-', $ current); // Si estamos en la primera entrada, entonces estamos en el nombre de archivo. if (count ($ file_parts) - 1 === $ i) / * Si 'interface' está contenido en las partes del nombre del archivo, entonces * define $ file_name de manera diferente para que se cargue correctamente. * De lo contrario, simplemente establezca $ file_name igual a la de la estructura de * nombre de archivo de clase. * / if (strpos (strtolower ($ file_parts [count ($ file_parts) - 1]), 'interface')) // Coge el nombre de la interfaz de su nombre completo. $ interface_name = explode ('_', $ file_parts [count ($ file_parts) - 1]); $ interface_name = $ interface_name [0]; $ file_name = "interface- $ interface_name.php"; else $ file_name = "class- $ current.php"; else else $ namespace = '/'. $ actual. $ namespace; // Ahora cree una ruta al archivo utilizando la asignación a la ubicación del archivo. $ filepath = trailingslashit (dirname (dirname (__FILE__)). $ namespace); $ filepath. = $ file_name; // Si el archivo existe en la ruta especificada, inclúyalo. if (file_exists ($ filepath)) include_once ($ filepath); else wp_die (esc_html ("El archivo que intenta cargarse en $ filepath no existe."));Ahi esta mucho de cosas que suceden dentro de esta función. Solo mirándolo desde un alto nivel, podemos ver que está haciendo lo siguiente:
Si se supone que una clase solo tiene una razón para cambiar, hay tres razones arriba (y eso es solo en un nivel alto) en las que esta función única podría cambiar. Además, el código podría ser más claro, así como.
No soy alguien para rehuir los comentarios de código, pero hay mucha explicación en el código anterior. Y está bien cuando acabas de comenzar a escribir un autocargador, pero cuando te diriges a un territorio más avanzado como el nuestro, entonces eso no te llevará a arquitecturas más rigurosas..
Aquí es donde las interfaces y el principio de responsabilidad única pueden venir de la mano..
Al igual que una interfaz proporciona un conjunto de firmas de funciones (o un contrato) para lo que proporcionarán sus implementadores, puede garantizar que cualquier clase que implemente esa interfaz se adhiera estrictamente a lo que define.
Pero esto plantea una pregunta interesante: ¿Deberíamos tener múltiples interfaces? Y la respuesta es que depende de la naturaleza de la solución que intenta crear..
En nuestro caso, creo que tiene sentido..
Después de todo, estamos buscando examinar el nombre de una clase entrante y determinar si es una interfaz o una clase, o si merece lanzar un error. Además, buscamos asegurarnos de que se incluya el archivo correcto con el resto del sistema.
Pero eso va más allá del tema de este tutorial en particular y tendremos que explorar con mayor profundidad cuando llegue el momento de escribir más código..
En este punto, hemos cubierto los conceptos necesarios para que podamos comenzar a refactorizar nuestro autocargador. Es decir, estaremos introduciendo una interfaz, asegurándonos de que nuestro código se adhiere a ella, y luego nos aseguraremos de que nuestra clase (o clases) y sus métodos respectivos se adhieran al principio de responsabilidad única.
Además, nos aseguraremos de que continúe funcionando bien dentro del contexto del complemento, esté debidamente documentado y de que cumpla con los estándares de codificación de WordPress..
Mientras tanto, si está interesado en leer más sobre la programación orientada a objetos en el contexto de WordPress, puede encontrar todos mis tutoriales anteriores en mi página de perfil. Siéntete libre de seguirme en mi blog o sígueme en Twitter, donde frecuentemente hablo de ambos..
Como siempre, si está buscando otras utilidades que lo ayuden a desarrollar su creciente conjunto de herramientas para WordPress o, por ejemplo, código para estudiar y tener más experiencia en WordPress, no olvide ver lo que tenemos disponible en Envato Market.
Dicho esto, el próximo tutorial de la serie será mucho más práctico. Es decir, estaremos escribiendo código, refactorizando código existente y aplicando todo lo que hemos aprendido en este tutorial. Hasta entonces, no dudes en dejar tus comentarios en los comentarios..