Что такое аспектно-ориентированное программирование?
Аспектно-ориентированное программирование (АОП) — это парадигма программирования. Студенты, изучающие веб-интерфейс Java, особенно те, кто использовал Spring, должны быть хорошо знакомы с ним. АОП — одна из важных концепций в среде Spring. Но в Javascript АОП часто упускается из виду.
Сцены
Предположим, у вас есть классное всплывающее окно с календарем.Однажды начальник попросил вас подсчитать количество нажатий на кнопку во всплывающем окне каждый день, поэтому вы сделали захоронение во всплывающем окне;
Через неделю начальник сказал, что пользователи сообщали, что всплывающее окно работало очень медленно и всячески зависало. Вы хотите увидеть среднее время выполнения функции, поэтому добавляете код статистики производительности во всплывающее окно.
Спустя долгое время вы обнаружите, что ваша бизнес-логика содержит массу вещей, не имеющих никакого отношения к бизнесу, даже некоторые функции, которые вы инкапсулировали.
Тогда существует АОП для решения такого рода проблем.
разделение интересов
Разделение бизнес-кода и кода статистики данных (не бизнес-кода) является одним из классических приложений АОП, независимо от того, на каком языке он написан. Отделение сквозных задач от основных задач является основной концепцией АОП.
Среди общих требований к внешнему интерфейсу есть некоторые компании, которые могут использовать АОП, чтобы отделить их от своих основных задач.
- Журнал журнала Node.js
- Закопанные точки, отчетность данных
- Анализ производительности, статистическое время выполнения функции
- Динамически добавлять параметры к запросам ajax, динамически изменять параметры функций
- Отдельный запрос формы и проверка
- Защита от тряски и дросселирования
Декоратор
Когда дело доходит до АОП, необходимо говорить о шаблоне декоратора, АОП часто путают с шаблоном декоратора.
До ES6+, чтобы использовать шаблон декоратора, обычно черезFunction.prototype.beforeсделать предварительную отделку иFunction.prototype.afterВыполните пост-декорирование (см. «Шаблоны проектирования и методы разработки JavaScript»).
Декоратор, представленный Javascript, похож по синтаксису на аннотации Java, но не имеет ничего общего с семантикой. Предложение Decorator предоставляет возможность украшать классы и методы Javascript внутри них. (хотя это просто синтаксический сахар для функций, которые запускаются во время компиляции)
Отчет о захороненных точках
Поскольку в фактической разработке с использованием React используется большое количество компонентов на основе классов, я использую React в качестве примера здесь.
Например, на странице есть кнопка, при нажатии на которую открывается всплывающее окно, в то же время требуется отчетность по данным, чтобы подсчитать, сколько пользователей нажали кнопку входа.
import React, { Component } from 'react';
import send from './send';
class Dialog extends Component {
constructor(props) {
super(props);
}
@send
showDialog(content) {
// do things
}
render() {
return (
<button onClick={() => this.showDialog('show dialog')}>showDialog</button>
)
}
}
export default Dialog;
Приведенный выше код относится к@sendDecorator, он изменит метод прототипа в этом классе.@sendРеализация декоратора
export default function send(target, name, descriptor) {
let oldValue = descriptor.value;
descriptor.value = function () {
console.log(`before calling ${name} with`, arguments);
return oldValue.apply(this, arguments);
};
return descriptor;
}
Выполнить после нажатия кнопкиshowDialogДо этого мы можем выполнять нужные операции с аспектами.Мы можем инкапсулировать код, связанный со скрытыми точками и отчетами о данных, в этом декораторе для реализации АОП.
Передняя отделка и задняя отделка
надsendЭтот декоратор на самом деле является предварительным декоратором, мы можем инкапсулировать его, чтобы он мог выполнять любую функцию заранее.
function before(beforeFn = function () { }) {
return function (target, name, descriptor) {
let oldValue = descriptor.value;
descriptor.value = function () {
beforeFn.apply(this, arguments);
return oldValue.apply(this, arguments);
};
return descriptor;
}
}
Таким образом, мы можем использовать@beforeДекоратор вырезает произвольный код, не относящийся к бизнесу, перед методом-прототипом.
function beforeLog() {
console.log(`before calling ${name} with`, arguments);
}
class Dialog {
...
@before(beforeLog)
showDialog(content) {
// do things
}
...
}
а также@beforeДекораторы похожи и могут реализовать@afterПостдекоратор, но порядок выполнения функций другой.
function after(afterFn = function () { }) {
return function (target, name, descriptor) {
let oldValue = descriptor.value;
descriptor.value = function () {
let ret = oldValue.apply(this, arguments);
afterFn.apply(this, arguments);
return ret;
};
return descriptor;
}
}
анализ производительности
Иногда мы хотим посчитать время выполнения кода на стороне пользователя, но не хотим встраивать управляющий код в бизнес-код, мы также можем использовать декоратор для выполнения АОП.
function measure(target, name, descriptor) {
let oldValue = descriptor.value;
descriptor.value = function () {
let ret = oldValue.apply(this, arguments);
performance.mark("startWork");
afterFn.apply(this, arguments);
performance.mark("endWork");
performance.measure("work", "startWork", "endWork");
performance
.getEntries()
.map(entry => JSON.stringify(entry, null, 2))
.forEach(json => console.log(json));
return ret;
};
return descriptor;
}
Добавить перед методом класса, время выполнения которого нужно считать@measureВсе, код для статистики производительности не будет вторгаться в бизнес-код.
class Dialog {
...
@measure
showDialog(content) {
// do things
}
...
}
резюме
Смысл аспектно-ориентированного программирования состоит в том, чтобы разделить основные задачи на задачи поперечного сечения.Фронтенд может использовать АОП для элегантной организации кода, такого как отчеты о данных, анализ производительности, время выполнения статистических функций, динамически изменяющиеся параметры функций и т. д. проверка формы плагина.
Ссылаться на
-
Шаблоны проектирования Javascript и практика разработки