Как должна быть структурирована модель в MVC? [закрыто]
Вопрос:
Я только начинаю осваивать фреймворк MVC и часто задаюсь вопросом, сколько кода должно находиться в модели. У меня есть класс для доступа к данным с методами, подобными следующему:
public function CheckUsername($connection, $username)
{
try
{
$data = array();
$data['Username'] = $username;
// SQL
$sql = "SELECT Username FROM " . $this->usersTableName . " WHERE Username = :Username";
// Выполнение запроса
return $this->ExecuteObject($connection, $sql, $data);
}
catch(Exception $e)
{
throw $e;
}
}
Мои модели, как правило, представляют собой классы-сущности, которые сопоставлены с таблицами базы данных.
Должно ли объект модели содержать все свойства, сопоставленные с базой данных, а также указанный выше код, или допустимо разделить этот код, который выполняет операции с базой данных?
В конечном итоге, не приведет ли это к тому, что у меня будут четыре уровня?
Статус: Закрыто. Этот вопрос основан на мнениях и не принимает ответов на данный момент.
2 ответ(ов)
Все, что относится к бизнес-логике, должно находиться в модели, будь то запрос к базе данных, вычисления, REST-вызовы и так далее.
Вы можете разместить доступ к данным прямо в модели; паттерн MVC не запрещает это. Можно обернуть это в сервисы, мапперы и прочие абстракции, но истинное определение модели — это слой, который обрабатывает бизнес-логику, не более того и не менее. Это может быть класс, функция или целый модуль с множеством объектов, если это то, что вам нужно.
Чаще всего проще иметь отдельный объект, который действительно выполняет запросы к базе данных, чем выполнять их непосредственно в модели. Это особенно пригодится при модульном тестировании (из-за удобства внедрения мок-объекта базы данных в вашу модель):
class Database {
protected $_conn;
public function __construct($connection) {
$this->_conn = $connection;
}
public function ExecuteObject($sql, $data) {
// код для выполнения запроса
}
}
abstract class Model {
protected $_db;
public function __construct(Database $db) {
$this->_db = $db;
}
}
class User extends Model {
public function CheckUsername($username) {
// ...
$sql = "SELECT Username FROM " . $this->usersTableName . " WHERE ...";
return $this->_db->ExecuteObject($sql, $data);
}
}
$db = new Database($conn);
$model = new User($db);
$model->CheckUsername('foo');
Также, в PHP редко требуется перехватывать и повторно генерировать исключения, так как трассировка стека сохраняется, особенно в таких случаях, как ваш пример. Просто позвольте исключению быть выброшенным и поймайте его в контроллере.
В большинстве приложений чаще всего существует три основные составляющие: данные, отображение и обработка. Эти три компонента мы обычно обозначаем буквами M
, V
и C
, что соответствует архитектуре MVC.
Model (M
) — это компонент, который содержит состояние приложения и его атрибуты. Он не знает ничего о V
и C
, то есть не зависит от их реализации.
View (V
) — это часть, которая отвечает за формат отображения приложения. Она знает, как визуализировать данные из модели, но не взаимодействует с контроллером C
.
Controller (C
) — это звено, которое обрабатывает логику приложения. Контроллер управляет связью между моделью M
и представлением V
и зависит от обоих компонентов, в отличие от модели и представления.
Таким образом, в архитектуре MVC обеспечивается четкое разделение ответственности, что облегчает внесение изменений и добавление улучшений в будущем.
Когда использовать 'self' вместо '$this'?
Разница между public, private и protected в ООП
Как удалить модель с помощью php artisan?
Что такое потокобезопасность и непотокобезопасность в PHP?
Вставка нового элемента в массив в любом месте в PHP