Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
Я бы рекомендовал её к прочтению тем, кто только начал осознавать, что его коду чего-то не хватает, и что он созрел для вникания в это далёкое понятие – «паттерны».
Почему одиночку нельзя вдруг создавать через конструктор? Почему не перенести логику из function getInstance() в конструктор?
<?php
var_dump(new StdClass()); //returns: object(stdClass)#1 (0) { }
Но вообще, я не силен в ООП, могу и ошибаться.
Почему одиночку нельзя вдруг создавать через конструктор? Почему не перенести логику из function getInstance() в конструктор?
self() вызывает конструктор (а в этот момент он ещё не instanceof self — значит он ещё раз вызовет self(), который, в свою очередь, ещё раз вызовет self(), который...). Если содержимое getInstance() перенести в __construct(), то выполнение просто зациклится. Всё равно, что писать while(true){/*здесь нет никаких break, exit и т.п.*/}.__construct() нет смысла использовать return, потому что __construct() в любом случае возвращает новый экземпляр класса. Почему одиночку нельзя вдруг создавать через конструктор? Почему не перенести логику из function getInstance() в конструктор?
Цели статьи были другими.
Википедию никто не отменял. Там можно почитать, зачем паттерны нужны.
Где именно я перепутал разные паттерны?
И что нужно это для того, чтобы методы, принимающие объекты в качестве параметров могли принимать объекты не одного конкретного класса, а всех классов какой-то ветви иерархии. А это, в свою очередь, нужно нужно чтобы упростить методы из предыдущего предложения и избежать их дублирования.
$STATE["db"] = get_db_object();В фреймворках часто можно встретить объект $app
Информация связана — вся она относится к приложению.
Чем, по-вашему, "$obj->property" остроконечников лучше чем "$obj[«property»] тупоконечников?
(ц), (д) — тут прошу поподробнее. Чувствую ценность в вашем комментарии, но нужно больше деталей.
Первая запись подразумевает фиксированный набор хорошо известных свойств, вторая — изменяемый словарь.
<?php
class TheClass
{
public $ownProperty;
public function getProp(){
echo "Не существующее свойство: " . $this->property . "<br>";
}
}
$obj = new TheClass();
$obj->property = "Существует.";
$obj->getProp(); // Не существующее свойство: Существует.
Основное применение реестра – в качестве безопасной замены глобальным переменным.
Признаю, в данном примере мало смысла. Здесь использование этого шаблона не оправдано. Я просто хотел показать его смысл.
<?php
require_once "classes/DB_Fabric.php";
require_once "classes/Renderer_Fabric.php";
$STATE = array();
$STATE["config"] = include "path/to/config.php";
$STATE["uri"] = $_SERVER["REQUEST_URI"];
$STATE["db"] = get_db_object();
$STATE["page"] = get_page_by_uri_from_somewhat_storage();
$STATE["output"] = render_page();
echo $STATE["output"];
exit();
function get_db_object(){ // Возвращает объект "База данных" для текущего uri согласно конфигурации.
global $STATE;
return new DB_Fabric($STATE["config"]["db"], $STATE["uri"] );
}
function get_page_by_uri_from_somewhat_storage(){ // возвращает объект "Текущая страница"
global $STATE;
if ( is_page_on_filesystem() ){
return load_page_from_filesystem();
} elseif( is_page_in_db() ) {
return get_page_from_db();
} else {
return get_404_page();
};
};
function is_page_on_filesystem(){
global $STATE;
$page_filename = $S["state"]["config"]["path_to_pages"] . $STATE["uri"];
return is_readable($page_filename);
};
function load_page_from_filesystem(){
global $STATE;
return file_get_contents( $S["state"]["config"]["path_to_pages"] . $STATE["uri"] );
};
function is_page_in_db(){
global $STATE;
if ( $STATE["db"]->find("page", "by_uri", $STATE["uri"]) ) return true;
else return false;
};
function get_page_from_db(){
global $STATE;
return $STATE["db"]->find("page", "by_uri", $STATE["uri"]);
}
function render_page(){ //Возвращает представление страницы для User-Agent, используя подходящий renderer для текущего uri согласно конфигурации
global $STATE;
$renderer = new Renderer_Fabric( $STATE["config"], $STATE["uri"] );
return $render->render( $STATE["page"]->data );
}
Как его можно доработать, чтобы продемонстрировать другие порождающие шаблоны?
$STATE = array() — «реестр», он же «пул объектов» (db, page), он же «синглтон» (ибо глобальная переменная).
get_page_by_uri_from_somewhat_storage() — «фабрика» (или абстрактная?). Или это вообще «Строитель»?
Метод, читающий что-то откуда-то, в норме не относят к порождающим паттернам
Но означают они что-то близкое, если не одно и то же.
Что тут имеется в виду?
от такие мелочи и отличают паттерн
совершенно не понятно, зачем примененное, и от этого очень опасное
Хорошо бы вы указали на эти мелочи, пока они остаются загадкой.
Использование $STATE направлено на снижение связности модулей программы
Реестр содержит семантически связанные и (в норме) однотипные объекты.
связать два модуля через хорошо известный обоим контракт,
Глобальная область видимости — это плохо. Это плохо именно потому, что у вас нарушается принцип единой ответственности.
В общем модулей сильно больше двух. И каждый из них связан только со $STATE.
Погружение внутрь хорошо для библиотек и т.п., но для основной программы это, по моему, лишнее.
Реестр содержит семантически связанные и (в норме) однотипные объекты.
У реестра одна ответственность — хранить значения (в том числе объекты, ресурсы и массивы в контексте PHP) в рантайме для всего приложения.
Но вот если однотипных значений одно-два (типа коннектов к СУБД), то вполне вероятно, что создание отдельного реестра на каждый тип будет выглядеть оверинженерингом.
Итак, мы рассмотрели 9 шаблонов проектирования. Это довольно длинная статья. Поэтому хотелось бы узнать ваше мнение. Есть ли смысл в проделанной работе и стоит ли мне завершить цикл, рассказав о структурных шаблонах и шаблонах поведения?
Шаблоны проектирования PHP. Часть 1. Порождающие