<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Паттерны проектирования в TypeScript]]></title><description><![CDATA[<p dir="auto">Доброго вечерочка, сегодня хотел бы немного рассказать про ООП в TS, и то что оно было бы не полным без обсуждения и реализации пары паттеронов проектирования.</p>
<p dir="auto">Начнем!</p>
<h2>Паттерн фабрики</h2>
<p dir="auto">Паттерн фабрики - это способ создания объекта, на основе которого можно сформировать объекты схожего типа.</p>
<p dir="auto">Для примера попробуем построить фабрику погромистов, начнем с определения тип <strong>Programmer</strong>:</p>
<pre><code class="language-ts">type Programmer = {
  grade: string
}
</code></pre>
<pre><code class="language-ts">class Junior implements Programmer {
  grade: 'junior'
}

class Middle implements Programmer {
  grade: 'middle'
}

class Senior implements Programmer {
  grade: 'senior'
}
</code></pre>
<p dir="auto">В этом примере мы используем <strong>type</strong>, хотя с тем же успехом могли воспользоваться и <strong>interface</strong>.</p>
<p dir="auto">Теперь приступим к созданию самой фабрики:</p>
<pre><code class="language-ts">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 
    }
  }
}
</code></pre>
<p dir="auto">Важное что хочется отметить:</p>
<ul>
<li>Использование объединения типов позволяет обеспечить максимальную безопасность метода <code>.create</code>, тем самым избегая ошибок из-за некорректного типа данных, передаваемого пользователями во время компиляции.</li>
<li>Использование <strong>type</strong> в <strong>TypeScript</strong> позволяет гарантировать, что каждый тип <strong>Programmer</strong> был учтен.</li>
</ul>
<p dir="auto">В данном случае мы применили паттерн “объект-компаньон” для создания типа <code>Programmer</code> и значения <code>Programmer</code> с совпадающим именем, что позволяет <code>TypeScript</code> различать пространства имен для типов и значений. Таким образом, мы определили, что данное значение предоставляет методы, работающие с этим типом. Процесс начинается с вызова метода <code>.create</code>:</p>
<pre><code class="language-ts">Programmer.create('junior') //Junior
</code></pre>
<p dir="auto">Хуяк-хуяк - Мы здесь используем паттерн “фабрика”. Можно дополнительно настроить сигнатуру метода <code>Programmer.create</code>, чтобы, например, передача параметра <code>'junior'</code>возвращала объект типа <code>Junior</code>, а <code>'middle'</code> — <code>Middle</code>. Однако такой подход мог бы подорвать целостность абстракции, которую предлагает паттерн: пользователи не должны заботиться о том, какой именно класс им вернется, главное — что он соответствует ожидаемому интерфейсу.</p>
<h2>Паттерн строитель</h2>
<p dir="auto">Едем дальше и переходим к паттерну строителю. Строитель - это некий способ отделить конструкцию объекта от его фактической реализации. Если ты пользовался когда либо <code>JQuery</code> (Лучше него ничего еще не придумал) или структуру <code>ES6</code> <code>Map</code> или <code>Set</code>, то этот стиль API должен быть знаком почти каждому:</p>
<pre><code class="language-ts">new RequestBuilder()
  .setURL('/users')
  .setMethod('get')
  .setData({firstName: 'Lox'})
  .send()
</code></pre>
<p dir="auto">И как же мы реализуем это очече спросишь ты ? - ИЗИ, начнем все с читенького класса:</p>
<pre><code class="language-ts">class RequestBuilder {}
</code></pre>
<p dir="auto">Для начала добавим <code>.setURL</code></p>
<pre><code class="language-ts">class RequestBuilder {
  private url: string | null = null
  
  setURL(url: string): this {
    this.url = url
    return this
  }
}
</code></pre>
<p dir="auto">Смотрим что у нас тут происходит:</p>
<ul>
<li>Первое - отслеживаем <code>URL</code>, установленный юзером в переменной приватного экземпляра <strong>url</strong>, которую мы инициализируем с <strong>null</strong>.</li>
<li>Возвращаем setURL который будет типом <code>this</code>, который является конкретным экземпляром RequestBuilder, в котором пользователь вызвал setURL.</li>
</ul>
<p dir="auto">А теперь добавим другие методы:</p>
<pre><code class="language-ts">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() {
    // ... крутим вертим
  }
}
</code></pre>
<p dir="auto">Ну и в принципе все )))))))))</p>
<p dir="auto">А вообще традиционный паттерн строитель небезопасен, потому что - мы можем вызвать <code>.send</code>  до того, как установим метод, урл или другие данные тем самым вызвав исключение в среде выполнения.</p>
<p dir="auto">На этом про паттерны на TS все, обнял, поднял, поцеловал <img src="https://forum.exlends.com/assets/plugins/nodebb-plugin-emoji/emoji/android/2764.png?v=a9b928d4b2f" class="not-responsive emoji emoji-android emoji--heart" style="height:23px;width:auto;vertical-align:middle" title="&lt;3" alt="❤" /></p>
]]></description><link>https://forum.exlends.com/topic/8/patterny-proektirovaniya-v-typescript</link><generator>RSS for Node</generator><lastBuildDate>Sat, 18 Apr 2026 01:35:19 GMT</lastBuildDate><atom:link href="https://forum.exlends.com/topic/8.rss" rel="self" type="application/rss+xml"/><pubDate>Thu, 30 May 2024 18:21:14 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Паттерны проектирования в TypeScript on Fri, 31 May 2024 07:03:05 GMT]]></title><description><![CDATA[<p dir="auto">Пользователь @kirilljs написал в <a href="/post/18">Паттерны проектирования в TypeScript</a>:</p>
<blockquote>
<p dir="auto">.setData({firstName: ‘Lox’})</p>
</blockquote>
<p dir="auto">Кек</p>
]]></description><link>https://forum.exlends.com/post/20</link><guid isPermaLink="true">https://forum.exlends.com/post/20</guid><dc:creator><![CDATA[Manul]]></dc:creator><pubDate>Fri, 31 May 2024 07:03:05 GMT</pubDate></item></channel></rss>