Перед введением в использование egg.js давайте представим наиболее часто используемый шаблон MV * в веб-разработке, чтобы мы могли лучше понять структуру каталогов egg.js, то есть разделение функций.
MV* относится к различным шаблонам веб-дизайна, таким как MVC, MVP, MVVM и т. д., которые улучшают организацию кода путем разделения задач Шаблоны проектирования не создаются из воздуха, а постоянно совершенствуются для решения сложных проблем, даже если вы не видели эти Внедрение шаблонов проектирования, идеи, возможно, использовались в повседневной разработке
Простейший пример
Используйте простейший пример, чтобы показать различные шаблоны проектирования
На странице есть диапазон с идентификатором контейнера, и нажатие кнопки увеличит его содержимое на 1.
<div>
<span id="container">0</span>
<button id="btn" onclick="javascript:add()">+</button>
</div>
<script>
function add (){
const container = document.getElementById('container');
const current = parseInt(container.innerText);
container.innerText = current + 1;
}
</script>
Логика рендеринга представления и обработки данных смешана, по мере усложнения бизнес-логики код становится неуправляемым и сложным в обслуживании.
MVC
MVC — это сокращение от Model View Controller.
- Модель: уровень модели, операции с данными
- Представление: слой представления, логика рендеринга пользовательского интерфейса.
- Контроллер: мост для связи между контроллерами, моделями данных и представлениями.
Модель MVC имеет много вариантов и методов потока данных. Наиболее традиционная модель MVC изолирует рендеринг представления и обработку данных. Операции представления принимаются через контроллер и передаются в модель данных. После того, как данные готовы, рендеринг представления управляется модель данных.
Приведенный выше пример можно написать в шаблоне MVC для простого разделения кода.
<div>
<span id="container">0</span>
<button id="btn">+</button>
</div>
function add (node) {
// 业务逻辑处理
const currentValue = parseInt(node.innerText);
const newValue = currentValue + 1;
// 更新视图
node.innerText = current + 1;
}
const button = document.getElementById('btn');
// 响应视图指令
button.addEventListener('click', () => {
const container = document.getElementById('container');
// 调用模型
add(container);
}, false);
- Слой представления является самым простым и обрабатывает рендеринг страницы.
- Уровень модели определяет реализацию операции +1 и обновляет данные представления.
- Контроллер перенаправляет запрос модели для обработки, когда пользователь нажимает кнопку.В веб-разработке маршрутизация общих запросов страницы и интерфейса также является обязанностью контроллера.
В приведенном выше примере, чтобы максимально изолировать обработку данных от пользовательского интерфейса, Контроллер получает узел-контейнер и передает его в Модель в качестве параметра, так что Контроллеру необходимо понимать Представление, т.е. по-прежнему связан с реализацией Представления, что в значительной степени используется в практике MVC.Бизнес-логика будет фактически написана в Контроллере, поскольку Контроллер позиционируется как мост для связи Модели Представления, эта часть муфты является приемлемым
Однако, поскольку обновление представления обрабатывается моделью, модель неизбежно связана с реализацией представления.Вы можете использовать режим наблюдателя, чтобы представление могло отслеживать изменения данных в режиме и вносить обновления, но реализация Вид зависит от Модели.
MVP
MVP — это аббревиатура от Model View Presenter, которая, можно сказать, является усовершенствованием модели MVC.По сравнению с MVC задачи и методы потока данных, отвечающие за каждый уровень, претерпели некоторые изменения.
- Модель: данные, связанные с конкретным бизнесом.
- Представление: логика рендеринга пользовательского интерфейса
- Презентатор: отвечает на команду представления и одновременно выполняет соответствующую бизнес-обработку.При необходимости вызывается модель для получения базовых данных, а результат команды возвращается в представление для управления визуализацией представления.
Шаблон MVP имеет несколько основных отличий от MVC.
- Просмотр и модель полностью изолированы, модель больше не несет ответственности за бизнес-логику и просматривать изменения, но только для базовой обработки данных
- Presenter берет на себя маршрутизацию и бизнес-логику, но требует, чтобы View реализовал интерфейс View, который удобен для отделения от конкретного View и может быть протестирован без использования пользовательского интерфейса.
- Уровень представления отвечает только за инициирование инструкций и отрисовку пользовательского интерфейса на основе данных и больше не отслеживает активно изменения данных, поэтому его также называют пассивным представлением.
Измените приведенный выше пример, используя шаблон MVP.
<div>
<span id="container">0</span>
<button id="btn">+</button>
</div>
<script>
// View Interface
const globalConfig = {
containerId: 'container',
buttonId: 'btn',
};
</script>
function add (num) {
return num + 1;
}
const button = document.getElementById(globalConfig.containerId);
const container = document.getElementById(globalConfig.buttonId);
// 响应视图指令
button.addEventListener('click', () => {
const currentValue = parseInt(container.innerText);
// 调用模型
const newValue = add(currentValue);
// 更新视图
container.innerText = current + 1;
}, false);
Таким образом, Model обрабатывает только независимую от бизнеса обработку данных, которая становится очень стабильной.В то же время Presenter и View связаны через интерфейс/конфигурацию, что намного ниже, чем прямое соединение MVC.
Видно, что MVP лучше, чем разделение данных и представлений MVC.Большую часть времени использование MVC на самом деле использует MVP.
MVVM
MVVM можно записать как MV-VM, что является аббревиатурой от Model View - ViewModel. Его можно рассматривать как вариант режима MVP. Обязанности View и Model такие же, как у MVP, но ViewModel в основном полагается на DataBinding для автоматического связать View и Model, а фреймворк реализует это для разработчиков приложений.Обновление View после изменения данных эквивалентно упрощению некоторых функций Presenter
Vue, который знаком к передней части, использует шаблон MVVM и использует VUE для реализации функций образца
Функция образца может быть легко реализована с Vue. Для того, чтобы показать образец MVVM-кода, я сознательно обошел по кругу.
<div id="test">
<!-- 数据和视图绑定 -->
<span>{{counter}}</span>
<button v-on:click="counterPlus">+</button>
</div>
function add (num) {
return num + 1;
}
new Vue({
el: '#test',
data: {
counter: 0
},
methods: {
counterPlus: function () {
// 只需要修改数据,无需手工修改视图
this.counter = add(this.counter);
}
}
})
Данные и представление связаны в представлении.В ViewModel нужно обновить только данные, а представление изменится автоматически.Привязка данных реализуется фреймворком.
Суммировать
MVC, MVP, MVVM Три популярных узора дизайна в основном в решении проблем разделения данных и логическим представлением, в реальном использовании, есть много вариантов, общих
- MVC делает первый шаг разделения представления и данных, который легко реализовать, но разделение представления, бизнес-логики и базовой модели данных является неполным.
- MVP полностью разделяет View и Model через Presenter, удаляя бизнес-логику и базовую логику данных, делая модель стабильной, но Presenter будет относительно раздутым, когда бизнес-логика сложна.
- MVVM реализует привязку представлений и данных через DataBinding, но это зависит от реализации фреймворка, что увеличивает стоимость понимания и усложняет отладку в случае некорректного использования
Между шаблонами проектирования нет абсолютной разницы. Конкретный выбор зависит от масштаба проекта и координации команды. Хотя в представленном позже egg.js используется Controller в структуре каталогов, на самом деле это шаблон MVP.