Паттерн "Шаблонный метод"
Паттерн "Шаблонный метод" (Template Method) определяет скелет алгоритма в методе, оставляя определение реализации некоторых шагов подклассам. Этот паттерн позволяет подклассам переопределять определенные шаги алгоритма без изменения структуры алгоритма.
Рассмотрим пример, где мы используем паттерн "Шаблонный метод" в Angular для обработки различных типов данных, например, для рендеринга различных форм.
Создание базового класса с шаблонным методом
Для начала создадим абстрактный класс FormRenderer, который будет содержать шаблонный метод render и шаги алгоритма, которые могут быть переопределены в подклассах.
// form-renderer.ts
export abstract class FormRenderer {
render(): void {
this.setup();
this.renderHeader();
this.renderForm();
this.renderFooter();
this.teardown();
}
protected setup(): void {
console.log('Default setup');
}
protected teardown(): void {
console.log('Default teardown');
}
protected abstract renderHeader(): void;
protected abstract renderForm(): void;
protected abstract renderFooter(): void;
}
Создание подклассов
Теперь создадим два подкласса: UserFormRenderer и ProductFormRenderer, которые будут предоставлять конкретные реализации для методов renderHeader, renderForm и renderFooter.
// user-form-renderer.ts
import { FormRenderer } from './form-renderer';
export class UserFormRenderer extends FormRenderer {
protected renderHeader(): void {
console.log('Rendering User Form Header');
}
protected renderForm(): void {
console.log('Rendering User Form Fields');
}
protected renderFooter(): void {
console.log('Rendering User Form Footer');
}
}
// product-form-renderer.ts
import { FormRenderer } from './form-renderer';
export class ProductFormRenderer extends FormRenderer {
protected renderHeader(): void {
console.log('Rendering Product Form Header');
}
protected renderForm(): void {
console.log('Rendering Product Form Fields');
}
protected renderFooter(): void {
console.log('Rendering Product Form Footer');
}
}
Использование
Теперь создадим Angular компонент, который будет использовать шаблонный метод для рендеринга различных форм.
// form.component.ts
import { Component, OnInit } from '@angular/core';
import { UserFormRenderer } from './user-form-renderer';
import { ProductFormRenderer } from './product-form-renderer';
import { FormRenderer } from './form-renderer';
@Component({
selector: 'app-form',
template: `
<button (click)="renderUserForm()">Render User Form</button>
<button (click)="renderProductForm()">Render Product Form</button>
`
})
export class FormComponent implements OnInit {
constructor() {}
ngOnInit(): void {}
renderUserForm(): void {
const userFormRenderer: FormRenderer = new UserFormRenderer();
userFormRenderer.render();
}
renderProductForm(): void {
const productFormRenderer: FormRenderer = new ProductFormRenderer();
productFormRenderer.render();
}
}
Объяснение
- Абстрактный класс
FormRenderer: - Определяет метод
render, который является шаблонным методом и задает последовательность шагов. - Содержит абстрактные методы
renderHeader,renderFormиrenderFooter, которые должны быть реализованы в подклассах. - Включает методы
setupиteardown, которые имеют базовую реализацию и могут быть переопределены в подклассах при необходимости. - Конкретные классы
UserFormRendererиProductFormRenderer: - Реализуют абстрактные методы для конкретного типа формы (пользовательской и продуктовой формы соответственно).
- Компонент
FormComponent: