Швидке створення прототипів: прототип до коду, частина 2
Попередня публікація демонструє велику роботу над тим, щоб взяти щось, що колись було швидким прототипом, і використати цей прототип для кодування. Якщо ви не стежили за цим, ми зробили наступне:
- обговорили та створили прототип для плагіна,
- накреслив один об’єктно-орієнтований підхід, який може працювати,
- і переробили наш прототип у фактичний код.
На даний момент ми можемо зробити ще кілька речей, щоб покращити наш код. А саме, ми можемо ввести поняття простору імен. Це робить організацію на крок вперед і може принести дивіденди для більших проектів.
Отже, ось подивіться, як це відбувається в нашому поточному проекті.
Прототип до коду: простори імен
Я детально розглядав простори імен у попередніх публікаціях. Якщо ви не читали, рекомендую. Потім поверніться та перегляньте решту публікації.
Якщо ви вирішите пропустити статтю, ось коротке визначення простору імен :
Простори імен призначені для вирішення двох проблем, з якими стикаються автори бібліотек і програм під час створення повторно використовуваних елементів коду, таких як класи або функції…
І загальна ідея полягає в тому, що ми організовуємо наші заняття на основі логічного зв’язку між ними.
Крім того, ми також упорядковуємо файли в каталогах, які відповідають простору імен. Це не те, що потрібно робити, але я вважаю, що це допомагає мати класи логічно організовані на диску так, як вони віртуально організовані в просторі імен.
З огляду на це, давайте впорядкуємо файли.
Упорядкування файлів
Замість того щоб починати з основного файлу плагіна, давайте спочатку впорядкуємо наші файли.
- Файли Meta Box і Meta Box Display будуть зберігатися в каталозі під назвою Display. Це абсолютно довільно, але оскільки це саме те, що ці файли роблять, здається, має сенс, що вони будуть саме там.
- Ми також можемо розмістити файли message-description.php і no-post-list.php у цьому каталозі, але розмістимо їх у підкаталозі під назвою Views. Ви можете назвати це Templates або Partials або щось подібне.
- Далі ми маємо класи, відповідальні за запит до бази даних, і клас, відповідальний за координацію обміну повідомленнями. Давайте розмістимо кожен із них у Utility. Звичайно, є й інші місця, куди вони можуть піти, але пам’ятайте, що мета — продемонструвати, як використовувати простори імен. Отже, якщо ви відчуваєте таку схильність, не соромтеся налаштувати свої файли на свій смак.
Якщо ви дотримувалися того, що ми надали вище, то у вас повинна бути структура каталогу, яка виглядає приблизно так:
Один із способів упорядкування файлів.
Тепер настав час визначити простори імен для кожного з класів. Оскільки ми впорядкували їх усі за каталогами, буде легко вказати простір імен; однак важливо розуміти, що нам потрібно буде використовувати ключове слово use, коли ми використовуємо класи, розташовані в інших просторах імен.
Давайте переглянемо кожен із наших файлів, починаючи з файлів у Utility. Спочатку ми почнемо з Post Messenger :
<?php
/**
* Display content for the meta box when requested.
*
* @author Tom McFarlin
* @since 0.2.0
*/
namespace McFarlinTRPUtility;
use McFarlinTRPUtilityPost_Query;
/**
* Retrieves information from the class responsible for querying the database and
* renders it in the context of our meta box when called via the Meta Box Display.
*
* @author Tom McFarlin
* @since 0.2.0
*/
class Post_Messenger {
// Snip for brevity.
}
Ви помітите, що простір імен файлу з’являється в заголовку разом із оголошенням про використання створеного нами класу Post Query . Я додав назву класу в кінець простору імен, тому мені не потрібно використовувати її в усій кодовій базі.
Зверніть увагу, що конструктор зараз виглядає так :
<?php
/**
* Instantiates the class by setting a reference to the query.
*
* @param string $plugin_dir The path to the root of the plugin directory.
*/
public function __construct( $plugin_dir) {
$this->query = new Post_Query();
$this->plugin_dir = trailingslashit( $plugin_dir );
}
Я додав аргумент $plugin_dir, оскільки нам потрібно використовувати його для належного відображення результатів запиту. І оскільки тепер вони знаходяться в іншій області програми, функції виглядають так :
<?php
/**
* Displays the description of the content of the meta box.
*
* @access private
*/
private function get_post_message() {
include_once $this->plugin_dir. 'Display/Views/post-list.php';
}
/**
* Displays the description of the content of the meta box.
*
* @access private
*/
private function get_description() {
include_once $this->plugin_dir. 'Display/Views/message-description.php';
}
/**
* Displays a message of there are no recent posts.
*
* @access private
*/
private function get_no_posts_message() {
include_once $this->plugin_dir. 'Display/Views/no-post-list.php';
}
Далі розглянемо клас Post Query . У цьому класі нічого особливого не змінилося, за винятком того, що ми дали йому простір імен, а також оновили запит лише для того, щоб відкликати три публікації (відповідно до цього коментаря ).
<?php
namespace McFarlinTRPUtility;
/**
* Queries the database for three most recent posts. Returns the query to the
* caller so that it can be interrogates for posts or not.
*
* @author Tom McFarlin
* @since 0.2.0
*/
class Post_Query {
// Snip for brevity.
private function get_posts() {
$args = array(
'post_type' => 'post',
'post_status' => 'publish',
'posts_per_page' => 3,
'orderby' => 'date',
'order' => 'desc',
);
$this->query = new WP_Query( $args );
return $this->query;
}
}
Зауважте, що в коді я також попередньо зафіксував WP_Query скісною рискою, оскільки це частина глобального простору імен.
Давайте перемістимося в каталог Display і поглянемо на клас Meta Box. Це також отримав простір імен і також використовує повну назву класу Meta Box Display, який ми зараз розглянемо.
<?php
namespace McFarlinTRPDisplay;
use McFarlinTRPDisplayMeta_Box_Display;
/**
* Registers the Meta Box with WordPress. Defines the ID, title, display function,
* and the post type on which it will live.
*
* @author Tom McFarlin
* @since 0.2.0
*/
class Meta_Box {
/**
* A reference to the class that will display the contents in the meta box.
*
* @access private
* @var Meta_Box_Display
*/
private $meta_box_display;
/**
* Instantiates the class by setting its property equal to a reference to its display.
*
* @param string $plugin_dir A reference to the root of the plugin's directory.
*/
public function __construct( $plugin_dir) {
$this->meta_box_display = new Meta_Box_Display( $plugin_dir );
}
// Snip for brevity.
}
Зауважте, що цей конструктор також приймає каталог плагіна як аргумент і також передає його класу Meta Box Display. Це робиться для того, щоб функції, відповідальні за відображення повідомлень, можна було правильно знайти в їх розташуванні в каталозі Views .
Нарешті, давайте розглянемо клас Meta Box Display . Це простий клас, який включає простір імен і посилається на Post Messenger, який ми розглянули вище.
<?php
/**
* Defines the display for the meta box.
*
* @author Tom McFarlin
* @since 0.2.0
*/
namespace McFarlinTRPDisplay;
use McFarlinTRPUtilityPost_Messenger;
/**
* Defines the display for the meta box that will render the content in the
* context of its meta box.
*
* @author Tom McFarlin
* @since 0.2.0
*/
class Meta_Box_Display {
/**
* A reference to the class that will display the contents in the meta box.
*
* @access private
* @var Post_Messenger
*/
private $messenger;
/**
* Instantiates the object by setting a property equal to that of the class
* responsible for rendering the messages from the post query.
*
* @param string $plugin_dir A reference to the root of the plugin's directory.
*/
public function __construct( $plugin_dir) {
$this->messenger = new Post_Messenger( $plugin_dir );
}
/**
* If there are posts to display, renders them in the metabox. Otherwise, displays
* a note that there are no posts to display.
*/
public function display() {
$this->messenger->get_message();
}
}
На цьому етапі ми завершили плагін. За одним винятком: файл початкового завантаження. Ми додали до нього простір імен і маємо оновити спосіб його створення :
<?php
namespace McFarlinTRP;
use McFarlinTRPDisplayMeta_Box;
include 'Display/class-meta-box.php';
include 'Display/class-meta-box-display.php';
include 'Utility/class-post-messenger.php';
include 'Utility/class-post-query.php';
add_action( 'add_meta_boxes', __NAMESPACE__. 'trp_start' );
/**
* Starts the plugin.
*/
function trp_start() {
$meta_box = new Meta_Box( dirname( __FILE__) );
$meta_box->init();
}
А саме ми маємо:
- визначив простір імен,
- посилання на розташування класу Meta Box ,
- оновлено шляхи, щоб вказати, де знайти файли (що, зрештою, можна зробити за допомогою автозавантажувача),
- і оновив виклик add_action.
Ось що стосується виклику дії add: оскільки WordPress потрібно знайти цю функцію, а функція знаходиться в просторі імен, повне ім’я функції має бути ідентифіковано, щоб WordPress міг її викликати. Звідси необхідність NAMESPACE в назві функції.
Тепер ми організовані (за одним винятком)
Як ви бачите, простори імен і каталоги, які їм відповідають, додають багато організації проекту. Це легше стежити, легше зрозуміти, куди йдуть речі (як для існуючих, так і для нових файлів). І це дає менше відчуття простого накопичення багатьох файлів в одному місці.
Навіть якщо клас трохи монолітний, його все одно можна організувати таким чином, щоб полегшити обслуговування.
З огляду на це, я б все ще дещо змінив у цьому плагіні: передача каталогу плагіна таким чином не допомагає з низькою зв’язністю, і це тісніше об’єднує класи, оскільки файл початкового завантаження має передавати значення в один клас, який передає його в інший клас, який використовує його для завантаження файлів і так далі.
То чи є способи це виправити? Абсолютно. І, можливо, ми розглянемо це в останній публікації.
До того часу пам’ятайте, що найновіша версія плагіна доступна на головній гілці з тегом 0.3.0 на GitHub.
Повідомлення серії
- Швидке створення прототипів за допомогою WordPress: від концепції до плагіна
- Швидке створення прототипів за допомогою WordPress: аналіз концепції
- Швидке створення прототипів: прототип до коду, частина 1
- Швидке створення прототипів: прототип до коду, частина 2
- Швидке створення прототипів: представлення автозавантаження