EDIT: После некоторых исследований я увидел эту структуру: эта структура MVC. У него есть классы в папке Libs, которые являются статическими (например, Config, Session), я могу использовать их?
Я новичок в практике MVC, и я застрял на странной проблеме.
У меня много моделей, таких как DB, User, Config и т.д., Но я использую многие из них в каждой создаваемой функции.
У меня проблема с шаблонами MVC; Я создал несколько моделей, я использую каждый из них для обработки сгруппированных задач (соединение, DB, ect..).
Проблема в том, что после создания базовых моделей я получил код вроде этого (внутри контроллера).
class User
{
function signup($username, $password, ...)
{
$config = new Config();
$DB = new DB();
$HTML = new Session();
// And so on...
$canRegister = $config->get("registration-enabled");
if ($canRegister and ..) {
$this->username = $username;
$DB->saveAccount($this);
$session->setUser($this);
} else {
throw new Exception('bad signup');
}
}
}
Я должен создавать экземпляры многих моделей только для одной или двух функций. Но если модели статичны, они должны выглядеть так:
class User
{
function signup($username, $password, ...)
{
$canRegister = Config::get("registration-enabled");
if ($canRegister and ..) {
$this->username = $username;
DB::saveAccount($this);
session::setUser($this);
} else {
throw new Exception('bad signup');
}
}
}
Обратите внимание, что многие модели не используют метод __construct. Так что хорошая практика (или неплохая) - иметь статические модели в шаблоне MVC?
Прежде чем отвечать, см. РЕДАКТ.
Модель состоит из служб, в то время как сами сервисы состоят из абстракций хранения и объектов, которые обрабатывают вычисления. Проще говоря, служба является мостом между объектами домена и абстракциями хранения (такими как Data Mappers или Table Gateways). Модель состоит из этих услуг.
Это типичный способ структурирования модели:
Model
- Storage
- MySQL
- YourMapper
- Service
- YourService
Класс, который обрабатывает абстракцию в таблицу, а также вычисление и валидация также известны как Anemic Model (что, кажется, ваше дело), потому что оно нарушает SRP и прерывает разделение проблем.
Когда вы придерживаетесь этого правильного пути, вы можете легко заменить хранилище (скажем, вы можете заменить MySQL на MongoDB), поскольку они больше не связаны с бизнес-логикой. Или вы можете заменить объекты домена, которые обрабатывают вычисления, даже не касаясь хранилища.
Для примера предположим, что вы пишете библиотеку, которая загружает файлы.
class Uploader
{
...
public function upload(array $files)
{
$path = Config::read('upload_path');
$some_another_option = Config::read('foo');
$this->move($path, $some_another_option, $files);
}
...
}
Итак, какая проблема может быть здесь? Просто помните, что мы пишем библиотеку и даем понять эти факты:
Чтобы использовать загружаемую библиотеку, объект Config должен быть правильно создан и данные должны быть полностью загружены в память. Это пустая трата оперативной памяти и
Что делать, если вы решили заменить Config
на другой источник необходимой информации? Вы не можете, потому что его плотно связанный
Если вы хотите распространять свою библиотеку, вам также придется распространять свои настройки Config +, что сделает вашу библиотеку плохой.
Да, вы, вероятно, видели такой подход в других рамках. Но популярность в любом случае не означает правильность.
Вы должны помнить, что объект-экземпляр является еще одной ответственностью. Когда вы создаете экземпляр Conifg
вы, вероятно, загружаете данные где-нибудь (массив или таблица, что угодно). Итак, в вашем первом подходе вы должны загрузить его n-times
? Это кажется очень неправильным способом.
То, что вы действительно должны сделать, это создать экземпляр Config только один раз и передать его классам, требующим его, например:
$config = new Conifg();
$config->load(__DIR__ . '/config_array.php');
$user = new User($config);
$system = new System($config);
// and so on, you got the point
То же самое относится к вашей DB
и Session
. Классы, которые используют эти объекты, не должны беспокоиться об их создании. Они просто должны беспокоиться о том, как их использовать.
Помните: ничто никогда не убивает способность повторного использования кода, например, Static classes и Singletons
Все классные чуваки относятся к этой методике как инъекция зависимостей
DB::saveAccount
по сути такой же, какdb_save_account()
. Лично я не вижу ничего плохого в процедурном программировании, но если вам нужен настоящий ООП, то это не так.