{"id":229525,"date":"2022-11-04T12:26:00","date_gmt":"2022-11-04T09:26:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=229525"},"modified":"2022-11-09T08:21:49","modified_gmt":"2022-11-09T05:21:49","slug":"prototipagem-rapida-prototipo-para-codigo-parte-2","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/pt-pt\/prototipagem-rapida-prototipo-para-codigo-parte-2\/","title":{"rendered":"Prototipagem R\u00e1pida: Prot\u00f3tipo para C\u00f3digo, Parte 2"},"content":{"rendered":"\n<p><a href=\"https:\/\/wordpress.mediadoma.com\/pt-pt\/prototipagem-rapida-prototipo-para-codigo-parte-1\/\" title=\"O post anterior\" >O post anterior<\/a> demonstra muito trabalho em pegar algo que j\u00e1 foi um prot\u00f3tipo r\u00e1pido e levar esse prot\u00f3tipo para o c\u00f3digo. Se voc\u00ea n\u00e3o tem acompanhado, fizemos o seguinte:<\/p>\n<ol>\n<li>conversamos e constru\u00edmos um prot\u00f3tipo para um plugin,<\/li>\n<li>diagramada uma abordagem orientada a objetos pode funcionar,<\/li>\n<li>e refatoramos nosso prot\u00f3tipo para c\u00f3digo real.<\/li>\n<\/ol>\n<p>Neste ponto, h\u00e1 mais algumas coisas que podemos fazer para melhorar nosso c\u00f3digo. Ou seja, podemos introduzir o conceito de namespaces. Isso leva a organiza\u00e7\u00e3o um passo adiante e pode pagar dividendos para projetos maiores.<\/p>\n<p>Ent\u00e3o, aqui est\u00e1 uma olhada em como isso se desenrola em nosso projeto atual.<\/p>\n<h2>Prot\u00f3tipo para c\u00f3digo: namespaces<\/h2>\n<p>Eu cobri namespaces em profundidade em posts anteriores. Se voc\u00ea n\u00e3o leu, <a href=\"https:\/\/wordpress.mediadoma.com\/pt-pt\/namespaces-e-carregamento-automatico-no-wordpress\/\" title=\"eu recomendo\" >eu recomendo<\/a>. Depois volte e confira o restante do post.<\/p>\n<p>Se voc\u00ea optar por pular o artigo, aqui est\u00e1 <a href=\"https:\/\/php.net\/manual\/en\/language.namespaces.rationale.php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">uma breve defini\u00e7\u00e3o de um namespace<\/a> :<\/p>\n<blockquote>\n<p>Os namespaces s\u00e3o projetados para resolver dois problemas que os autores de bibliotecas e aplicativos encontram ao criar elementos de c\u00f3digo reutiliz\u00e1veis, como classes ou fun\u00e7\u00f5es\u2026<\/p>\n<\/blockquote>\n<p>E a ideia geral \u00e9 que organizemos nossas classes com base em uma rela\u00e7\u00e3o l\u00f3gica que elas t\u00eam umas com as outras.<\/p>\n<p>Al\u00e9m disso, tamb\u00e9m organizamos os arquivos em diret\u00f3rios que correspondem ao namespace. Isso n\u00e3o \u00e9 algo que precisa ser feito, mas acho que ajuda ter as classes organizadas logicamente no disco da maneira como s\u00e3o organizadas virtualmente no namespace.<\/p>\n<p>Dito isso, vamos organizar os arquivos.<\/p>\n<h3>Organizando os arquivos<\/h3>\n<p>Em vez de come\u00e7ar com o arquivo de plugin principal, vamos come\u00e7ar organizando nossos arquivos primeiro.<\/p>\n<ul>\n<li>Os arquivos Meta Box e Meta Box Display residir\u00e3o em um diret\u00f3rio chamado <strong>Display<\/strong>. Isso \u00e9 completamente arbitr\u00e1rio, mas como \u00e9 isso que esses arquivos fazem, parece fazer sentido que seja onde eles residam.<\/li>\n<li>Tamb\u00e9m podemos colocar os arquivos <strong>message-description.php<\/strong> e <strong>no-post-list.php<\/strong> nesse diret\u00f3rio, mas vamos coloc\u00e1-los em um subdiret\u00f3rio chamado <strong>Views<\/strong>. Voc\u00ea pode chamar isso de <strong>Templates<\/strong> ou <strong>Partials<\/strong> ou algo similar.<\/li>\n<li>Em seguida, temos as classes respons\u00e1veis \u200b\u200bpor consultar o banco de dados e a classe respons\u00e1vel por coordenar as mensagens. Vamos colocar cada um deles em <strong>Utility.<\/strong> Existem outros lugares que eles podem ir, com certeza, mas lembre-se de que o objetivo \u00e9 demonstrar como usar namespaces. Ent\u00e3o, se voc\u00ea se sentir t\u00e3o inclinado, sinta-se \u00e0 vontade para ajustar seus arquivos para se adequar ao seu gosto.<\/li>\n<\/ul>\n<p>Se voc\u00ea seguiu o que temos acima, voc\u00ea deve ter uma estrutura de diret\u00f3rios parecida com esta:<\/p>\n<p>Uma maneira de organizar seus arquivos.<\/p>\n<p>Agora \u00e9 hora de definir namespaces para cada uma das classes. Como organizamos todos eles em seus diret\u00f3rios, ser\u00e1 f\u00e1cil especificar um namespace; no entanto, \u00e9 importante reconhecer que precisaremos usar a\u00a0 palavra-chave <strong><a href=\"https:\/\/php.net\/manual\/en\/language.namespaces.importing.php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">use<\/a><\/strong> quando estivermos usando classes localizadas em outros namespaces.<\/p>\n<p>Vamos passar por cada um dos nossos arquivos come\u00e7ando com os arquivos em <strong>Utility<\/strong>. Primeiro, vamos come\u00e7ar com o <a href=\"https:\/\/gist.github.com\/tommcfarlin\/38c72277ddbd0fa70a74c03598070703#file-00-post-messenger-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">Post Messenger<\/a> :<\/p>\n<pre><code>&lt;?php\n\/**\n * Display content for the meta box when requested.\n *\n * @author Tom McFarlin\n * @since  0.2.0\n *\/\n\nnamespace McFarlinTRPUtility;\nuse McFarlinTRPUtilityPost_Query;\n\n\/**\n * Retrieves information from the class responsible for querying the database and\n * renders it in the context of our meta box when called via the Meta Box Display.\n *\n * @author Tom McFarlin\n * @since  0.2.0\n *\/\nclass Post_Messenger {\n  \/\/ Snip for brevity. \n}<\/code><\/pre>\n<p>Voc\u00ea notar\u00e1 que o namespace do arquivo aparece no cabe\u00e7alho junto com uma declara\u00e7\u00e3o para usar a\u00a0 classe <strong>Post Query<\/strong> que criamos. Anexei o nome da classe ao final do namespace, para n\u00e3o precisar us\u00e1-lo em toda a base de c\u00f3digo.<\/p>\n<p>Observe que o construtor agora se parece <a href=\"https:\/\/gist.github.com\/tommcfarlin\/38c72277ddbd0fa70a74c03598070703#file-01-post-messenger-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">com isso<\/a> :<\/p>\n<pre><code>&lt;?php\n\n\/**\n * Instantiates the class by setting a reference to the query.\n *\n * @param string $plugin_dir The path to the root of the plugin directory.\n *\/\npublic function __construct( $plugin_dir) {\n\n    $this-&gt;query      = new Post_Query();\n    $this-&gt;plugin_dir = trailingslashit( $plugin_dir );\n}<\/code><\/pre>\n<p>Eu adicionei um\u00a0 argumento <strong>$plugin_dir<\/strong> porque precisamos usar isso para exibir os resultados da consulta corretamente. E como eles agora residem em uma \u00e1rea diferente do aplicativo, as fun\u00e7\u00f5es se parecem <a href=\"https:\/\/gist.github.com\/tommcfarlin\/38c72277ddbd0fa70a74c03598070703#file-02-post-messenger-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">com isso<\/a> :<\/p>\n<pre><code>&lt;?php\n\n\/**\n * Displays the description of the content of the meta box.\n *\n * @access private\n *\/\nprivate function get_post_message() {\n    include_once $this-&gt;plugin_dir. 'Display\/Views\/post-list.php';\n}\n\n\/**\n * Displays the description of the content of the meta box.\n *\n * @access private\n *\/\nprivate function get_description() {\n    include_once $this-&gt;plugin_dir. 'Display\/Views\/message-description.php';\n}\n\n\/**\n * Displays a message of there are no recent posts.\n *\n * @access private\n *\/\nprivate function get_no_posts_message() {\n    include_once $this-&gt;plugin_dir. 'Display\/Views\/no-post-list.php';\n}<\/code><\/pre>\n<p>Em seguida, vamos ver a\u00a0 classe <a href=\"https:\/\/gist.github.com\/tommcfarlin\/38c72277ddbd0fa70a74c03598070703#file-03-post-query-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">Post Query<\/a>. Nada mudou muito nesta classe, exceto que demos a ela um namespace e tamb\u00e9m atualizamos a consulta apenas para retirar tr\u00eas postagens (conforme <a href=\"https:\/\/tommcfarlin.com\/prototype-to-code-1\/#comment-911828\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">este coment\u00e1rio<\/a> ).<\/p>\n<pre><code>&lt;?php\n\nnamespace McFarlinTRPUtility;\n\n\/**\n * Queries the database for three most recent posts. Returns the query to the\n * caller so that it can be interrogates for posts or not.\n *\n * @author Tom McFarlin\n * @since  0.2.0\n *\/\nclass Post_Query {\n\n  \/\/ Snip for brevity.\n\n    private function get_posts() {\n\n        $args = array(\n            'post_type'        =&gt; 'post',\n            'post_status'      =&gt; 'publish',\n            'posts_per_page' =&gt; 3,\n            'orderby'          =&gt; 'date',\n            'order'            =&gt; 'desc',\n        );\n        $this-&gt;query = new WP_Query( $args );\n\n        return $this-&gt;query;\n    }\n}<\/code><\/pre>\n<p>Observe no c\u00f3digo que tamb\u00e9m pr\u00e9-fixei <a href=\"https:\/\/codex.wordpress.org\/Class_Reference\/WP_Query\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">WP_Query<\/a> com uma barra porque faz parte do namespace global.<\/p>\n<p>Vamos entrar no\u00a0 diret\u00f3rio <strong>Display<\/strong> e dar uma olhada na <a href=\"https:\/\/gist.github.com\/tommcfarlin\/38c72277ddbd0fa70a74c03598070703#file-04-meta-box-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">classe Meta Box<\/a>. Isso tamb\u00e9m recebeu um namespace e tamb\u00e9m est\u00e1 usando o nome totalmente qualificado da\u00a0 classe <strong>Meta Box Display<\/strong> que veremos momentaneamente.<\/p>\n<pre><code>&lt;?php\n\n namespace McFarlinTRPDisplay;\n use McFarlinTRPDisplayMeta_Box_Display;\n\n\/**\n * Registers the Meta Box with WordPress. Defines the ID, title, display function,\n * and the post type on which it will live.\n *\n * @author Tom McFarlin\n * @since  0.2.0\n *\/\nclass Meta_Box {\n\n    \/**\n     * A reference to the class that will display the contents in the meta box.\n     *\n     * @access private\n     * @var    Meta_Box_Display\n     *\/\n    private $meta_box_display;\n\n    \/**\n     * Instantiates the class by setting its property equal to a reference to its display.\n     *\n     * @param string $plugin_dir A reference to the root of the plugin's directory.\n     *\/\n    public function __construct( $plugin_dir) {\n        $this-&gt;meta_box_display = new Meta_Box_Display( $plugin_dir );\n    }\n\n    \/\/ Snip for brevity.\n}<\/code><\/pre>\n<p>Observe que este construtor tamb\u00e9m aceita o diret\u00f3rio do plugin como um argumento e o passa para a\u00a0 classe <strong>Meta Box Display<\/strong> tamb\u00e9m. Isto \u00e9 para que as fun\u00e7\u00f5es respons\u00e1veis \u200b\u200bpor exibir as mensagens possam ser encontradas corretamente em sua localiza\u00e7\u00e3o no\u00a0 diret\u00f3rio <strong>Views<\/strong>.<\/p>\n<p>Finalmente, vamos revisar a\u00a0 classe <strong>Meta Box Display<\/strong>. Esta \u00e9 uma classe simples que inclui o namespace e faz refer\u00eancia ao <strong>Post Messenger<\/strong> que analisamos acima.<\/p>\n<pre><code>&lt;?php\n\/**\n * Defines the display for the meta box.\n *\n * @author Tom McFarlin\n * @since  0.2.0\n *\/\n\nnamespace McFarlinTRPDisplay;\nuse McFarlinTRPUtilityPost_Messenger;\n\n\/**\n * Defines the display for the meta box that will render the content in the\n * context of its meta box.\n *\n * @author Tom McFarlin\n * @since  0.2.0\n *\/\nclass Meta_Box_Display {\n\n    \/**\n     * A reference to the class that will display the contents in the meta box.\n     *\n     * @access private\n     * @var    Post_Messenger\n     *\/\n    private $messenger;\n\n    \/**\n     * Instantiates the object by setting a property equal to that of the class\n     * responsible for rendering the messages from the post query.\n     *\n     * @param string $plugin_dir A reference to the root of the plugin's directory.\n     *\/\n    public function __construct( $plugin_dir) {\n        $this-&gt;messenger = new Post_Messenger( $plugin_dir );\n    }\n\n    \/**\n     * If there are posts to display, renders them in the metabox. Otherwise, displays\n     * a note that there are no posts to display.\n     *\/\n    public function display() {\n        $this-&gt;messenger-&gt;get_message();\n    }\n}\n<\/code><\/pre>\n<p>Neste ponto, completamos o c\u00edrculo atrav\u00e9s do plugin. Com uma exce\u00e7\u00e3o: o arquivo bootstrap. Adicionamos um namespace a ele e precisamos atualizar a maneira <a href=\"https:\/\/gist.github.com\/tommcfarlin\/38c72277ddbd0fa70a74c03598070703#file-06-bootstrap-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">como \u00e9 instanciado<\/a> :<\/p>\n<pre><code>&lt;?php\n\nnamespace McFarlinTRP;\nuse McFarlinTRPDisplayMeta_Box;\n\ninclude 'Display\/class-meta-box.php';\ninclude 'Display\/class-meta-box-display.php';\ninclude 'Utility\/class-post-messenger.php';\ninclude 'Utility\/class-post-query.php';\n\nadd_action( 'add_meta_boxes', __NAMESPACE__. 'trp_start' );\n\/**\n * Starts the plugin.\n *\/\nfunction trp_start() {\n\n    $meta_box = new Meta_Box( dirname( __FILE__) );\n    $meta_box-&gt;init();\n}<\/code><\/pre>\n<p>Ou seja, temos:<\/p>\n<ul>\n<li>definiu o namespace,<\/li>\n<li>referenciar a localiza\u00e7\u00e3o da\u00a0 classe <strong>Meta Box<\/strong> ,<\/li>\n<li>atualizou os caminhos para incluir onde encontrar os arquivos (o que pode ser feito com um carregador autom\u00e1tico),<\/li>\n<li>e atualizou a\u00a0 chamada <strong>add_action<\/strong>.<\/li>\n<\/ul>\n<p>Aqui est\u00e1 a coisa sobre a chamada de a\u00e7\u00e3o add: Como o WordPress precisa localizar essa fun\u00e7\u00e3o e a fun\u00e7\u00e3o reside em um namespace, o nome totalmente qualificado da fun\u00e7\u00e3o deve ser identificado para que o WordPress possa invoc\u00e1-lo. Da\u00ed a necessidade de <strong><a href=\"https:\/\/php.net\/manual\/en\/language.namespaces.nsconstants.php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">NAMESPACE<\/a><\/strong> no nome da fun\u00e7\u00e3o.<\/p>\n<h2>Agora estamos organizados (com uma exce\u00e7\u00e3o)<\/h2>\n<p>Como voc\u00ea pode ver, namespaces e diret\u00f3rios que correspondem a eles adicionam muita organiza\u00e7\u00e3o a um projeto. \u00c9 mais f\u00e1cil de seguir, mais f\u00e1cil de entender para onde as coisas v\u00e3o (para arquivos existentes e novos). E d\u00e1 menos sensa\u00e7\u00e3o de acumular muitos arquivos em um \u00fanico lugar.<\/p>\n<p>Mesmo que uma classe seja um pouco mon\u00f3lito, ela ainda pode ser organizada de forma a facilitar a manuten\u00e7\u00e3o.<\/p>\n<p>Com isso dito, ainda h\u00e1 algo que eu mudaria neste plugin: Passar o diret\u00f3rio do plugin assim n\u00e3o \u00e9 algo que ajuda com baixa coes\u00e3o e acopla mais firmemente as classes porque o arquivo bootstrap precisa passar um valor para uma classe que o passa para outra classe que o usa para carregar arquivos e assim por diante.<\/p>\n<p>Ent\u00e3o, existem maneiras de corrigir isso? Absolutamente. E talvez n\u00f3s vamos dar uma olhada nisso no post final.<\/p>\n<p>At\u00e9 l\u00e1, lembre-se que a vers\u00e3o mais recente do plugin est\u00e1 dispon\u00edvel <a href=\"https:\/\/github.com\/tommcfarlin\/three-recent-posts\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">no branch master, marcado como 0.3.0, no GitHub<\/a>.<\/p>\n<h2>Postagens da s\u00e9rie<\/h2>\n<ol>\n<li><a href=\"https:\/\/wordpress.mediadoma.com\/pt-pt\/prototipagem-rapida-com-wordpress-do-conceito-ao-plugin\/\" title=\"Prototipagem R\u00e1pida com WordPress: Do Conceito ao Plugin\">Prototipagem R\u00e1pida com WordPress: Do Conceito ao Plugin<\/a><\/li>\n<li><a href=\"https:\/\/wordpress.mediadoma.com\/pt-pt\/prototipagem-rapida-com-wordpress-analise-de-conceito\/\" title=\"Prototipagem R\u00e1pida com WordPress: An\u00e1lise de Conceito\">Prototipagem R\u00e1pida com WordPress: An\u00e1lise de Conceito<\/a><\/li>\n<li><a href=\"https:\/\/wordpress.mediadoma.com\/pt-pt\/prototipagem-rapida-prototipo-para-codigo-parte-1\/\" title=\"Prototipagem R\u00e1pida: Prot\u00f3tipo para C\u00f3digo, Parte 1\">Prototipagem R\u00e1pida: Prot\u00f3tipo para C\u00f3digo, Parte 1<\/a><\/li>\n<li><a href=\"https:\/\/tommcfarlin.com\/prototype-to-code-2\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">Prototipagem R\u00e1pida: Prot\u00f3tipo para C\u00f3digo, Parte 2<\/a><\/li>\n<li><a href=\"https:\/\/wordpress.mediadoma.com\/pt-pt\/prototipagem-rapida-apresentando-o-autoloading\/\" title=\"Prototipagem R\u00e1pida: Apresentando o Autoloading\">Prototipagem R\u00e1pida: Apresentando o Autoloading<\/a><\/li>\n<\/ol>\n<p><div id=\"PostUnique_PostSource\" style=\"padding-top: 50px\">Fonte de grava\u00e7\u00e3o:  <a target=\"_blank\" rel=\"noopener nofollow\" href=\"\/\/tommcfarlin.com\" class=\"external external_icon\">tommcfarlin.com<\/a><\/div><\/p>\n","protected":false},"excerpt":{"rendered":"<p>No esfor\u00e7o cont\u00ednuo de passar do prot\u00f3tipo para o c\u00f3digo, usarei o plug-in em andamento e implementarei interfaces para organiza\u00e7\u00e3o.<\/p>\n","protected":false},"author":1,"featured_media":223922,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_wp_rev_ctl_limit":""},"categories":[722,920,846],"tags":[1170],"class_list":["post-229525","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-desenvolvedor","category-outro","category-tutoriais","tag-affiai-pt-pt"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/posts\/229525","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/comments?post=229525"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/posts\/229525\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/media\/223922"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/media?parent=229525"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/categories?post=229525"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/tags?post=229525"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}