Widgets de WordPress: detecta la programación orientada a objetos
Si no ha leído la primera publicación de esta serie, se la recomiendo, ya que estamos comenzando a escribir código orientado a objetos para WordPress mediante el uso de la API de Widgets.
La serie va a capturar algunas cosas:
- mostrarle el esqueleto básico de un widget y por qué está orientado a objetos,
- discuta qué cosas debería poder notar y por qué
- primero actualice el modelo de widget directamente en este sitio y luego envíelo a GitHub,
- construya un widget utilizando la API con el modelo como base para nuestro trabajo.
Pero antes de hacer eso, quiero asegurarme de que todos los que lean esto estén al tanto de los principios básicos de la programación orientada a objetos y tengan todo lo necesario para crear una solución orientada a objetos para WordPress.
Para ello, recomiendo lo siguiente:
- Dos pilares de la programación orientada a objetos: Parte 1 de 2
- Dos pilares de la programación orientada a objetos: Parte 2 de 2
- Clases abstractas, Parte 1: Comportamiento de abstracción
- Clases abstractas, Parte 2 – Clases abstractas e interfaces
- El desarrollador independiente de WordPress
Si has leído todo ese contenido, genial. Vas a estar bien preparado para esta publicación y las próximas publicaciones. Si no es así, puede haber algunos agujeros en el resto de lo que está a punto de leer, pero la esencia de la publicación debería ser lo suficientemente clara.
¿Cuál es el trato, exactamente?
Aquí está la cuestión: la semana pasada, compartí un poco de código junto con información sobre la API de Widgets. Voy a revisar eso un poco más en esta publicación antes de entrar en la parte más intensiva de codificación por dos razones:
- Quiero que todos los que lean esto estén en la misma página en lo que se refiere a escribir código orientado a objetos (al menos, en este contexto),
- Reconozco que las personas provienen de diferentes orígenes y quiero asegurarme de que todos estemos en la misma página tanto como sea posible antes de continuar.
Si tiene experiencia escribiendo código orientado a objetos, especialmente en una capacidad avanzada, esto puede parecerle más simple; de lo contrario, espero que esto lo brinde todo lo que necesita para detectar prácticas orientadas a objetos no solo con respecto a esta API sino también al leer el código de otros.
Cómo detectar la programación orientada a objetos
Quizás una primera pregunta natural es ¿por qué necesitamos poder detectar, leer o comprender la programación orientada a objetos antes de escribirla?
Una palabra sobre el código incorrecto
La respuesta corta a eso es esta:
No es necesario, pero es útil. Si puede leer programación orientada a objetos, tendrá una ventaja inicial para aprovechar lo que ofrece como paradigma porque se basará en las estrategias y el trabajo realizado por otros en otros proyectos.
Esto no significa que no leeremos el código incorrecto, pero haremos lo que podamos para identificar el código incorrecto, identificar las áreas problemáticas y luego hacer lo que podamos para evitar incorporarlo en nuestro trabajo.
Sin embargo, por ahora, echemos un vistazo a la API de Widgets para ver qué podemos hacer para detectar la programación orientada a objetos.
Volver a Programación Orientada a Objetos
En la publicación anterior, describí dos cosas que indican que la API está orientada a objetos (al menos hasta cierto punto):
- el uso de la palabra clave extends ,
- funciones que debemos implementar.
La razón por la que quiero volver a visitar este tema es que identifica dos elementos clave que forman parte de los principios fundamentales de la orientación a objetos: la herencia y la implementación de funciones (que a menudo forman parte de las clases abstractas ).
Una nota antes de que veamos lo anterior:
Cuando mire la fuente de la clase WP_Widget, notará que no hay métodos abstractos. Pero algunas de las funciones que debemos implementar, que mencionaré más adelante en esta publicación, son candidatas principales para métodos abstractos. Y discutiré por qué, también.
Separemos los temas anteriores en dos secciones separadas: herencia y abstracciones.
Herencia
Cubrí la profundidad relativa de la herencia en la publicación anterior, por lo que no profundizaré en el punto aquí. Ofreceré algunas palabras, pero estoy mucho más interesado en discutir la abstracción, lo cual haré en un momento.
Sin embargo, antes de profundizar demasiado en esto, consulte el siguiente código:
<?php
class AcmeWidget extends WP_Widget
{
public function __construct()
{
}
public function widget($args, $instance)
{
}
public function form($instance)
{
}
public function update($newInstance, $oldInstance)
{
}
}
Pero primero, podemos reconocer que cualquier clase que implemente la API de Widgets debe usar la herencia simplemente por la palabra clave extends.
Esto significa que hay un nivel de funcionalidad que vamos a heredar (u obtener gratis) y hay un nivel de funcionalidad que debemos implementar por nuestra cuenta.
Del manual de PHP :
Por ejemplo, cuando amplía una clase, la subclase hereda todos los métodos públicos y protegidos de la clase principal. A menos que una clase anule esos métodos, conservarán su funcionalidad original.
Sin embargo, cuando hereda la funcionalidad de una clase, puede encontrar que es importante llamar estrictamente al constructor del padre (en nuestra función __construct ).
Pero esto plantea lo que creo que es uno de los problemas más importantes con la herencia en PHP (y la razón por la que quería incluir esta sección): ¿Necesitamos llamar explícitamente al constructor padre?
También según el manual:
Los constructores principales no se llaman implícitamente si la clase secundaria define un constructor. Para ejecutar un constructor principal, se requiere una llamada a parent::__construct() dentro del constructor secundario. Si el hijo no define un constructor, entonces puede ser heredado de la clase padre como un método de clase normal (si no fue declarado como privado).
Pero podemos simplificar esto. Quizás esto sea más fácil de recordar:
- Si nuestra clase usa herencia pero no define un constructor, se llama al constructor padre.
- Si nuestra clase usa herencia pero define un constructor, la construcción principal debe llamarse explícitamente.
O tal vez incluso más simplemente:
- Si nuestra clase no define un constructor, el código por defecto será el constructor de los padres.
¿Tener sentido? En resumen, si definimos nuestras propiedades, inicialización y código en un constructor, la primera línea del constructor de nuestra clase debería ser una llamada al constructor principal.
Abstracción
Para ser absolutamente claro, el código fuente de la clase WP_Widget no incluye métodos abstractos. Parte de esto tiene que ver con cómo se construye la clase, parte de esto tiene que ver con la compatibilidad con versiones anteriores y las características de PHP5.
Sin embargo, esto no significa que no podamos identificar qué funciones podrían marcarse como abstract. De hecho, creo que explica qué clases deberían hacerse abstractas. Pero primero, definamos funciones abstractas.
Al heredar de una clase abstracta, todos los métodos marcados como abstractos en la declaración de clase del padre deben ser definidos por el hijo; además, estos métodos deben definirse con la misma (o menos restringida) visibilidad.
Al mirar la fuente de nuestro widget:
<?php
class AcmeWidget extends WP_Widget
{
public function __construct()
{
}
public function widget($args, $instance)
{
}
public function form($instance)
{
}
public function update($newInstance, $oldInstance)
{
}
}
Creo que es justo decir que la función de formulario podría marcarse como abstracta porque es exclusiva de nuestra implementación. Otra forma de pensar en las funciones abstractas desde el punto de vista de la programación es preguntarse: ¿Qué funciones requerirán una funcionalidad única?
Y en este caso, la función de formulario es precisamente eso porque cada widget será diferente de manera única con respecto a lo que representa. La función de widget también podría marcarse como abstracta porque genera el contenido del widget. Este contenido, naturalmente, se basa en la funcionalidad que hemos implementado en nuestra implementación.
Además, el código fuente de la propia clase WP_Widget dice:
la función WP_Widget::widget() debe anularse en una subclase.’
Este es precisamente el tipo de función que debe marcarse como abstracta. Porque PHP arrojará un error si una función se marca como abstracta y no se implementa. No necesitábamos ninguna función de troquel ni nada por el estilo.
Sin embargo, las otras funciones no necesariamente tendrán que marcarse como abstractas y he aquí por qué:
- __construct llamará al constructor del padre, en el nivel más básico, y esto es necesario para inicializar la clase base. Sin embargo, no olvides; podemos agregar nuestras propiedades a este método que son únicas para nuestra clase.
- update usa la funcionalidad en la clase principal para serializar información.
Por lo tanto, nos quedan dos funciones que podrían marcarse como abstractas en una iteración más moderna de la clase.
Siguiente
En este punto, todos deberíamos estar en la misma página en lo que se refiere al código orientado a objetos. Al menos hasta donde podemos llegar a través de una serie de publicaciones de blog.
A partir de la próxima publicación, volveremos a escribir código.
Es decir, revisaremos el modelo estándar de widgets de WordPress y lo refactorizaremos en su estado actual para adoptar estándares de PHP más modernos.
Voy a compartir los cambios que estoy haciendo, las justificaciones de por qué, y luego también hablaré sobre el tipo de widget que vamos a construir en base al modelo estándar (y podemos hacerlo).
