Паттерны проектирования в TypeScript
-
Доброго вечерочка, сегодня хотел бы немного рассказать про ООП в TS, и то что оно было бы не полным без обсуждения и реализации пары паттеронов проектирования.
Начнем!
Паттерн фабрики
Паттерн фабрики - это способ создания объекта, на основе которого можно сформировать объекты схожего типа.
Для примера попробуем построить фабрику погромистов, начнем с определения тип Programmer:
type Programmer = { grade: string }
class Junior implements Programmer { grade: 'junior' } class Middle implements Programmer { grade: 'middle' } class Senior implements Programmer { grade: 'senior' }
В этом примере мы используем type, хотя с тем же успехом могли воспользоваться и interface.
Теперь приступим к созданию самой фабрики:
let Programmer = { create(type: 'junior' | 'middle' | 'senior'): Programmer { switch (type) { case 'junior': retrun new Junior case 'midle': retrun new Middle case 'Senior ': retrun new Senior } } }
Важное что хочется отметить:
- Использование объединения типов позволяет обеспечить максимальную безопасность метода
.create
, тем самым избегая ошибок из-за некорректного типа данных, передаваемого пользователями во время компиляции. - Использование type в TypeScript позволяет гарантировать, что каждый тип Programmer был учтен.
В данном случае мы применили паттерн “объект-компаньон” для создания типа
Programmer
и значенияProgrammer
с совпадающим именем, что позволяетTypeScript
различать пространства имен для типов и значений. Таким образом, мы определили, что данное значение предоставляет методы, работающие с этим типом. Процесс начинается с вызова метода.create
:Programmer.create('junior') //Junior
Хуяк-хуяк - Мы здесь используем паттерн “фабрика”. Можно дополнительно настроить сигнатуру метода
Programmer.create
, чтобы, например, передача параметра'junior'
возвращала объект типаJunior
, а'middle'
—Middle
. Однако такой подход мог бы подорвать целостность абстракции, которую предлагает паттерн: пользователи не должны заботиться о том, какой именно класс им вернется, главное — что он соответствует ожидаемому интерфейсу.Паттерн строитель
Едем дальше и переходим к паттерну строителю. Строитель - это некий способ отделить конструкцию объекта от его фактической реализации. Если ты пользовался когда либо
JQuery
(Лучше него ничего еще не придумал) или структуруES6
Map
илиSet
, то этот стиль API должен быть знаком почти каждому:new RequestBuilder() .setURL('/users') .setMethod('get') .setData({firstName: 'Lox'}) .send()
И как же мы реализуем это очече спросишь ты ? - ИЗИ, начнем все с читенького класса:
class RequestBuilder {}
Для начала добавим
.setURL
class RequestBuilder { private url: string | null = null setURL(url: string): this { this.url = url return this } }
Смотрим что у нас тут происходит:
- Первое - отслеживаем
URL
, установленный юзером в переменной приватного экземпляра url, которую мы инициализируем с null. - Возвращаем setURL который будет типом
this
, который является конкретным экземпляром RequestBuilder, в котором пользователь вызвал setURL.
А теперь добавим другие методы:
class RequestBuilder { private data: object | null = null private method: 'get' | 'post' | null = null private url: string | null = null setMethod(method: 'get' | 'post'): this { this.method = method return this } setData(data: object): this { this.data = data return this } setURL(url: string): this { this.url = url return this } send() { // ... крутим вертим } }
Ну и в принципе все )))))))))
А вообще традиционный паттерн строитель небезопасен, потому что - мы можем вызвать
.send
до того, как установим метод, урл или другие данные тем самым вызвав исключение в среде выполнения.На этом про паттерны на TS все, обнял, поднял, поцеловал
- Использование объединения типов позволяет обеспечить максимальную безопасность метода
-
Пользователь @kirilljs написал в Паттерны проектирования в TypeScript:
.setData({firstName: ‘Lox’})
Кек