{"id":230772,"date":"2022-12-14T14:43:00","date_gmt":"2022-12-14T11:43:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=230772"},"modified":"2022-12-14T14:43:26","modified_gmt":"2022-12-14T11:43:26","slug":"widgets-de-wordpress-detecta-la-programacion-orientada-a-objetos","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/es\/widgets-de-wordpress-detecta-la-programacion-orientada-a-objetos\/","title":{"rendered":"Widgets de WordPress: detecta la programaci\u00f3n orientada a objetos"},"content":{"rendered":"\n<p>Si no ha le\u00eddo la primera publicaci\u00f3n de esta serie, se la recomiendo, ya que estamos comenzando a escribir c\u00f3digo orientado a objetos para WordPress mediante el uso de la <strong><a href=\"https:\/\/developer.wordpress.org\/themes\/functionality\/widgets\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">API de Widgets.<\/a><\/strong><\/p>\n<p>La serie va a capturar algunas cosas:<\/p>\n<ol>\n<li>mostrarle el esqueleto b\u00e1sico de un widget y por qu\u00e9 est\u00e1 orientado a objetos,<\/li>\n<li>discuta qu\u00e9 cosas deber\u00eda poder notar y por qu\u00e9<\/li>\n<li>primero actualice el modelo de widget directamente en este sitio y luego env\u00edelo a GitHub,<\/li>\n<li>construya un widget utilizando la API con el modelo como base para nuestro trabajo.<\/li>\n<\/ol>\n<p>Pero antes de hacer eso, quiero asegurarme de que todos los que lean esto est\u00e9n al tanto de los principios b\u00e1sicos de la programaci\u00f3n orientada a objetos y tengan todo lo necesario para crear una soluci\u00f3n orientada a objetos para WordPress.<\/p>\n<p>Para ello, recomiendo lo siguiente:<\/p>\n<ol>\n<li><strong><a href=\"https:\/\/wordpress.mediadoma.com\/es\/los-dos-primeros-pilares-de-la-programacion-orientada-a-objetos\/\" title=\"Dos pilares de la programaci\u00f3n orientada a objetos: Parte 1 de 2\">Dos pilares de la programaci\u00f3n orientada a objetos: Parte 1 de 2<\/a><\/strong><\/li>\n<li><strong><a href=\"https:\/\/wordpress.mediadoma.com\/es\/los-segundos-dos-pilares-de-la-programacion-orientada-a-objetos\/\" title=\"Dos pilares de la programaci\u00f3n orientada a objetos: Parte 2 de 2\">Dos pilares de la programaci\u00f3n orientada a objetos: Parte 2 de 2<\/a><\/strong><\/li>\n<li><strong><a href=\"https:\/\/wordpress.mediadoma.com\/es\/clases-abstractas-parte-1-comportamiento-de-abstraccion\/\" title=\"Clases abstractas, Parte 1: Comportamiento de abstracci\u00f3n\">Clases abstractas, Parte 1: Comportamiento de abstracci\u00f3n<\/a><\/strong><\/li>\n<li><strong><a href=\"https:\/\/wordpress.mediadoma.com\/es\/clases-abstractas-parte-2-clases-abstractas-e-interfaces\/\" title=\"Clases abstractas, Parte 2 - Clases abstractas e interfaces\">Clases abstractas, Parte 2 &#8211; Clases abstractas e interfaces<\/a><\/strong><\/li>\n<li><strong><a href=\"https:\/\/tommcfarlin.com\/tag\/the-independent-wordpress-developer\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">El desarrollador independiente de WordPress<\/a><\/strong><\/li>\n<\/ol>\n<p>Si has le\u00eddo todo ese contenido, genial. Vas a estar bien preparado para esta publicaci\u00f3n y las pr\u00f3ximas publicaciones. Si no es as\u00ed, puede haber algunos agujeros en el resto de lo que est\u00e1 a punto de leer, pero la esencia de la publicaci\u00f3n deber\u00eda ser lo suficientemente clara.<\/p>\n<h3>\u00bfCu\u00e1l es el trato, exactamente?<\/h3>\n<p>Aqu\u00ed est\u00e1 la cuesti\u00f3n: la <strong><a href=\"https:\/\/wordpress.mediadoma.com\/es\/widgets-de-wordpress-un-enfoque-orientado-a-objetos\/\" title=\"semana pasada\">semana pasada<\/a><\/strong>, compart\u00ed un poco de c\u00f3digo junto con informaci\u00f3n sobre la <strong><a href=\"https:\/\/developer.wordpress.org\/themes\/functionality\/widgets\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">API de Widgets<\/a><\/strong>. Voy a revisar eso un poco m\u00e1s en esta publicaci\u00f3n antes de entrar en la parte m\u00e1s intensiva de codificaci\u00f3n por dos razones:<\/p>\n<ol>\n<li>Quiero que todos los que lean esto est\u00e9n en la misma p\u00e1gina en lo que se refiere a escribir c\u00f3digo orientado a objetos (al menos, en este contexto),<\/li>\n<li>Reconozco que las personas provienen de diferentes or\u00edgenes y quiero asegurarme de que todos estemos en la misma p\u00e1gina tanto como sea posible antes de continuar.<\/li>\n<\/ol>\n<p>Si tiene experiencia escribiendo c\u00f3digo orientado a objetos, especialmente en una capacidad avanzada, esto puede parecerle m\u00e1s simple; de lo contrario, espero que esto lo brinde todo lo que necesita para detectar pr\u00e1cticas orientadas a objetos no solo con respecto a esta API sino tambi\u00e9n al leer el c\u00f3digo de otros.<\/p>\n<h2>C\u00f3mo detectar la programaci\u00f3n orientada a objetos<\/h2>\n<p>Quiz\u00e1s una primera pregunta natural es \u00bfpor qu\u00e9 necesitamos poder detectar, leer o comprender la programaci\u00f3n orientada a objetos antes de escribirla?<\/p>\n<h3>Una palabra sobre el c\u00f3digo incorrecto<\/h3>\n<p>La respuesta corta a eso es esta:<\/p>\n<p>No es necesario, pero es \u00fatil. Si puede leer programaci\u00f3n orientada a objetos, tendr\u00e1 una ventaja inicial para aprovechar lo que ofrece como paradigma porque se basar\u00e1 en las estrategias y el trabajo realizado por otros en otros proyectos.<\/p>\n<p>Esto no significa que no leeremos el c\u00f3digo incorrecto, pero haremos lo que podamos para identificar el c\u00f3digo incorrecto, identificar las \u00e1reas problem\u00e1ticas y luego hacer lo que podamos para evitar incorporarlo en nuestro trabajo.<\/p>\n<p>Sin embargo, por ahora, echemos un vistazo a la <strong><a href=\"https:\/\/developer.wordpress.org\/themes\/functionality\/widgets\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">API de Widgets<\/a><\/strong> para ver qu\u00e9 podemos hacer para detectar la programaci\u00f3n orientada a objetos.<\/p>\n<h3>Volver a Programaci\u00f3n Orientada a Objetos<\/h3>\n<p>En la publicaci\u00f3n anterior, describ\u00ed dos cosas que indican que la API est\u00e1 orientada a objetos (al menos hasta cierto punto):<\/p>\n<ol>\n<li>el uso de la palabra clave <strong>extends<\/strong> ,<\/li>\n<li>funciones que debemos implementar.<\/li>\n<\/ol>\n<p>La raz\u00f3n 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\u00f3n a objetos: la <strong><a href=\"https:\/\/php.net\/manual\/en\/language.oop5.inheritance.php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">herencia<\/a><\/strong> y la implementaci\u00f3n de funciones (que a menudo forman parte de <strong><a href=\"https:\/\/php.net\/manual\/en\/language.oop5.abstract.php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">las clases abstractas<\/a><\/strong> ).<\/p>\n<p>Una nota antes de que veamos lo anterior:<\/p>\n<p>Cuando mire <strong><a href=\"https:\/\/developer.wordpress.org\/reference\/classes\/wp_widget\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">la fuente de la clase WP_Widget<\/a><\/strong>, notar\u00e1 que no hay m\u00e9todos abstractos. Pero algunas de las funciones que debemos implementar, que mencionar\u00e9 m\u00e1s adelante en esta publicaci\u00f3n, son candidatas principales para m\u00e9todos abstractos. Y discutir\u00e9 por qu\u00e9, tambi\u00e9n.<\/p>\n<p>Separemos los temas anteriores en dos secciones separadas: herencia y abstracciones.<\/p>\n<h3>Herencia<\/h3>\n<p>Cubr\u00ed la profundidad relativa de la herencia <strong><a href=\"https:\/\/wordpress.mediadoma.com\/es\/widgets-de-wordpress-un-enfoque-orientado-a-objetos\/\" title=\"en la publicaci\u00f3n anterior\">en la publicaci\u00f3n anterior<\/a><\/strong>, por lo que no profundizar\u00e9 en el punto aqu\u00ed. Ofrecer\u00e9 algunas palabras, pero estoy mucho m\u00e1s interesado en discutir la abstracci\u00f3n, lo cual har\u00e9 en un momento.<\/p>\n<p>Sin embargo, antes de profundizar demasiado en esto, consulte <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/ea73655b0a022d65317529930cbb0cad#file-00-widget-base-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">el siguiente c\u00f3digo:<\/a><\/strong><\/p>\n<pre><code>&lt;?php\nclass AcmeWidget extends WP_Widget \n{ \n    public function __construct() \n    {\n    }\n\n    public function widget($args, $instance) \n    {\n    }\n\n    public function form($instance)\n    {\n    }\n\n    public function update($newInstance, $oldInstance)\n    {\n    }\n}<\/code><\/pre>\n<p>Pero primero, podemos reconocer que cualquier clase que implemente la API de Widgets debe usar la herencia simplemente por la palabra clave <strong>extends<\/strong>.<\/p>\n<p>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.<\/p>\n<p>Del <strong><a href=\"https:\/\/php.net\/manual\/en\/language.oop5.inheritance.php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">manual de PHP<\/a><\/strong> :<\/p>\n<blockquote>\n<p>Por ejemplo, cuando ampl\u00eda una clase, la subclase hereda todos los m\u00e9todos p\u00fablicos y protegidos de la clase principal. A menos que una clase anule esos m\u00e9todos, conservar\u00e1n su funcionalidad original.<\/p>\n<\/blockquote>\n<p>Sin embargo, cuando hereda la funcionalidad de una clase, puede encontrar que es importante llamar estrictamente al constructor del padre (en nuestra funci\u00f3n <strong>__construct<\/strong> ).<\/p>\n<p>Pero esto plantea lo que creo que es uno de los problemas m\u00e1s importantes con la herencia en PHP (y la raz\u00f3n por la que quer\u00eda incluir esta secci\u00f3n): \u00bfNecesitamos llamar expl\u00edcitamente al constructor padre?<\/p>\n<p>Tambi\u00e9n seg\u00fan <strong><a href=\"http:\/\/www.php.net\/manual\/en\/language.oop5.decon.php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">el manual:<\/a><\/strong><\/p>\n<blockquote>\n<p>Los constructores principales no se llaman impl\u00edcitamente si la clase secundaria define un constructor. Para ejecutar un constructor principal, se requiere una llamada a <strong>parent::__construct()<\/strong> dentro del constructor secundario. Si el hijo no define un constructor, entonces puede ser heredado de la clase padre como un m\u00e9todo de clase normal (si no fue declarado como privado).<\/p>\n<\/blockquote>\n<p>Pero podemos simplificar esto. Quiz\u00e1s esto sea m\u00e1s f\u00e1cil de recordar:<\/p>\n<ol>\n<li>Si nuestra clase usa herencia pero no define un constructor, se llama al constructor padre.<\/li>\n<li>Si nuestra clase usa herencia pero define un constructor, la construcci\u00f3n principal debe llamarse expl\u00edcitamente.<\/li>\n<\/ol>\n<p>O tal vez incluso m\u00e1s simplemente:<\/p>\n<ul>\n<li>Si nuestra clase no define un constructor, el c\u00f3digo por defecto ser\u00e1 el constructor de los padres.<\/li>\n<\/ul>\n<p>\u00bfTener sentido? En resumen, si definimos nuestras propiedades, inicializaci\u00f3n y c\u00f3digo en un constructor, la primera l\u00ednea del constructor de nuestra clase deber\u00eda ser una llamada al constructor principal.<\/p>\n<h3>Abstracci\u00f3n<\/h3>\n<p>Para ser absolutamente claro, el c\u00f3digo fuente de la clase <strong>WP_Widget<\/strong> no incluye m\u00e9todos abstractos. Parte de esto tiene que ver con c\u00f3mo se construye la clase, parte de esto tiene que ver con la compatibilidad con versiones anteriores y las caracter\u00edsticas de PHP5.<\/p>\n<p>Sin embargo, esto no significa que no podamos identificar qu\u00e9 funciones podr\u00edan marcarse como <strong>abstract<\/strong>. De hecho, creo que explica qu\u00e9 clases deber\u00edan hacerse abstractas. Pero primero, definamos funciones abstractas.<\/p>\n<p><strong><a href=\"https:\/\/php.net\/manual\/en\/language.oop5.abstract.php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">Del manual<\/a><\/strong> :<\/p>\n<blockquote>\n<p>Al heredar de una clase abstracta, todos los m\u00e9todos marcados como abstractos en la declaraci\u00f3n de clase del padre deben ser definidos por el hijo; adem\u00e1s, estos m\u00e9todos deben definirse con la misma (o menos restringida) visibilidad.<\/p>\n<\/blockquote>\n<p>Al mirar la fuente de nuestro widget:<\/p>\n<pre><code>&lt;?php\nclass AcmeWidget extends WP_Widget \n{ \n    public function __construct() \n    {\n    }\n\n    public function widget($args, $instance) \n    {\n    }\n\n    public function form($instance)\n    {\n    }\n\n    public function update($newInstance, $oldInstance)\n    {\n    }\n}<\/code><\/pre>\n<p>Creo que es justo decir que la funci\u00f3n de <strong>formulario<\/strong> podr\u00eda marcarse como <strong>abstracta<\/strong> porque es exclusiva de nuestra implementaci\u00f3n. Otra forma de pensar en las funciones abstractas desde el punto de vista de la programaci\u00f3n es preguntarse: \u00bfQu\u00e9 funciones requerir\u00e1n una funcionalidad \u00fanica?<\/p>\n<p>Y en este caso, la funci\u00f3n de <strong>formulario<\/strong> es precisamente eso porque cada widget ser\u00e1 diferente de manera \u00fanica con respecto a lo que representa. La funci\u00f3n de <strong>widget<\/strong> tambi\u00e9n podr\u00eda marcarse como abstracta porque genera el contenido del widget. Este contenido, naturalmente, se basa en la funcionalidad que hemos implementado en nuestra implementaci\u00f3n.<\/p>\n<p>Adem\u00e1s, el c\u00f3digo fuente de la propia clase <strong>WP_Widget<\/strong> dice:<\/p>\n<blockquote>\n<p>la funci\u00f3n WP_Widget::widget() debe anularse en una subclase.&#8217;<\/p>\n<\/blockquote>\n<p>Este es precisamente el tipo de funci\u00f3n que debe marcarse como abstracta. Porque PHP arrojar\u00e1 un error si una funci\u00f3n se marca como abstracta y no se implementa. No necesit\u00e1bamos ninguna funci\u00f3n de <strong>troquel<\/strong> ni nada por el estilo.<\/p>\n<p>Sin embargo, las otras funciones no necesariamente tendr\u00e1n que marcarse como abstractas y he aqu\u00ed por qu\u00e9:<\/p>\n<ol>\n<li><strong>__construct<\/strong> llamar\u00e1 al constructor del padre, en el nivel m\u00e1s b\u00e1sico, y esto es necesario para inicializar la clase base. Sin embargo, no olvides; podemos agregar nuestras propiedades a este m\u00e9todo que son \u00fanicas para nuestra clase.<\/li>\n<li><strong>update\u00a0<\/strong> usa la funcionalidad en la clase principal para serializar informaci\u00f3n.<\/li>\n<\/ol>\n<p>Por lo tanto, nos quedan dos funciones que podr\u00edan marcarse como abstractas en una iteraci\u00f3n m\u00e1s moderna de la clase.<\/p>\n<h2>Siguiente<\/h2>\n<p>En este punto, todos deber\u00edamos estar en la misma p\u00e1gina en lo que se refiere al c\u00f3digo orientado a objetos. Al menos hasta donde podemos llegar a trav\u00e9s de una serie de publicaciones de blog.<\/p>\n<p>A partir de la pr\u00f3xima publicaci\u00f3n, volveremos a escribir c\u00f3digo.<\/p>\n<p>Es decir, revisaremos el modelo est\u00e1ndar de <strong><a href=\"https:\/\/github.com\/tommcfarlin\/WordPress-Widget-Boilerplate\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">widgets de WordPress<\/a><\/strong> y lo refactorizaremos en su estado actual para adoptar est\u00e1ndares de PHP m\u00e1s modernos.<\/p>\n<p><a href=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-161697-61e7280e064dc.png\" data-rel=\"lightbox\"><img decoding=\"async\" class=\"SDStudio-light-box-enable SDStudio-editor-tools-md-imp\" src=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-161697-61e7280e064dc.png\" alt=\"Widgets de WordPress: detecta la programaci\u00f3n orientada a objetos\"><\/a><\/p>\n<p>Voy a compartir los cambios que estoy haciendo, las justificaciones de por qu\u00e9, y luego tambi\u00e9n hablar\u00e9 sobre el tipo de widget que vamos a construir en base al modelo est\u00e1ndar (y podemos hacerlo).<\/p>\n<p><div id=\"PostUnique_PostSource\" style=\"padding-top: 50px\">Fuente de grabaci\u00f3n:  <a target=\"_blank\" rel=\"noopener nofollow\" href=\"\/\/tommcfarlin.com\" class=\"external external_icon\">tommcfarlin.com<\/a><\/div><\/p>\n","protected":false},"excerpt":{"rendered":"<p>El objetivo es armarte con todo lo que necesitas para detectar pr\u00e1cticas orientadas a objetos tanto en esta API como en otras.<\/p>\n","protected":false},"author":1,"featured_media":235594,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_wp_rev_ctl_limit":""},"categories":[892,716,800,861],"tags":[1172],"class_list":["post-230772","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-codigo","category-desarrollador","category-php-2","category-wordpress-2","tag-affiai-es"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/posts\/230772","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/comments?post=230772"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/posts\/230772\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/media\/235594"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/media?parent=230772"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/categories?post=230772"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/tags?post=230772"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}