предисловие
Несколько дней назад я поделился несколькими менее строгими интеллект-картами, в том числе одной о шаблонах проектирования:
Давно помню только несколько паттернов проектирования, и они плохо применяются.Мы просто используем эту диаграмму как набросок и говорим о тех шаблонах проектирования, которые мы используем непреднамеренно — творчески.
1. Три заводских режима:Factory Pattern
Вообще говоря, три шаблона проектирования:
- Простой заводской шаблон (
Simple Factory
) - Шаблон фабричного метода (
Factory method
) - Абстрактный заводской узор (
Abstract factory
)
Его ядро:
Роль фабрики заключается в том, чтобы скрыть сложность создания экземпляра, а нужно только предоставить простой и понятный интерфейс. --- Отрывок из книги «Путь фронтенд-интервью»
Разница в следующем:
- Простой фабричный шаблон, используемый для создания экземпляра определенного объекта продукта, используемый для создания одного объекта.
- Шаблон фабричного метода откладывает создание экземпляра до подклассов.
- Шаблон абстрактной фабрики — это фабричная абстракция класса, используемого для создания кластера класса продукта, и он не отвечает за создание экземпляра продукта определенного типа.
На самом деле из того, что вы бы использовалиjQuery
С самого начала уже используется заводской шаблон:
Шаблоны проектирования JavaScript и практика — Factory Pattern
1. jQuery
из$(selector)
jQuery
середина$('div')
а такжеnew $('div')
Какой лучше использовать? явно прямой$()
наиболее удобно, потому что$()
Это уже заводской метод.
class jQuery {
constructor(selector) {
super(selector)
}
// ....
}
window.$ = function(selector) {
return new jQuery(selector)
}
2. React
изcreateElement()
React.createElement()
метод является фабричным методом
React.createElement('h1', null, 'Hello World!'),
3. Vue
Асинхронный компонент
пройти черезpromise
Путьresolve
из компонента
export function createComponent (
Ctor: Class<Component> | Function | Object | void,
data: ?VNodeData,
context: Component,
children: ?Array<VNode>,
tag?: string
): VNode | Array<VNode> | void {
// ...逻辑处理
// async component
let asyncFactory
const vnode = new VNode(
`vue-component-${Ctor.cid}${name ? `-${name}` : ''}`,
data, undefined, undefined, undefined, context,
{ Ctor, propsData, listeners, tag, children },
asyncFactory
)
}
2. Одноэлементный шаблон:Singleton Pattern
Шаблон Singleton — один из самых простых шаблонов проектирования.
Объяснить на просторечии это:
Экземпляры доступны везде
Есть три основных момента шаблона singleton:
- Класс может иметь только один экземпляр;
- Он должен сам создать этот экземпляр;
- Он должен предоставить этот экземпляр для всей системы сам по себе.
С конкретной точки зрения реализации это следующие три момента:
- Класс одноэлементного шаблона предоставляет только частный конструктор
- Определение класса содержит статический частный объект класса
- Этот класс предоставляет статическую общедоступную функцию для создания или получения собственного статического закрытого объекта.
Точно так же это также один из самых ранних шаблонов проектирования, с которыми мы столкнулись:
1. Ссылка на сторонние библиотеки
Несколько ссылок будут использовать только одну ссылку на библиотеку, напримерjQuery
,lodash
,moment
Ждать.
2. Vuex / Redux
глобальное управление состояниемstore
Vuex
а такжеRedux
Данные хранятся в одномstore
середина,Mobx
Хранить данные в распределенномstore
середина
const store = createStore(reducer)
render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
)
3. Vue
Установка сторонних плагинов в
ПервыйVuex
Установить:
let Vue // bind on install
export function install (_Vue) {
if (Vue && _Vue === Vue) {
// 如果发现 Vue 有值,就不重新创建实例了
return
}
Vue = _Vue
applyMixin(Vue)
}
Другие аналогичны, если вам интересно, вы можете перейти кGitHub
поискexport function install (Vue)
4. Простая реализация одноэлементного паттерна:
class SingletonClass {
constructor() {
if (!SingletonClass.instance) {
SingletonClass.instance = this;
}
return SingletonClass.instance;
}
// other things
}
const instance = new SingletonClass();
Object.freeze(instance);
export default instance;
3. Режим строителя:Builder Pattern
, режим строителя в основном используется для«Построение сложного объекта шаг за шагом»
Здесь «шаг за шагом» является стабильным алгоритмом, а части сложных объектов часто меняются.
Одним словом: командир ставит задачи, а строители осуществляют разработку, каждый со своими обязанностями, и стабилизируют ее в большом процессе.
Леди состоит в том, чтобы построить виллу, вам нужно найти пакет-армадиана, пакет выделит конкретную задачу для работников. После этого дай леди.Скевоморфная интерпретация концепции режима строителя
1. jQuery
строитель в
jQuery
Режим среднего строителя отражается в:
$( "<div class= "foo">bar</div>" );
$( "<p id="test">foo <em>bar</em></p>").appendTo("body" );
var newParagraph = $( "<p />" ).text( "Hello world" );
$( "<input />" )
.attr({ "type": "text", "id":"sample"});
.appendTo("#container");
НижеjQuery
Внутри исходного кодаjQuery.prototype
Фрагмент метода, который будет передан от кjQuery()
Конструкция тегов для селекторовjQuery
объект.
Неважно, еслиdocument.createElement
Для создания новых элементов ссылки на элементы (найденные или созданные) вводятся в возвращаемый объект, поэтому.attr()
Сразу же после этого можно использовать другие методы.
// HANDLE: $(html) -> $(array)
if ( match[1] ) {
context = context instanceof jQuery ? context[0] : context;
doc = ( context ? context.ownerDocument || context : document );
//如果传入的是单个字符串,并且是单个标记
//只需执行createElement并跳过其余部分
ret = rsingleTag.exec( selector );
if ( ret ) {
if ( jQuery.isPlainObject( context ) ) {
selector = [ document.createElement( ret[1] ) ];
jQuery.fn.attr.call( selector, context, true );
} else {
selector = [ doc.createElement( ret[1] ) ];
}
} else {
ret = jQuery.buildFragment( [ match[1] ], [ doc ] );
selector = ( ret.cacheable ? jQuery.clone(ret.fragment)
: ret.fragment ).childNodes;
}
return jQuery.merge( this, selector );
1. Идеальная реализация шаблона строителя
По сути, цель шаблона Builder — уменьшить количество параметров, используемых конструкторами, и предоставить способ добавления гибкого поведения к объектам.
// 使用建造者模式之前
const person1 = new Person('Peter', 26, true, 40074986, 4, 2);
// 使用建造者模式之后
const person1 = new Person();
person1
.name('Peter')
.age(26)
.member(true)
.phone(40074986)
.children(4)
.cars(2);
2. ES6
режим строителя в
Предположим, что в бизнес-сценарии системы ввода товаров есть четыре обязательных данных, а именно: название, цена и классификация.
Долженbuild
метод вернет окончательныйJavaScript
объект.
/书籍建造者类
class ProductBuilder {
constructor() {
this.name = '';
this.price = 0;
this.category = '';
}
withName(name) {
this.name = name
return this
}
withPrice(price) {
this.price = price
return this
}
withCategory(category) {
this.category = category
return this
}
build() {
return {
name: this.name,
price: this.price,
category: this.category,
}
}
}
console.log(
new ProductBuilder()
.withName('《哈利·波特》')
.withCategory('book')
.withPrice('29.9')
.build()
Хотя объектов всего три, наш конструктор уже довольно большой и требует многоwithers
.
Размер построителя растет линейно с количеством полей. у нас слишком многоwithxxxx
метод. На самом деле мы можем автоматически создавать такого родаwithxxxx
метод упрощения кода.
3. Упрощенный режим строителя
class ProductBuilder {
constructor() {
this.name = ''
this.price = ''
this.category = 'other'
// 为每个属性生成`wither`
Object.keys(this).forEach(key => {
const witherName = `with${key.substring(0, 1).toUpperCase()}${key.substring(1)}`
this[witherName] = value => {
this[key] = value
return this
}
})
}
build() {
// 获取此生成器的所有非函数属性的数组
const keysNoWithers = Object.keys(this).filter(key => typeof this[key] !== 'function')
return keysNoWithers.reduce((returnValue, key) => {
return {
...returnValue,
[key]: this[key],
}
}, {})
}
}
console.log(
new ProductBuilder()
.withName('《哈利波特》')
.withCategory('book')
.build()
)
Мы автоматически создадим все методы построения с xxxx при вызове конструктора Здесь мы используем новый синтаксис ES6: Object.keys получает массив свойств объекта, ... синтаксис для слияния объектов
В итоге у нас есть декларативный (легкий для понимания) подход и шаблон построителя, в котором свойства можно добавлять динамически.
5. Извлеките общие части и внедрите несколько сборщиков
Когда у вас много построителей, мы можем легко извлечь их обобщенные части в общий родительский класс, что упрощает создание новых построителей.
class BaseBuilder {
init() {
Object.keys(this).forEach((key) => {
const witherName = `with${key.substring(0,1).toUpperCase()}${key.substring(1)}`;
this[witherName] = (value) => {
this[key] = value;
return this;
};
});
}
build() {
const keysNoWithers = Object.keys(this).filter((key) => (
typeof this[key] !== 'function'
));
return keysNoWithers.reduce((returnValue, key) => {
return {
...returnValue,
[key]: this[key]
};
}, {});
}
}
Затем вы можете создать несколько сборщиков:
class ProductBuilder extends BaseBuilder {
constructor() {
super();
this.name = '《前端劝退秘诀》';
this.price = 9.99;
this.category = 'other';
super.init();
}
}
Видно, что использование шаблона построителя подходит только для создания чрезвычайно сложных объектов. В реальном интерфейсном бизнесе, когда нет такого чрезвычайно сложного создания объектов, объекты должны создаваться непосредственно с использованием объектных литералов или фабричных шаблонов.
4. Режим прототипа
prototype
...и тогда я буду зарублен насмерть.
5. Далее: Шаблоны структурного проектирования
Изначально я планировал ограничиться более чем 10 000 слов и снова и снова писать все шаблоны проектирования.
Но я думаю, что этот опыт чтения на самом деле не очень хорош (в основном лень, я хочу писать медленно.)
Ах да, теперь еще есть надежные инсайдеры, которые могут связаться со мной
- WeChat:
huab119
- Почта:
454274033@qq.com
Справочная статья
- An Exploration of JavaScript Builders
- The Builder Pattern
- «Путь фронтенд-интервью»
Сборник статей автора Nuggets
Если вам нужно перепечатать его в публичный аккаунт, просто позвоните мне и добавьте его в белый список.
- Руководство "True® Full Stack Road" для веб-интерфейсной разработки
- «Практика Vue» — плагин Vue CLI за 5 минут
- Вооружите свой интерфейсный проект «Практикой Vue»
- «Intermediate and Advanced Front-End Interview» JavaScript Рукописный код Invincible Cheats
- «Узнайте из исходного кода» ответы на вопросы Vue, которые интервьюеры не знают
- JS-операция «Узнать из исходного кода» в исходном коде Vue
- «Учитесь на основе исходного кода» полностью разбирайтесь в параметрах Vue.
- Правильная позиция для обновления vue-cli3 в проекте "Vue Practice"
- Почему вы до сих пор не можете понять цепочку областей видимости JavaScript?