<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Iaan Mesquita</title>
    <description>The latest articles on DEV Community by Iaan Mesquita (@ianito).</description>
    <link>https://dev.to/ianito</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F651949%2Fb2f935e6-6bdd-42dd-bcf2-4d86c27703a9.jpg</url>
      <title>DEV Community: Iaan Mesquita</title>
      <link>https://dev.to/ianito</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ianito"/>
    <language>en</language>
    <item>
      <title>Observer Pattern: Keeping Components in Sync</title>
      <dc:creator>Iaan Mesquita</dc:creator>
      <pubDate>Sun, 27 Aug 2023 16:32:05 +0000</pubDate>
      <link>https://dev.to/ianito/observer-pattern-keeping-components-in-sync-j02</link>
      <guid>https://dev.to/ianito/observer-pattern-keeping-components-in-sync-j02</guid>
      <description>&lt;p&gt;Hi again,&lt;/p&gt;

&lt;p&gt;If you don't know me, my name is Iaan Mesquita.&lt;/p&gt;

&lt;p&gt;Today, we'll discuss about Observer Pattern - Behavioral Pattern.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Also known as: &lt;strong&gt;Event-Subscriber&lt;/strong&gt; and &lt;strong&gt;Listener&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I recommend you start from my last article (&lt;a href="https://dev.to/ianito/design-patterns-factory-method-22if"&gt;Factory Method: Simplifying Object Instantiation&lt;/a&gt;) because there are some concepts that are good to know before starting this. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Like I said in the previous article, not always I'll use the best approaches to explain the pattern because I want to make the article simpler for those who don't know about this pattern&lt;/p&gt;

&lt;p&gt;And also, it's good to have an understanding of Object-Oriented Programming (OOP) and SOLID principles.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Concepts&lt;/li&gt;
&lt;li&gt;Problem&lt;/li&gt;
&lt;li&gt;Resolving problem without Observer pattern&lt;/li&gt;
&lt;li&gt;Observer Pattern&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;li&gt;References&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As you know, before we start, let's take a look at a concept. &lt;/p&gt;

&lt;h2&gt;
  
  
  Concepts
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Don't Repeat Yourself (DRY)
&lt;/h3&gt;

&lt;p&gt;Don't Repeat Yourself (DRY) is a software development principle aimed at reducing the repetition of code patterns. The main idea behind DRY is to eliminate redundant code: if you have two or more identical code blocks in different parts of your software, you might be doing something wrong.&lt;/p&gt;

&lt;p&gt;The main advantage of this principle is that it has better maintainability in the entire lifetime of your software. Imagine you have a lot of places inside your code that are the same, if you change the behavior of it you need to change it in a lot of places.&lt;/p&gt;

&lt;p&gt;But, don't take this principle strictly true, you need to understand WHEN and HOW to apply it to work well. DRY shouldn't be a problem or concern for you.&lt;/p&gt;

&lt;p&gt;We can discuss in the future a good example of "DRY(ing) in a bad way"&lt;/p&gt;

&lt;h2&gt;
  
  
  Problem
&lt;/h2&gt;

&lt;p&gt;Taylor Alexis is a smart person, currently, she works in a big company that sells a lot of video games, but there are two that are the most sold and are very disputated: &lt;strong&gt;Playstation&lt;/strong&gt; and &lt;strong&gt;Xbox&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;And she knows these two brands have a lot of fanboys that can not hear the other brand's name because they get very mad.&lt;/p&gt;

&lt;p&gt;But the business doesn't care and just wants to sell a lot of video games, whatever fanboys they are. These video games sell so fast but there is a waitlist that they subscribe to and get emailed when the video game has come into the store.&lt;/p&gt;

&lt;p&gt;Despite the business needs to sell a lot, whatever kind of fanboys they were, it's not a good idea to send an email that they don't want to. Like: "THE BEST CONSOLE EVER HAS COME TO OUR STORE: PLAYSTATION / XBOX". &lt;/p&gt;

&lt;h3&gt;
  
  
  Resolving problem without Observer pattern
&lt;/h3&gt;

&lt;p&gt;Taylor had been on vacation when everything happened, and the team decided to implement one solution for this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Whatsapp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SMS&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../services&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SendMessageToWaitlisteners&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;serviceName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;xboxSubscribersList&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;playstationList&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;serviceName&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;email&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;contactInfo&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;xboxSubscribersList&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Email&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;contactInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;sendMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;THE BEST CONSOLE EVER HAS COME TO OUR STORE: XBOX&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;contactInfo&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;playstationList&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Email&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;contactInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;sendMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;THE BEST CONSOLE EVER HAS COME TO OUR STORE: PLAYSTATION&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But the customers started to complain because they don't use Email, they use WhatsApp and SMS and they wanted receive the message through these platforms. So the team implemented the other behaviors:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Whatsapp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SMS&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../services&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SendMessageToWaitlisteners&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;serviceName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;xboxSubscribersList&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;playstationList&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;serviceName&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;email&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;contactInfo&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;xboxSubscribersList&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Email&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;contactInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;sendMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;THE BEST CONSOLE EVER HAS COME TO OUR STORE: XBOX&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;contactInfo&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;playstationList&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Email&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;contactInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;sendMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;THE BEST CONSOLE EVER HAS COME TO OUR STORE: PLAYSTATION&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;serviceName&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;whatsapp&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;contactInfo&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;xboxSubscribersList&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Whatsapp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;contactInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;numberPhone&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;sendMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;THE BEST CONSOLE EVER HAS COME TO OUR STORE: XBOX&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;contactInfo&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;playstationList&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Whatsapp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;contactInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;numberPhone&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;sendMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;THE BEST CONSOLE EVER HAS COME TO OUR STORE: PLAYSTATION&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;serviceName&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;sms&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;contactInfo&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;xboxSubscribersList&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;SMS&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;contactInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;numberPhone&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;sendMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;THE BEST CONSOLE EVER HAS COME TO OUR STORE: XBOX&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;contactInfo&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;playstationList&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;SMS&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;contactInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;numberPhone&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;sendMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;THE BEST CONSOLE EVER HAS COME TO OUR STORE: PLAYSTATION&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Even though everything was working fine, they realized that the code was so ugly, then they decided to isolate the part they think was repeating and isolate the message:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Whatsapp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SMS&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../services&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SendMessageToWaitlisteners&lt;/span&gt;  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="nx"&gt;createMessage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;consoleName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;`THE BEST CONSOLE EVER HAS COME TO OUR STORE: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;consoleName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
    &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;serviceName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;xboxSubscribersList&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;playstationList&lt;/span&gt;
          &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;xboxMessage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;SendMessageToWaitlisteners&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;XBOX&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;playstatioMessage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;SendMessageToWaitlisteners&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;PLAYSTATION&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;contactInfo&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;xboxSubscribersList&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;serviceName&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;email&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Email&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;contactInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;sendMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;xboxMessage&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;serviceName&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;whatsapp&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Whatsapp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;contactInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;numberPhone&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;sendMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;xboxMessage&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;serviceName&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;sms&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;SMS&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;contactInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;numberPhone&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;sendMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;xboxMessage&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;contactInfo&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;playstationList&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;serviceName&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;email&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Email&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;contactInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;sendMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;playstatioMessage&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;serviceName&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;whatsapp&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Whatsapp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;contactInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;numberPhone&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;sendMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;playstatioMessage&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;serviceName&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;sms&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;SMS&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;contactInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;numberPhone&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;sendMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;playstatioMessage&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You may be thinking the code now is better (at least compared to before), but &lt;strong&gt;NO!&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Of course, we have a problem with repetition but the most evident problem in this code is COUPLING.&lt;/p&gt;

&lt;p&gt;What if the business needs to send different messages for each service? For instance, with WhatsApp, I would like to use some emojis, so would I create another variable and use it?&lt;/p&gt;

&lt;p&gt;What if the business needs to implement another service, like messaging through Messenger? Should I create another conditional and implement the service?&lt;/p&gt;

&lt;p&gt;What if the business needs to update another software that is interested in this behavior? Like, posting into a business's social networks? Should we create another conditional? &lt;/p&gt;

&lt;p&gt;OMG, so chaotic. 🤪&lt;/p&gt;

&lt;h2&gt;
  
  
  Observer Pattern
&lt;/h2&gt;

&lt;p&gt;Taylor has come back from her vacation and went to her job. When she went there and started to work on code the team started being worried about her because they thought she would complain about code quality when would read. But she just says: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I know you guys tried your best with all constraints and context and I really appreciate it. Everything worked as expected, however, looking ahead, we need to improve this to help us in the future, especially because we probably will need to implement a lot of things in the future based on this behavior(Out-of-stock console arrived in-store). So, let's go guys, let's implement Observer Pattern.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The Observer Pattern is a Behavioral Design Pattern that allows an object (known as the "subject/observable/event/publisher") to publish changes to its state so that other objects (known as "observers/listeners/subscribers") can react accordingly. &lt;/p&gt;

&lt;p&gt;Let's understand some concepts about the Observer pattern using our example below and cleaning up our code when it's possible:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Subject:&lt;/strong&gt; This is an interface that declares a set of methods for managing subscribers.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;In our example:&lt;/strong&gt; Subject Interface&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Subject&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;addObserver&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;observer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Observer&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nf"&gt;removeObserver&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;observer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Observer&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nf"&gt;notifyAll&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Observer:&lt;/strong&gt; This is an interface or abstract class representing any object that needs to be notified of changes by the subject.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;In our example:&lt;/strong&gt; Observer Interface&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Observer&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;currentQuantityInStock&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;ConcreteSubject:&lt;/strong&gt; ConcreteSubject is a class that implements the Subject interface and contains the actual state or data that the observers are interested in. When this state changes, the observers need to be notified. In our case to simplify our example, we will just notifyAll when our state changes to positively.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;In our example:&lt;/strong&gt; PlaystationStockConcreteSubject and XboxStockConcreteSubject classes&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PlaystationStockConcreteSubject&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;Subject&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;observers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Observer&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;_quantityInStock&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;
    &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="kd"&gt;get&lt;/span&gt; &lt;span class="nf"&gt;quantityInStock&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_quantityInStock&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="kd"&gt;set&lt;/span&gt; &lt;span class="nf"&gt;quantityInStock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_quantityInStock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;notifyAll&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nf"&gt;addObserver&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;observer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Observer&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;observers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;observer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nf"&gt;removeObserver&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;observer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Observer&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;observers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;indexOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;observer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;observers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;splice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nf"&gt;notifyAll&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;observer&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;observers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;observer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;quantityInStock&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;XboxStockConcreteSubject&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;Subject&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;observers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Observer&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;_quantityInStock&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;
    &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="kd"&gt;get&lt;/span&gt; &lt;span class="nf"&gt;quantityInStock&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_quantityInStock&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="kd"&gt;set&lt;/span&gt; &lt;span class="nf"&gt;quantityInStock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_quantityInStock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;notifyAll&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nf"&gt;addObserver&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;observer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Observer&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;observers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;observer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nf"&gt;removeObserver&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;observer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Observer&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;observers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;indexOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;observer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;observers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;splice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nf"&gt;notifyAll&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;observer&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;observers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;observer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;quantityInStock&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;ConcreteObserver:&lt;/strong&gt; A class that implements the Observer. It will have a method to get updated data from the Subject.&lt;/p&gt;

&lt;p&gt;To summarize things, let's assume that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Xbox users only want to be notified by email and WhatsApp.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;PlayStation users only by SMS.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The system wants to post on social networks if Xbox or PlayStation increases their stocks.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;In our example:&lt;/strong&gt; XboxEmailNotificator,XboxWhatsappNotificator,PlaystationSmsNotificator and SocialNetworkNotificator classes&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;XboxEmailNotificator&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;Observer&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;emailService&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;emailList&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;
        &lt;span class="p"&gt;){}&lt;/span&gt;
    &lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;currentQuantityInStock&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;emailService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Hello, this is an email to let you know about our Xbox stock, we have &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;currentQuantityInStock&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; available!!`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;emailList&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;XboxWhatsappNotificator&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;Observer&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;whatsappService&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;numbersPhone&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;
    &lt;span class="p"&gt;){}&lt;/span&gt;
    &lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;currentQuantityInStock&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;whatsappService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Hey buddy 😃, come on to our store there is a lot of &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;currentQuantityInStock&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; xbox available!! 💁💁`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;numbersPhone&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PlaystationSmsNotificator&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;Observer&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;whatsappService&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;numbersPhone&lt;/span&gt;
    &lt;span class="p"&gt;){}&lt;/span&gt;
    &lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;currentQuantityInStock&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;whatsappService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Hey!!! There is &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;currentQuantityInStock&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; PLAYSTATIONS available!! 💁💁`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;numbersPhone&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SocialNetworkNotificator&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;Observer&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;facebookSDK&lt;/span&gt;
    &lt;span class="p"&gt;){}&lt;/span&gt;
    &lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;currentQuantityInStock&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;facebookSDK&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Stock Update! New consoles now available. Grab yours! 🚀 #Restocked`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And our client code may look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;
&lt;span class="c1"&gt;//Fake data&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fakeEmails&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;iaan.123@gmail.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;another_guy@123xyz.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;johndoe@johndoe.com&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fakeNumbers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;+1999999999&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;+11231111111&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;+167145349873648&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="c1"&gt;//ConcreteSubjects&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;xboxStockConcreteSubject&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;XboxStockConcreteSubject&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;playstationStockConcreteSubject&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;PlaystationStockConcreteSubject&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;//ConcreteObservers&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;xboxEmailNotificator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;XboxEmailNotificator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;EmailService&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nx"&gt;fakeEmails&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;xboxWhatsappNotificator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;XboxWhatsappNotificator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;WhatsappService&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nx"&gt;fakeNumbers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;playstationSmsNotificator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;PlaystationSmsNotificator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;SmsService&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nx"&gt;fakeNumbers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;socialNetworkNotificator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;SocialNetworkNotificator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;FacebookSDK&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

&lt;span class="c1"&gt;//Registering observers into subject&lt;/span&gt;
&lt;span class="nx"&gt;xboxStockConcreteSubject&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addObserver&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;xboxEmailNotificator&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;xboxStockConcreteSubject&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addObserver&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;xboxWhatsappNotificator&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;playstationStockConcreteSubject&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addObserver&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;playstationSmsNotificator&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;xboxStockConcreteSubject&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addObserver&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;socialNetworkNotificator&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;playstationStockConcreteSubject&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addObserver&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;socialNetworkNotificator&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And when my state inside my concrete subjects is updated, so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;
&lt;span class="nx"&gt;xboxStockConcreteSubject&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;quantityInStock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;9999&lt;/span&gt;
&lt;span class="cm"&gt;/**
 * Email Sent: Hello, this is an email to let you know about our Xbox stock, we have 9999 available!!
 * Whatsapp Sent: Hey buddy 😃, come on to our store there is a lot of 9999 xbox available!! 💁💁
 * Facebook Post Sent: Stock Update! New consoles now available. Grab yours! 🚀 #Restocked
 */&lt;/span&gt;

&lt;span class="nx"&gt;playstationStockConcreteSubject&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;quantityInStock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;
&lt;span class="cm"&gt;/**
 * Sms Sent: Hey!!! There is 25 PLAYSTATIONS available!! 💁💁
 * Facebook Post Sent: Stock Update! New consoles now available. Grab yours! 🚀 #Restocked
 */&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, if just need to create a new behavior in a system that will execute if the stock is updated, I just need to create a new class that implements Observer and register it into a specific ConcretClass (Like PlaystationStockConcreteSubject)&lt;/p&gt;

&lt;p&gt;I can also register/remove an observer at any time, even at runtime.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pros &amp;amp; Cons
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Pros:
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Decoupling:&lt;/strong&gt; The Observer pattern promotes a decoupled design where subjects and observers can interact without being tightly linked.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- Single Responsibility Principle:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The Subject has the responsibility of managing its observers. It can attach, detach, and notify observers, but it doesn't concern itself with what these observers do with the information. This separation ensures that the Subject remains focused on its core task.&lt;/li&gt;
&lt;li&gt;Each Observer has its own responsibility for how it reacts to the notifications from the Subject. One observer might send notifications to customers, another might post on social network, and more. By keeping these responsibilities separate, the Observer Pattern adheres to the SRP.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;- Open Closed Principle&lt;/strong&gt;: You can introduce new types of Subjects/Observers into the program without breaking existing client code, just implementing the contracts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dynamic Relationships:&lt;/strong&gt; Observers can be added or removed at runtime, offering dynamic relationships.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Broadcast Communication:&lt;/strong&gt; A single subject can notify multiple observers without knowing who or what those observers are.&lt;/p&gt;

&lt;h4&gt;
  
  
  Cons
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Overhead:&lt;/strong&gt; The pattern can introduce overengineering, especially if not many components need to be observed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Randomly Update:&lt;/strong&gt; The subscribers will be updated but in a random order.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Unexpected Updates:&lt;/strong&gt; Observers might receive updates they didn't expect, leading to potential issues.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Memory Leaks:&lt;/strong&gt; If observers aren't properly removed, it can lead to memory leaks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Thanks for reading.&lt;/p&gt;

&lt;p&gt;We learned in this article that the Observer pattern can promote a more modular and scalable architecture, making systems easier to extend and maintain without coupling components.&lt;/p&gt;

&lt;p&gt;However, remember this quote: "Not every problem is a nail, so use your hammer wisely."&lt;/p&gt;

&lt;p&gt;I'm so excited to write these articles because I'm challenging myself to organize my thoughts, improve my writing (English is not my first language), and help people who are interested in these kinds of subjects.&lt;/p&gt;

&lt;p&gt;As always, your feedback, suggestions, and critiques are welcome.&lt;/p&gt;

&lt;p&gt;I hope you enjoyed it and I hope to see you in the next article.&lt;/p&gt;

&lt;p&gt;Bye.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://refactoring.guru/design-patterns/observer" rel="noopener noreferrer"&gt;Refactoring.guru - Observer&lt;/a&gt;&lt;br&gt;
&lt;a href="https://en.wikipedia.org/wiki/Observer_pattern" rel="noopener noreferrer"&gt;Observer pattern - Wikipedia&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.youtube.com/watch?v=4OLCrClb_So" rel="noopener noreferrer"&gt;Você nunca mais vai conseguir ler um código da mesma forma... - Filipe Deschamps&lt;/a&gt;&lt;br&gt;
&lt;a href="https://en.wikipedia.org/wiki/Don%27t_repeat_yourself#:~:text=%22Don't%20repeat%20yourself%22,redundancy%20in%20the%20first%20place." rel="noopener noreferrer"&gt;DRY - Wikipedia&lt;/a&gt;&lt;br&gt;
&lt;a href="https://unity.com/how-to/create-modular-and-maintainable-code-observer-pattern" rel="noopener noreferrer"&gt;Observer - Unity&lt;/a&gt;&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>beginners</category>
      <category>patterns</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>Design Patterns: Factory Method [PT-BR]</title>
      <dc:creator>Iaan Mesquita</dc:creator>
      <pubDate>Sat, 19 Aug 2023 16:54:42 +0000</pubDate>
      <link>https://dev.to/ianito/design-patterns-factory-method-pt-br-21a3</link>
      <guid>https://dev.to/ianito/design-patterns-factory-method-pt-br-21a3</guid>
      <description>&lt;p&gt;&lt;em&gt;English version: &lt;a href="https://dev.to/ianito/design-patterns-factory-method-22if"&gt;https://dev.to/ianito/design-patterns-factory-method-22if&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Olá,&lt;/p&gt;

&lt;p&gt;Se você ainda não me conhece, eu me chamo Iaan Mesquita. &lt;/p&gt;

&lt;p&gt;Atuo como engenheiro de software e hoje darei início a uma série de artigos que falam um pouco sobre a área de Engenharia de Software/Arquitetura de Software.&lt;/p&gt;

&lt;p&gt;Mas antes, você provavelmente pode se perguntar: Por que os padrões de projeto são tão importantes? Bem, eles fornecem soluções para problemas comuns com os quais nós, como desenvolvedores, precisamos lidar. Assim, o uso de padrões de projeto podem tornar o software mais fácil de entender (embora nem sempre), estender e manter.&lt;/p&gt;

&lt;p&gt;Recomendo começar essa série por este artigo, pois irei introduzir alguns conceitos que serão fundamentais para os próximos artigos. Para evitar repetições, aconselho que você se familiarize com esses conceitos básicos.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nota:&lt;/strong&gt; Nem sempre seguirei as práticas mais recomendadas ao explicar um padrão de design específico (já que meu objetivo é focar no conceito em questão). Todo feedback é bem-vindo, mas entenda essa limitação pois quero explicar os conceitos de uma forma que algum iniciante possa entender. Além disso, alguns termos não serão traduzidos pois eu acho que mais bagunça do que ajuda.&lt;/p&gt;

&lt;p&gt;Também é interessante ter uma compreensão de Programação Orientada a Objetos (POO) e dos princípios SOLID.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resumo
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Readability vs Writability&lt;/li&gt;
&lt;li&gt;Injeção de Dependência&lt;/li&gt;
&lt;li&gt;Padrões Criacionais, Estruturais, e Comportamentais&lt;/li&gt;
&lt;li&gt;Problema&lt;/li&gt;
&lt;li&gt;Factory Method&lt;/li&gt;
&lt;li&gt;Prós &amp;amp; Contras&lt;/li&gt;
&lt;li&gt;Conclusão&lt;/li&gt;
&lt;li&gt;Referências&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Antes de começar a discutir os padrões de design, vamos dar uma olhada em alguns conceitos:&lt;/p&gt;

&lt;h3&gt;
  
  
  Readability vs Writability
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Readability&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Significa a facilidade com que um código pode ser lido e compreendido por outros desenvolvedores.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Writability&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Significa a facilidade com que um código pode ser escrito. Isso não tem nada a ver com a velocidade de que você escreve um código. Podemos entender esse conceito pela facilidade de expressar nossas ideias como desenvolvedores. Se você já trabalhou com a linguagem C, pode entender esse conceito se lembrando da manipulação de strings e comparando-a com outra linguagem, tipo Javascript.&lt;/p&gt;

&lt;p&gt;Esses dois conceitos são muito importantes no campo da engenharia de software (mas não exclusivamente). Em geral, você não criará coisas novas, mas aprimorará coisas que já existem e, para isso, a readability e writability podem afetar nosso software a longo prazo.&lt;/p&gt;

&lt;p&gt;Se você pudesse escolher entre um software que pudesse ser lido/extendido com facilidade ou um software em que cada desenvolvedor decidisse seguir seus próprios padrões, qual você escolheria?&lt;/p&gt;

&lt;p&gt;A menos que esteja tentando se desafiar, eu sei a resposta. xD&lt;/p&gt;

&lt;p&gt;No entanto, isso não significa que todos os padrões comumente conhecidos ofereçam uma ótima writability ou readability. Às vezes, precisaremos priorizar um em detrimento do outro por motivos de melhor extensibilidade ou até mesmo, restrições específicas do projeto/equipe.&lt;/p&gt;

&lt;p&gt;De qualquer forma, entender esses conceitos é crucial para discutir, decidir e aplicá-los quando necessário.&lt;/p&gt;

&lt;h3&gt;
  
  
  Injeção de dependência
&lt;/h3&gt;

&lt;p&gt;A injeção de dependência (DI) é um padrão de design de software que define como os componentes ou objetos devem adquirir suas dependências. Em vez de um objeto criar suas próprias dependências (como instanciar dentro da implementação) ou usar instâncias globais, as dependências são "injetadas" no objeto, normalmente por meio de seu construtor, um método ou propriedades. Isso permite melhor flexibilidade para testes e manutenção no software.&lt;/p&gt;

&lt;p&gt;Apesar de simples, discutiremos esse padrão de design no futuro.&lt;/p&gt;

&lt;h3&gt;
  
  
  Padrões criacionais, estruturais e comportamentais
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Os padrões criacionais&lt;/strong&gt; concentram-se em maneiras de instanciar objetos. Esses padrões oferecem várias técnicas, além do uso de construtores, para garantir a flexibilidade e a capacidade de manutenção.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Os padrões estruturais&lt;/strong&gt; orientam a composição de objetos ou classes, visando à escalabilidade e à capacidade de manutenção.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Os padrões comportamentais&lt;/strong&gt; tratam de como os objetos interagem e se comunicam, enfatizando as responsabilidades dos objetos e como eles se comunicam.&lt;/p&gt;

&lt;p&gt;Porém hoje discutiremos o &lt;strong&gt;Método Fábrica (Factory Method) - (Padrão de Criação)&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Problema
&lt;/h2&gt;

&lt;p&gt;Imagine que você esteja criando um aplicativo para ajudar seu cliente a gerenciar suas contas do Instagram. Como você é uma startup, está validando suas ideias e o primeiro e único recurso que seu aplicativo tem é a capacidade de publicar no Instagram.&lt;/p&gt;

&lt;p&gt;Mas agora seus clientes amaram seu aplicativo e estão sentindo falta de outras redes sociais, como X, Facebook, BlueSky e diversas outras, e você decidiu implementá-las.&lt;/p&gt;

&lt;p&gt;Você ainda não sabe qual a API da rede social que irá implementar, mas sabe que é uma API.&lt;/p&gt;

&lt;p&gt;No entanto, você sabe que cada rede social tem seu próprio método para postar nelas e também tem diferentes dependências e validações mas você sabe que o comportamento é o mesmo: postar em uma rede social.&lt;/p&gt;

&lt;p&gt;Você concorda comigo que todos os lugares dentro do seu aplicativo que precisam ter essa funcionalidade de postar em uma rede social não precisa saber sobre a implementação? Basta funcionar como esperado e publicar nelas? &lt;/p&gt;

&lt;p&gt;Para esse exemplo, vamos supor também que você esteja desenvolvendo seu sistema usando injeção de dependência, passando dependências pelo construtor. Um exemplo disso seria:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;TwitterAPI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;messageValidator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;twitterSDK&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;//or and&lt;/span&gt;
&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;FacebookAPI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;messageValidator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;userIdHash&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;facebookSDK&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;//or and&lt;/span&gt;
&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;InstagramAPI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;instagramSDK&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Não pense muito nos detalhes, apenas capte a ideia principal: Estamos passando algumas dependências que a classe precisa através do construtor.&lt;/p&gt;

&lt;p&gt;Acontece que se precisarmos usar a FacebookAPI/TwitterAPI em muitos lugares, toda vez que nós quisermos usar os métodos da classe, precisaremos primeiro instanciá-la e com isso também  passar suas dependências.&lt;/p&gt;

&lt;p&gt;Mas não só isso, o que acontece se o Facebook decidir que não permitirá que você publique na plataforma deles antes de confirmar que você não é um robô e você precisa fazer essa validação por você mesmo? Como resultado, você precisará validar isso antes de enviar, e agora você tem muitos lugares para fazer essa alteração porque uma coisa mudou na forma de como se comunicar com a API do Facebook.&lt;/p&gt;

&lt;p&gt;Portanto, uma solução para esse problema é usar Factories.&lt;/p&gt;

&lt;h3&gt;
  
  
  Método Fábrica (Factory Method)
&lt;/h3&gt;

&lt;p&gt;O &lt;strong&gt;Factory Method&lt;/strong&gt; é um padrão de design de criação que fornece uma interface para a criação de objetos, mas permite que as subclasses alterem o tipo do objeto que será criado, e os objetos retornados por um Factory Method são geralmente chamados de &lt;strong&gt;products&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A ideia principal do Factory Method é delegar a implementação do código de criação às suas subclasses ou classes que a implementam.&lt;/p&gt;

&lt;p&gt;No entanto, há uma limitação: as subclasses podem retornar diferentes tipos de Product somente se esses Products tiverem uma classe ou interface base comum (APIIntegration). &lt;/p&gt;

&lt;p&gt;Além disso, o Factory Method na classe base deve ter seu tipo de retorno (APIIntegration) declarado como essa interface.&lt;/p&gt;

&lt;p&gt;Vamos entender alguns conceitos sobre o Factory Method usando o exemplo abaixo:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Product:&lt;/strong&gt; É uma interface ou classe abstrata que define o tipo de objetos que o Factory Method criará.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Em nosso exemplo:&lt;/em&gt;&lt;/strong&gt; Interface APIIntegration&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Creator:&lt;/strong&gt; Essa classe declara o próprio Factory Method. Esse método retorna um objeto do tipo do Product. Em algumas implementações, o Creator pode ser uma interface, uma classe abstrata ou até mesmo uma classe concreta.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Em nosso exemplo:&lt;/em&gt;&lt;/strong&gt; Interface APIFactory com métodos createApi e retorna um Product do tipo APIIntegration&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ConcreteCreator:&lt;/strong&gt; Uma classe que implementa ou estende o Creator e sobrescreve o método factory para retornar uma instância de um ConcreteProduct específico.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Em nosso exemplo:&lt;/em&gt;&lt;/strong&gt; TwitterAPIFactory, FacebookAPIFactory e InstagramAPIFactory&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ConcreteProduct:&lt;/strong&gt; Essa é uma implementação específica do Product. É isso que o ConcreteCreator instanciará e retornará.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Em nosso exemplo:&lt;/em&gt;&lt;/strong&gt; TwitterAPI, FacebookAPI, InstagramAPI&lt;/p&gt;

&lt;p&gt;Então, vamos dar uma olhada no código:&lt;/p&gt;

&lt;p&gt;Não leve muito a sério os detalhes de como me conectei ao APIS ou à sintaxe, todos os exemplos são fakes e não se baseiam na documentação oficial. Apenas absorva a ideia do que estou fazendo. &lt;/p&gt;

&lt;p&gt;As dependências das classes do ConcreteProduct são passadas por meio do construtor. (DI)&lt;/p&gt;

&lt;h4&gt;
  
  
  Product
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;APIIntegration&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Creator
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;APIFactory&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;createAPI&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nx"&gt;APIIntegration&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  ConcreteProduct
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TwitterAPI&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;APIIntegration&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Private and readonly is the same as initializing the property through constructor method&lt;/span&gt;
    &lt;span class="c1"&gt;// this.messageValidator = messageValidator&lt;/span&gt;
    &lt;span class="c1"&gt;// and so on&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;messageValidator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;MessageValidator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt;  &lt;span class="nx"&gt;twitterSdk&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;TwitterSDK&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
  &lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// A code to make it possible(Implementation)&lt;/span&gt;
    &lt;span class="c1"&gt;// Fake code below&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;messageValidator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
      &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;invalid validation&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;twitterSdk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isConnected&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;connection refused&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;twitterSdk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Posting on twitter: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;FacebookAPI&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;APIIntegration&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Private and readonly is the same as initializing the property through constructor method&lt;/span&gt;
    &lt;span class="c1"&gt;// this.messageValidator = messageValidator&lt;/span&gt;
    &lt;span class="c1"&gt;// and so on&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;messageValidator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;MessageValidator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;userIdHash&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;facebookSDK&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;FacebookSDK&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt; &lt;span class="c1"&gt;//New param (userIdHash)&lt;/span&gt;
  &lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="c1"&gt;// A code to make it possible(Implementation)&lt;/span&gt;
    &lt;span class="c1"&gt;// Fake code below&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;messageValidator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
      &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;invalid validation&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;facebookSDK&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isConnected&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;connection refused&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;facebookSDK&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userIdHash&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
      &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;user not found&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;facebookSDK&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Posting on facebook: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;InstagramAPI&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;APIIntegration&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Private and readonly is the same as initializing the property through constructor method&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;instagramSDK&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;InstagramSDK&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt; &lt;span class="c1"&gt;//New params (userIdHash)&lt;/span&gt;
  &lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// A code to make it possible(Implementation)&lt;/span&gt;
    &lt;span class="c1"&gt;// Fake code below&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;instagramSDK&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Posting on instagram: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  ConcreteCreator
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TwitterAPIFactory&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;APIFactory&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;createAPI&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nx"&gt;APIIntegration&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;messageValidator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;MessageValidator&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;twitterSDK&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;TwitterSDK&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;TwitterAPI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;messageValidator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;twitterSDK&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;FacebookAPIFactory&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;APIFactory&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;createAPI&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nx"&gt;APIIntegration&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;messageValidator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;MessageValidator&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;facebookSDK&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;FacebookSDK&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;userIdHash&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;123&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;FacebookAPI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;messageValidator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;userIdHash&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;facebookSDK&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;InstagramAPIFactory&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;APIFactory&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;createAPI&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nx"&gt;APIIntegration&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;instagramSDK&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;InstagramSDK&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;InstagramAPI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;instagramSDK&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Client code
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;allSocialNetworks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nx"&gt;APIFactory&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;InstagramAPIFactory&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;FacebookAPIFactory&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;TwitterAPIFactory&lt;/span&gt;&lt;span class="p"&gt;()];&lt;/span&gt;
&lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;api&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;allSocialNetworks&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;socialNetworkAPI&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createAPI&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nx"&gt;socialNetworkAPI&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello Followers&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Com esse padrão de design, se eu precisar modificar as dependências ou até mesmo atualizar os pacotes que o Facebook, o Twitter ou o Instagram usam, só preciso ajustar meu ConcreteCreator e/ou ConcreteProduct, desde que eu respeite meu contrato APIIntegration(Product) e APIFactory(Creator).&lt;/p&gt;

&lt;p&gt;Qualquer parte do meu código em que eu utilize minha API permanece inalterada e não é afetada por essas mudanças. Isso isola os possíveis bugs e reduz os locais onde o código precisa ser atualizado, diminuindo as chances de bugs.&lt;/p&gt;

&lt;p&gt;Se eu também decidir integrar outra rede social, como o Threads, é simples, basta que eu crie um ConcreteProduct e ConcreteFactory específicos. Depois, posso chamá-la no código, sem precisar fazer mudanças bruscas alterando o que já existe.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ThreadsAPI&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;APIIntegration&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;threadsSDK&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ThreadsSDK&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

  &lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// A code to make it possible(Implementation)&lt;/span&gt;
    &lt;span class="c1"&gt;// Fake code below&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;threadsSDK&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Posting on Threads: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ThreadsAPIFactory&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;APIFactory&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;createAPI&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nx"&gt;APIIntegration&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;threadsSDK&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ThreadsSDK&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ThreadsAPI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;threadsSDK&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E se eu também precisar criar testes para testar esse comportamento, eu não preciso usar uma implemetação real. Posso criar um ConcreteProduct e ConcreteFactory específicos que simulem esse comportamento.&lt;/p&gt;

&lt;h3&gt;
  
  
  Alguns pontos sobre o Factory Method
&lt;/h3&gt;

&lt;p&gt;Quando falamos de design de software, não se trata apenas de fazer o código funcionar. Trata-se também de garantir que o código possa evoluir e precisamos ter em mente que tudo muda.&lt;/p&gt;

&lt;p&gt;A tecnologia de hoje pode se tornar obsoleta amanhã. (Um salve pra galera do java escripto) &lt;/p&gt;

&lt;p&gt;Portanto, nosso código precisa ser flexível o suficiente para acomodar essas mudanças sem ter de criar tudo novamente.&lt;/p&gt;

&lt;p&gt;O Factory Method Pattern é bom nesses cenários:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Abstração:&lt;/strong&gt; Ele fornece um ponto em comum com o código de diversos lugares  em um só e o processo de instanciação do objeto. Essa abstração garante que, mesmo que a lógica de criação se torne complexa no futuro, ela não afetará outras partes do aplicativo.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Extensibilidade:&lt;/strong&gt; Deseja adicionar outra rede socia ao seu aplicativo? Com o Factory Method, você pode introduzir sem esforço um novo ConcreteProduct (como uma nova integração de API) sem alterar muito do código existente.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Manutenibilidade:&lt;/strong&gt; Como mencionado anteriormente, as alterações são localizadas. Se a API de uma determinada plataforma for alterada, só precisaremos modificar sua respectiva Factory e Product, deixando o restante do aplicativo intocado.&lt;/p&gt;

&lt;p&gt;Esse padrão, embora não seja uma solução mágica para todos os problemas, oferece uma boa abordagem para a criação de objetos. Ele encapsula as complexidades e fornece uma estrutura clara, tornando o código mais compreensível e menos propenso a erros.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prós e contras
&lt;/h3&gt;

&lt;p&gt;Como qualquer ferramenta ou abordagem, o Factory Method tem suas vantagens e desvantagens:&lt;/p&gt;

&lt;h4&gt;
  
  
  Prós
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Você evita o acoplamento forte entre a criação(creators) e a implementação(Concrete Products).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Single Responsability: É possível deixar a reponsabilidade de criação do Product em apenas um lugar, o que facilita a manutenção do código.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Open/Closed Principle:  Você pode introduzir novos tipos de Products no programa sem quebrar o código do cliente existente.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Contras
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;O código pode se tornar mais complicado, pois você precisa introduzir muitas subclasses novas para implementar o padrão. O melhor cenário é quando você está introduzindo o padrão em uma hierarquia existente de classes de criadores.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Se a sua classe não precisar de muitas dependências, esse padrão pode ser over-engineering.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Se as dependência do aplicativo não mudam com frequência, o Factory Method poderá apenas aumentar a base de código sem agregar valor real. A otimização prematura é a raiz de todo o mal.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;No software, as coisas mudam rapidamente. Portanto, precisamos de maneiras de mudar nossos aplicativos sem começar do zero. &lt;/p&gt;

&lt;p&gt;O Factory Method nos ajuda a fazer isso. É como ter pedaços de códigos que podem ser facilmente trocados e substituídos conforme necessário.&lt;/p&gt;

&lt;p&gt;Isso simplifica a adição de novas coisas ou a alteração de partes do nosso aplicativo.&lt;/p&gt;

&lt;p&gt;No entanto, é importante entender os prós e os contras. &lt;/p&gt;

&lt;p&gt;Sempre priorize a simplicidade e a clareza e use padrões onde eles realmente agregam valor.&lt;/p&gt;

&lt;p&gt;Muito obrigado por ler até aqui :)&lt;/p&gt;

&lt;p&gt;Sinta-se convidado a participar com dúvidas, críticas e sugestões. &lt;/p&gt;

&lt;p&gt;Em nosso próximo artigo, discutiremos mais um pouco sobre outro tópico relacionado a engenharia de software. &lt;/p&gt;

&lt;p&gt;Até mais :)&lt;/p&gt;

&lt;h2&gt;
  
  
  Referências
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612" rel="noopener noreferrer"&gt;Design Patterns: Elements of Reusable Object-Oriented Software&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://refactoring.guru/" rel="noopener noreferrer"&gt;Refactoring.guru&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rmanguinho/clean-ts-api/" rel="noopener noreferrer"&gt;Rodrigo Manguinho - Clean TS API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=EdFq_JIThqM" rel="noopener noreferrer"&gt;The Factory Method Pattern Explained and Implemented in Java&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=xN7EFHU_rXA" rel="noopener noreferrer"&gt;Factory, Abstract Factory, Factory Method - Design Pattern (C#)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>architecture</category>
      <category>patterns</category>
      <category>softwareengineering</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Factory Method: Simplifying Object Instantiation</title>
      <dc:creator>Iaan Mesquita</dc:creator>
      <pubDate>Sat, 19 Aug 2023 16:54:28 +0000</pubDate>
      <link>https://dev.to/ianito/design-patterns-factory-method-22if</link>
      <guid>https://dev.to/ianito/design-patterns-factory-method-22if</guid>
      <description>&lt;p&gt;&lt;em&gt;Portuguese version: &lt;a href="https://dev.to/ianito/design-patterns-factory-method-pt-br-21a3"&gt;https://dev.to/ianito/design-patterns-factory-method-pt-br-21a3&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Hi there,&lt;/p&gt;

&lt;p&gt;If you don't know me, my name is Iaan Mesquita. &lt;/p&gt;

&lt;p&gt;I'm a software engineer, and today I'll start a series of articles that talk a little bit about the Software Engineering/Software Architecture field.&lt;/p&gt;

&lt;p&gt;But why are design patterns so important? Well, they provide solutions for common problems that we, as software engineers, need to deal. Using design patterns can make software easier to understand (though not always), extend, and maintain.&lt;/p&gt;

&lt;p&gt;I recommend starting with this article, as it introduces concepts that will be foundational for the upcoming ones. To avoid redundancy, I advise familiarizing yourself with these basics.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; I won't always follow best practices when explaining a specific design pattern (since my goal is to focus on the concept at hand), please consider if your suggestions would simplify things for those unfamiliar with patterns. All feedback is welcome.&lt;/p&gt;

&lt;p&gt;And also, it's good to have an understanding of Object-Oriented Programming (OOP) and SOLID principles.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Readability vs Writability&lt;/li&gt;
&lt;li&gt;Dependecy Injection&lt;/li&gt;
&lt;li&gt;Creational, Structural, and Behavioral Patterns&lt;/li&gt;
&lt;li&gt;Problem&lt;/li&gt;
&lt;li&gt;Factory Method&lt;/li&gt;
&lt;li&gt;Pros &amp;amp; Cons&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;li&gt;References&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Before start discussing Design Patterns, let's take a look at some concepts:&lt;/p&gt;

&lt;h3&gt;
  
  
  Readability vs Writability
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Readability&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It means the ease with which a code can be read and understood by other developers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Writability&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It means the ease with which a code can be written. This is nothing about the velocity of typing, we can understand this concept by the easiness of expressing our ideas as a software engineer. If you ever worked with C language, you can understand this concept by remembering string manipulation there and compare with another language.&lt;/p&gt;

&lt;p&gt;These two concepts are so important in the Software Engineering field (not only). In general, you won't create new things but enhance things that already exist and for that, readability and writability can affect our software in the long term.&lt;/p&gt;

&lt;p&gt;If you could choose between software that you can read/write with facility or software with every developer decided to follow your own patterns, what do you will chose?&lt;/p&gt;

&lt;p&gt;Unless you are trying to challenge yourself, I know the answer. xD&lt;/p&gt;

&lt;p&gt;However, this doesn't imply that every common pattern known offers optimal writability or readability. At times, we might have to prioritize one over the other for reasons like enhanced extensibility or specific project/team constraints.&lt;/p&gt;

&lt;p&gt;Otherwise understanding these concepts is crucial when deciding when and how to apply them.&lt;/p&gt;

&lt;h3&gt;
  
  
  Dependency Injection
&lt;/h3&gt;

&lt;p&gt;Dependency Injection (DI) is a software design pattern that deals with how components or objects acquire their dependencies. Instead of an object creating its own dependencies (like instantiating your dependencies) or using global instances, dependencies are "injected" into the object, typically through its constructor, a method, or properties. This allows for greater flexibility, testability, and maintainability in software design.&lt;/p&gt;

&lt;p&gt;We can discuss this pattern in the future.&lt;/p&gt;

&lt;h3&gt;
  
  
  Creational, Structural, and Behavioral Patterns
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Creational Patterns&lt;/strong&gt; focus on optimal ways to instantiate objects. These patterns offer various techniques, besides using constructors, to ensure flexibility and maintability.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Structural Patterns&lt;/strong&gt; guide the composition of objects or classes, aiming for scalability and maintainability.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Behavioral Patterns&lt;/strong&gt; address how objects interact and communicate, emphasizing objects' responsibilities and their collaboration.&lt;/p&gt;

&lt;p&gt;Today we will discuss &lt;strong&gt;Factory Method - (Creational Pattern)&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Problem
&lt;/h2&gt;

&lt;p&gt;Imagine that you’re creating an application to help your customer to manage their Instagram accounts. As well as you are a startup, you are validating your ideas and the first and only feature that your app has is the ability to post on Instagram.&lt;/p&gt;

&lt;p&gt;Now your customers loved your application and they are missing other social networks like X, Facebook, BlueSky, and whatever and you decided to implement them. I don't know yet which social api I'm going to use, but I know it's an API.&lt;/p&gt;

&lt;p&gt;However, you know that every social network has its own method way to post into them, with different dependencies and validations for example, but you know the behavior is the same: Post inside a social network.&lt;/p&gt;

&lt;p&gt;Are you agree with me that every place inside your application that you need to post inside a social network, doesn't need to know about implementation? Just work as expected and post inside a social network? &lt;/p&gt;

&lt;p&gt;For this instance, let's assume that you are designing your application using Dependency Injection passing dependencies through the constructor, you would need to inject them into the constructor, like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;TwitterAPI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;messageValidator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;twitterSDK&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;//or and&lt;/span&gt;
&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;FacebookAPI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;messageValidator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;userIdHash&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;facebookSDK&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;//or and&lt;/span&gt;
&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;InstagramAPI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;instagramSDK&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Don't think so much about details, just catch the main idea, I'm passing some dependencies that my class needs.&lt;/p&gt;

&lt;p&gt;Let's imagine too that I'll need to use FacebookAPI/TwitterAPI in a lot of places, and every time I wanted to use methods from class we first need to instantiate it and pass its dependencies through the constructor.&lt;/p&gt;

&lt;p&gt;But not only this, what happens if Facebook decided that they won't let you post inside a platform before you confirm that you're not a robot? As a result, you will need to validate this before sending, and now you have a lot of places to make this change because one thing changed in the way that Facebook APIs communicate.&lt;/p&gt;

&lt;p&gt;So, one solution to this problem is using Factories.&lt;/p&gt;

&lt;h3&gt;
  
  
  Factory Method
&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;Factory Method&lt;/strong&gt; is a creational design pattern that provides an interface for creating objects but allows subclasses to change the type of an object that will be created and objects returned by a factory method are often referred to as &lt;strong&gt;products&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The main idea of the Factory Method is to delegate the implementation of the creation code to its subclasses or classes that implement it.&lt;/p&gt;

&lt;p&gt;But there is a limitation though: subclasses may return different types of products only if these products have a common base class or interface(APIIntegration). Also, the factory method in the base class should have its return type(APIIntegration) declared as this interface.&lt;/p&gt;

&lt;p&gt;Let's understand some concepts about Factory Method using our example below:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Product:&lt;/strong&gt; This is an interface or abstract class defining the type of objects the factory method will create.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;In our example:&lt;/strong&gt; Interface APIIntegration&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Creator:&lt;/strong&gt; This class declares the factory method itself. This method returns an object of type Product. In some implementations, the Creator might be an interface, an abstract class, or even a concrete class.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;In our example:&lt;/strong&gt;&lt;/em&gt; Interface APIFactory with createApi methods and return a product of type APIImplementation&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ConcreteCreator:&lt;/strong&gt; A class that implements or extends the Creator and overrides the factory method to return an instance of a specific ConcreteProduct.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;In our example&lt;/em&gt;&lt;/strong&gt;: TwitterAPIFactory, FacebookAPIFactory, and InstagramAPIFactory&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ConcreteProduct:&lt;/strong&gt; This is a specific implementation of the Product. This is what the ConcreteCreator will instantiate and return.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;In our example&lt;/em&gt;&lt;/strong&gt;: TwitterAPI, FacebookAPI, InstagramAPI&lt;/p&gt;

&lt;p&gt;So, let's see the code:&lt;/p&gt;

&lt;p&gt;Don't take the details of how I connected to APIS too seriously or syntax, all the examples are fake and not based on the main documentation. Just absorb the idea. &lt;/p&gt;

&lt;p&gt;The dependencies of the ConcreteProduct's classes are passed through the constructor. (DI)&lt;/p&gt;

&lt;h4&gt;
  
  
  Product
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;APIIntegration&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Creator
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;APIFactory&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;createAPI&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nx"&gt;APIIntegration&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  ConcreteProduct
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TwitterAPI&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;APIIntegration&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Private and readonly is the same as initializing the property through constructor method&lt;/span&gt;
    &lt;span class="c1"&gt;// this.messageValidator = messageValidator&lt;/span&gt;
    &lt;span class="c1"&gt;// and so on&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;messageValidator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;MessageValidator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt;  &lt;span class="nx"&gt;twitterSdk&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;TwitterSDK&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
  &lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// A code to make it possible(Implementation)&lt;/span&gt;
    &lt;span class="c1"&gt;// Fake code below&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;messageValidator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
      &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;invalid validation&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;twitterSdk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isConnected&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;connection refused&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;twitterSdk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Posting on twitter: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;FacebookAPI&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;APIIntegration&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Private and readonly is the same as initializing the property through constructor method&lt;/span&gt;
    &lt;span class="c1"&gt;// this.messageValidator = messageValidator&lt;/span&gt;
    &lt;span class="c1"&gt;// and so on&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;messageValidator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;MessageValidator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;userIdHash&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;facebookSDK&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;FacebookSDK&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt; &lt;span class="c1"&gt;//New param (userIdHash)&lt;/span&gt;
  &lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="c1"&gt;// A code to make it possible(Implementation)&lt;/span&gt;
    &lt;span class="c1"&gt;// Fake code below&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;messageValidator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
      &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;invalid validation&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;facebookSDK&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isConnected&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;connection refused&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;facebookSDK&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userIdHash&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
      &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;user not found&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;facebookSDK&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Posting on facebook: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;InstagramAPI&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;APIIntegration&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Private and readonly is the same as initializing the property through constructor method&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;instagramSDK&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;InstagramSDK&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt; &lt;span class="c1"&gt;//New params (userIdHash)&lt;/span&gt;
  &lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// A code to make it possible(Implementation)&lt;/span&gt;
    &lt;span class="c1"&gt;// Fake code below&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;instagramSDK&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Posting on instagram: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  ConcreteCreator
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TwitterAPIFactory&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;APIFactory&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;createAPI&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nx"&gt;APIIntegration&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;messageValidator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;MessageValidator&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;twitterSDK&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;TwitterSDK&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;TwitterAPI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;messageValidator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;twitterSDK&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;FacebookAPIFactory&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;APIFactory&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;createAPI&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nx"&gt;APIIntegration&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;messageValidator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;MessageValidator&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;facebookSDK&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;FacebookSDK&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;userIdHash&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;123&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;FacebookAPI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;messageValidator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;userIdHash&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;facebookSDK&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;InstagramAPIFactory&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;APIFactory&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;createAPI&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nx"&gt;APIIntegration&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;instagramSDK&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;InstagramSDK&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;InstagramAPI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;instagramSDK&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Client code
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;allSocialNetworks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nx"&gt;APIFactory&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;InstagramAPIFactory&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;FacebookAPIFactory&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;TwitterAPIFactory&lt;/span&gt;&lt;span class="p"&gt;()];&lt;/span&gt;
&lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;api&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;allSocialNetworks&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;socialNetworkAPI&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createAPI&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nx"&gt;socialNetworkAPI&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello Followers&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this design pattern, if I need to modify the dependencies or even update the packages that Facebook, Twitter, or Instagram use, I just need to adjust my ConcreteCreator and/or ConcreteProduct as long as I respect my contract APIIntegration(Product) and APIFactory(Creator).&lt;/p&gt;

&lt;p&gt;Anywhere in my code where I utilize my API remains unchanged and unaffected by these shifts. This isolates potential sources of errors and minimizes the areas of code we must update, decreasing the chances of introducing bugs.&lt;/p&gt;

&lt;p&gt;If I ever decide to integrate another social network, like Threads, it's as simple as crafting its specific ConcreteProduct and ConcreteFactory. Then, I can call it within my client code, without disrupting the existing setup.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ThreadsAPI&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;APIIntegration&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;threadsSDK&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ThreadsSDK&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

  &lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// A code to make it possible(Implementation)&lt;/span&gt;
    &lt;span class="c1"&gt;// Fake code below&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;threadsSDK&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Posting on Threads: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ThreadsAPIFactory&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;APIFactory&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;createAPI&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nx"&gt;APIIntegration&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;threadsSDK&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ThreadsSDK&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ThreadsAPI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;threadsSDK&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And if I also need to create tests to test this behavior, I don't need to use a real implementation. I can create a specific ConcreteProduct and ConcreteFactory that simulate this behavior.&lt;/p&gt;

&lt;h3&gt;
  
  
  Some points about Factory Method
&lt;/h3&gt;

&lt;p&gt;When we talk about software design, it's not just about making the code work. It's also about ensuring that the code can evolve and we need to have in mind that everything changes. Today's technology might be obsolete tomorrow. &lt;/p&gt;

&lt;p&gt;Therefore, our code needs to be flexible enough to accommodate these changes without having to create everything again.&lt;/p&gt;

&lt;p&gt;The Factory Method Pattern is good in these scenarios:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Abstraction:&lt;/strong&gt; It provides a buffer between the client code and the object instantiation process. This abstraction ensures that even if the creation logic becomes complex in the future, it won't ripple and affect other parts of the application.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Extensibility:&lt;/strong&gt; Want to add another social media platform to your application? With the Factory Method, you can effortlessly introduce a new ConcreteProduct (like a new API integration) without changing much of your existing code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Maintainability:&lt;/strong&gt; As mentioned earlier, changes are localized. If the API of a particular platform changes, we only have to modify its respective factory and product, leaving the rest of the application untouched.&lt;/p&gt;

&lt;p&gt;This pattern, while not a silver bullet for all problems, offers a good approach to object creation. It encapsulates the complexities and provides a clear structure, making the code more understandable and less prone to errors.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pros and Cons
&lt;/h3&gt;

&lt;p&gt;Like any tool or approach, the Factory Method Pattern has its advantages and disadvantages:&lt;/p&gt;

&lt;h4&gt;
  
  
  Pros
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;You avoid tight coupling between the creator and the concrete products.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Single Responsibility Principle. You can move the product creation code into one place in the program, making the code easier to support.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Open/Closed Principle. You can introduce new types of products into the program without breaking existing client code.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Cons
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The code may become more complicated since you need to introduce a lot of new subclasses to implement the pattern. The best-case scenario is when you’re introducing the pattern into an existing hierarchy of creator classes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If your class doesn't need a lot of dependencies this pattern can add over-engineering.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If the application's dependency requirements are not expected to change frequently, then the Factory Method Pattern may just increase the codebase without adding real value. (Over-engineering)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In software, things change fast. So, we need ways to update our apps without starting from scratch. &lt;/p&gt;

&lt;p&gt;The Factory Method Pattern helps us do this. It's like having building blocks we can easily swap out and replace as needed.&lt;/p&gt;

&lt;p&gt;It makes adding new things or changing parts of our app simpler.&lt;/p&gt;

&lt;p&gt;However, it's important to understand the pros and cons. &lt;/p&gt;

&lt;p&gt;Always prioritize simplicity and clarity, and employ patterns where they genuinely add value.&lt;/p&gt;

&lt;p&gt;Thank you for reading, and in our next article we will discuss a little bit about another design pattern.&lt;/p&gt;

&lt;p&gt;Feel free to comment, make suggestions and criticize.&lt;/p&gt;

&lt;p&gt;See you :)&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612" rel="noopener noreferrer"&gt;Design Patterns: Elements of Reusable Object-Oriented Software&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://refactoring.guru/" rel="noopener noreferrer"&gt;Refactoring.guru&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rmanguinho/clean-ts-api/" rel="noopener noreferrer"&gt;Rodrigo Manguinho - Clean TS API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=EdFq_JIThqM" rel="noopener noreferrer"&gt;The Factory Method Pattern Explained and Implemented in Java&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=xN7EFHU_rXA" rel="noopener noreferrer"&gt;Factory, Abstract Factory, Factory Method - Design Pattern (C#)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>architecture</category>
      <category>softwareengineering</category>
      <category>patterns</category>
      <category>typescript</category>
    </item>
    <item>
      <title>How did I discover a security vulnerability in a system of my university</title>
      <dc:creator>Iaan Mesquita</dc:creator>
      <pubDate>Tue, 17 May 2022 21:54:51 +0000</pubDate>
      <link>https://dev.to/ianito/how-did-i-discover-a-security-vulnerability-in-a-system-of-my-university-916</link>
      <guid>https://dev.to/ianito/how-did-i-discover-a-security-vulnerability-in-a-system-of-my-university-916</guid>
      <description>&lt;p&gt;&lt;strong&gt;Portuguese version:&lt;/strong&gt; &lt;a href="https://dev.to/ianito/como-eu-descobri-uma-falha-de-seguranca-em-um-sistema-na-minha-universidade-21f"&gt;Como eu descobri uma falha de segurança em um sistema na minha universidade&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hi everybody, today i will tell you how did I discover a security vulnerability in a system of my university, what i did i do in next, how we can avoid this and my conclusions.&lt;/p&gt;

&lt;p&gt;I want to be clear that my objectives weren't stain company image, university or developers, but only can contribute with system security and also contribute for information security scenario in Brazil.&lt;/p&gt;

&lt;h2&gt;
  
  
  How did I discover vulnerability ?
&lt;/h2&gt;

&lt;p&gt;Well, at the time we were in the pandemic when classes were mostly online and that's why the use of online system was most frequent than in person. Then, in this class was introduced for us a system (already utilized for a some time by university) and that we should utilised to post exercicies and follow our grade. Being a new system, I was curious to see what was traffing between the application and my network and I have started to look for something interestant.&lt;/p&gt;

&lt;p&gt;So, I founded two requests interestant:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One that returned my personal data&lt;/li&gt;
&lt;li&gt;Another that returned some numbers of my credit card, card flag, expiration date and etc&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyh31zketqhcszxzy7kfd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyh31zketqhcszxzy7kfd.png" alt="Rota dados pessoais" width="800" height="210"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F88uop6werxyfarh3sfua.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F88uop6werxyfarh3sfua.png" alt="Rota cartão de crédito" width="800" height="227"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;But Iaan, we only found two requests that show our self data, and?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You're right, that's why i decided to test if that routes was allow made if I haven't a token or a valid token.&lt;/p&gt;

&lt;p&gt;Did not work. :(&lt;/p&gt;

&lt;p&gt;It was then i thought, and if my token is valid but my request has a ID different of my user id?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;And... THATS WORKED!!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I made a request using the curl command and changing my id what which was a parameter in the route.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8psg4rgb8s90ind7y9tb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8psg4rgb8s90ind7y9tb.png" alt="Imagem do terminal com curl" width="800" height="608"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Same happened with route that return some info about my credit card.&lt;/p&gt;

&lt;p&gt;This happens because the application back-end only verified if my token is valid to make the request but not verify if the id was requesting really belonged to my user.&lt;/p&gt;

&lt;p&gt;Suppose my id is 21 and I have be authenticate in application, so the route to show my personal data were something like:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;http://myapi.com.br/personal-data?id=21&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then, I was already authenticate and my token was valid, if i changed my &lt;code&gt;id&lt;/code&gt; in the request to 22, I could get all personal data of id 22.&lt;/p&gt;

&lt;p&gt;Ok, vulnerability found and now?&lt;/p&gt;

&lt;h2&gt;
  
  
  What did I do after finding the vulnerability?
&lt;/h2&gt;

&lt;p&gt;I started documenting all I have done to discover this vulnerability to report to those responsibles.&lt;br&gt;
I created abstract of vulnerability .&lt;br&gt;
In this document I described a abstract of vulnerability, how to execute, possible solution, a tiny script to prove the vulnerability (Proof-of-concept) and the source code.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fye8psn0360d19lctrol5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fye8psn0360d19lctrol5.png" alt="Documento" width="800" height="444"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;PoC:&lt;a href="https://www.youtube.com/watch?v=tU1qOoPhwtg" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=tU1qOoPhwtg&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I didn't know responsible's email of application so i asked for help to my professor and he helped me to send document to them.&lt;br&gt;
In the next day, I receveid a response email:&lt;/p&gt;

&lt;p&gt;(Google translate bellow xD)&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Dear,&lt;br&gt;
We hope to find you all well.&lt;br&gt;
We have received your notification regarding a security flaw in one of our applications and we would like to inform you that we have immediately submitted this notification to our engineering team for analysis and correction.&lt;br&gt;
After analysis, it was found that in fact there was a vulnerability that would allow the consultation of other people's registration data, only when in possession of a valid token. The token in this context is similar to a key, generated from the successful authentication of a student after entering their username and personal password. People without this token, that is, without a valid login, would not be able to access said personal data.&lt;/p&gt;

&lt;p&gt;All necessary corrections and validations have been implemented so that this scenario no longer occurs.&lt;br&gt;
Regarding credit card data, it is important to note that we do not store any critical or sensitive student credit card data. For the avoidance of doubt, below is a brief explanation of how credit card use works in our solutions:&lt;/p&gt;

&lt;p&gt;When a student wants to make any payment via credit card, when entering their card information, this data is sent directly to the Banking Institution through a process called "Transparent Checkout" where the data is being sent directly to the bank within of our platform. In other words, it is as if the student were on the bank's website while still on our platform. This communication with the bank is carried out using a secure and encrypted connection, in addition to all the latest security protocols available for the internet. At no time do we collect any information transacted in this transaction. After completing the payment, the Banking Institution returns us whether it was successful or not, and, when successful, sends us a token that identifies that student's card with the bank. Accompanied by this token comes the masked number of the card and its brand, so that if the student needs to make another payment through the platform, he can do it more easily and quickly. This token by itself has no validity because, in the event of a new payment, the insertion of the verification code printed on the credit card and a public and a private key created between the bank and our system will be required for the transaction be validated, reinforcing that the entire transaction will be carried out in a secure environment provided by the Banking Institution.&lt;/p&gt;

&lt;p&gt;We highly value the quality and integrity of the services we provide. Our innovation cycle includes reviewing services already built to measure performance and safety criteria. We are deeply sorry that this failure has gone unnoticed. Therefore, we carefully check all the points that were raised and these have already been corrected. We also emphasize our commitment to follow and keep an eye on all&lt;br&gt;
current legislation regarding information security, in particular the Law&lt;br&gt;
no. 13.709/18 (General Law for the Protection of Personal Data - "LGPD") and the Law&lt;br&gt;
12.965/2014 (Marco Civil da Internet).&lt;/p&gt;

&lt;p&gt;On all our platforms, our privacy policy is publicly available, which explains how personal data is treated in our solutions. Questions related to XX's Privacy Policy or any other questions related to the topic of security and protection of Personal Data, can be sent via the support contact email&lt;br&gt;
Certain of our understanding, we make ourselves available for any clarifications. Yours sincerely,&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Then, I checked if the vulnerability was fixed.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdgrzri79fso0xlalq5ub.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdgrzri79fso0xlalq5ub.png" alt="Falha resolvida" width="800" height="446"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What we can learning about this?
&lt;/h2&gt;

&lt;p&gt;Never trust the user, remember that any validation you do on the client side is susceptible to changes by the user. Validate everything on the backend that needs validation and run tests to make sure your result is as expected. Could we change the &lt;code&gt;id&lt;/code&gt; from &lt;code&gt;int&lt;/code&gt; to a &lt;code&gt;UUID&lt;/code&gt;? It depends, if it's just for that, it's not a good idea because a validation would already make it impossible and only with this change you would be solving only part of the problem. You have to understand the trade-offs in adopting this technique. (I recommend the article &lt;a href="https://gist.github.com/rponte/bf362945a1af948aa04b587f8ff332f8" rel="noopener noreferrer"&gt;Are you going to use UUID as PK instead of Int/BigInt in your database? Think again...&lt;/a&gt;, it has some pretty good insights)&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Thanks for reading, this is one of my posts that is part of my new way of learning using learn in public.&lt;/p&gt;

&lt;p&gt;If you're interested, you can check out what it is: &lt;a href="https://www.swyx.io/learn-in-public/" rel="noopener noreferrer"&gt;https://www.swyx.io/learn-in-public/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I intend to continue doing this and I already have the next post prepared.&lt;/p&gt;

&lt;p&gt;Spoiler: This one also involved my university&lt;/p&gt;

&lt;p&gt;:)&lt;/p&gt;

&lt;p&gt;PS: I'm learning English too, feel free to comment on my grammatical errors.&lt;/p&gt;

</description>
      <category>security</category>
      <category>api</category>
      <category>pentest</category>
    </item>
    <item>
      <title>Como eu descobri uma falha de segurança em um sistema na minha universidade</title>
      <dc:creator>Iaan Mesquita</dc:creator>
      <pubDate>Tue, 17 May 2022 21:54:36 +0000</pubDate>
      <link>https://dev.to/ianito/como-eu-descobri-uma-falha-de-seguranca-em-um-sistema-na-minha-universidade-21f</link>
      <guid>https://dev.to/ianito/como-eu-descobri-uma-falha-de-seguranca-em-um-sistema-na-minha-universidade-21f</guid>
      <description>&lt;p&gt;&lt;strong&gt;English version:&lt;/strong&gt; &lt;a href="https://dev.to/ianito/how-did-i-discover-a-security-vulnerability-in-a-system-of-my-university-916"&gt;How did I discover a security vulnerability in a system of my university&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Eai galera, então hoje eu vou contar como eu descobri uma falha de segurança em um dos sistemas que minha universidade utiliza, o que eu fiz logo em seguida, como podemos evitar e minhas conclusões.&lt;/p&gt;

&lt;p&gt;Quero deixar claro que meu objetivo não é manchar a imagem da empresa, universidade ou dos desenvolvedores, mas sim poder contribuir com a segurança do sistema bem como também contribuir para o cenário de Segurança da Informação no país. &lt;/p&gt;

&lt;h2&gt;
  
  
  Como eu descobri a falha?
&lt;/h2&gt;

&lt;p&gt;Bom, na época estavamos na pandemia em que as aulas em sua maioria eram todas onlines e por isso o uso de sistemas onlines eram mais frequentes do que no presencial. Então, nessa aula foi nos apresentados um sistema (já utilizado a algum tempo pela universidade) e que deveriamos utilizar para postar atividades e acompanhar notas. Sendo um sistema novo, tive a curiosidade de ver o que estava trafegando nas requisições feitas pelo sistema e comecei a procurar requisições que fossem interessantes. &lt;/p&gt;

&lt;p&gt;Então, encontrei duas requisições interessantes.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Uma que me retornava meus dados cadastrais&lt;/li&gt;
&lt;li&gt;Outra que me retornava alguns números do meu cartão de crédito, data de validade, bandeira e etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyh31zketqhcszxzy7kfd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyh31zketqhcszxzy7kfd.png" alt="Rota dados pessoais" width="800" height="210"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F88uop6werxyfarh3sfua.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F88uop6werxyfarh3sfua.png" alt="Rota cartão de crédito" width="800" height="227"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Mas Iaan, até agora só encontramos duas rotas que mostram nossos próprios dados, e dai?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Você tem razão, por isso eu decidi testar se essas rotas permitiriam ser feitas se eu não tivesse um token ou se meu token fosse inválido, e...&lt;/p&gt;

&lt;p&gt;Não deu em nada. :(&lt;/p&gt;

&lt;p&gt;Foi então que eu pensei, e se meu token for válido mas minha requisição tiver um id diferente do meu, ou seja, de outro usuário?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;E... funcionou! :D&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Fiz uma requisição utilizando o comando &lt;code&gt;curl&lt;/code&gt; e mudando meu &lt;code&gt;id&lt;/code&gt; que era um paramêtro na rota.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8psg4rgb8s90ind7y9tb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8psg4rgb8s90ind7y9tb.png" alt="Imagem do terminal com curl" width="800" height="608"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O mesmo acontecia na rota que mostrava informações dos cartões de créditos.&lt;/p&gt;

&lt;p&gt;Isso acontece pois o back-end da aplicação apenas verificava se o token era válido para fazer a requisição mas não verificava se o id que eu estava solicitando realmente pertenciam a meu usuário. &lt;/p&gt;

&lt;p&gt;Suponhamos que meu &lt;code&gt;id&lt;/code&gt; seja o 21 e que eu esteja autenticado na aplicação, então a rota para mostrar meus dados pessoais poderia ser algo assim:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;http://apidosistema.com.br/dados-pessoais?id=21&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Então, como eu estava autenticado e meu token era válido, se eu mudasse o &lt;code&gt;id&lt;/code&gt; da requisição para 22, eu conseguia obter dados do usuário com esse &lt;code&gt;id&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;http://apidosistema.com.br/dados-pessoais?id=22&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Ok, falha encontrada e agora?&lt;/p&gt;

&lt;h2&gt;
  
  
  O que eu fiz logo após encontrar a falha?
&lt;/h2&gt;

&lt;p&gt;Comecei a documentar o que eu tinha descoberto para reportar aos responsáveis.&lt;br&gt;
Criei um documento em que eu dava um resumo da falha que tinha acabado de descobrir.&lt;br&gt;
Nesse documento descrevi um resumo da falha, gravidade, como executar, possível solução, um script simples que mostrava a falha (Proof-of-concept) e o código fonte do mesmo.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fye8psn0360d19lctrol5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fye8psn0360d19lctrol5.png" alt="Documento" width="800" height="444"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;PoC:&lt;a href="https://www.youtube.com/watch?v=tU1qOoPhwtg" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=tU1qOoPhwtg&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Como não sabia o email dos responsáveis pela plataforma, entrei em contato com meu professor que me ajudou a enviar o documento para eles.&lt;br&gt;
No dia seguinte, recebi um email com uma resposta da plataforma.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Prezados,&lt;br&gt;
Esperamos encontrar todos bem.&lt;br&gt;
Recebemos a sua notificação a respeito de uma falha de segurança em uma de nossas aplicações e gostaríamos de informar que de imediato, submetemos essa notificação ao nosso time de engenharia para análise e devidas correções.&lt;br&gt;
Após análise ficou constatado que de fato existia uma vulnerabilidade que permitiria a consulta dos dados cadastrais de outras pessoas, somente quando em posse de um token válido. O token nesse contexto é semelhante a uma chave, gerada a partir da autenticação bem-sucedida de um aluno no após informar seu usuário e sua senha pessoal. Pessoas sem esse token, ou seja, sem um login válido, não conseguiriam acesso aos referidos dados pessoais.&lt;/p&gt;

&lt;p&gt;Todas as correções e validações necessárias foram implementadas para que esse cenário não ocorra mais.&lt;br&gt;
Com relação aos dados de cartão de crédito é importante destacar que não armazenamos nenhum dado crucial ou sigiloso do cartão de crédito do aluno. A fim de não restarem dúvidas, abaixo segue uma breve explicação de como funciona o uso do cartão de crédito nas nossas soluções:&lt;/p&gt;

&lt;p&gt;Quando um aluno deseja realizar qualquer pagamento via cartão de crédito, ao inserir as informações do seu cartão, esses dados são enviados diretamente à Instituição Bancária através de um processo chamado de “Checkout transparente” onde os dados estão sendo enviados diretamente ao banco de dentro da nossa plataforma. Em outras palavras, é como se o aluno estivesse no site do banco estando ainda na nossa plataforma. Essa comunicação com o banco é realizada utilizando uma conexão segura e criptografa, além de todos os mais recentes protocolos de segurança disponíveis para internet. Em nenhum momento nós coletamos quaisquer informações transacionadas nessa operação. Após a finalização do pagamento a Instituição Bancária nos retorna se ela foi bemsucedida ou não, e, quando bem-sucedida, nos envia um token que identifica aquele cartão do aluno junto ao banco. Acompanhado desse token vem o número mascarado do cartão e sua bandeira, para que caso o aluno precise realizar outro pagamento pela plataforma, ele consiga fazê-lo de forma mais fácil e rápida. Esse token por si só não tem nenhuma validade pois, na eventualidade de um novo pagamento, será exigido a inserção do código de verificação impresso no cartão de crédito e de uma chave pública e outra privada criadas entre o banco e nosso sistema para que a transação seja validada, reforçando que toda a transação será realizada em um ambiente seguro fornecido pela Instituição Bancária.&lt;/p&gt;

&lt;p&gt;Prezamos muito pela qualidade e integridade dos serviços que prestamos. Nosso ciclo de inovação contempla revistar serviços já construídos para mensurar critérios de desempenho e segurança. Sentimos profundamente que essa falha tenha passado despercebida. Por isso, verificamos com muita cautela todos os pontos que foram levantados e estes já se encontram corrigidos. Ressaltamos também nosso compromisso em seguir e mantermos atentos a toda&lt;br&gt;
a legislação vigente referente a segurança da informação, em destaque para a Lei&lt;br&gt;
nº. 13.709/18 (Lei Geral de Proteção de Dados pessoais - "LGPD") e a Lei&lt;br&gt;
12.965/2014 (Marco Civil da Internet). &lt;/p&gt;

&lt;p&gt;Em todas as nossas plataformas, está disponível, de forma pública, a nossa política de privacidade que explica como os dados pessoais são tratados nas nossas soluções. Questionamentos relacionados à Política de Privacidade da XX ou quaisquer outras dúvidas relacionadas ao tema de segurança e proteção dos Dados Pessoais, podem ser enviadas através do e-mail de contato com o suporte&lt;br&gt;
Certo de nossa compreensão, nos colocamos à disposição para quaisquer esclarecimentos. Atenciosamente, &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Em seguida, eu conferi se a falha tinha sido corrigida:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdgrzri79fso0xlalq5ub.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdgrzri79fso0xlalq5ub.png" alt="Falha resolvida" width="800" height="446"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  O que podemos aprender disso?
&lt;/h2&gt;

&lt;p&gt;Nunca confie no usuário, lembre-se que qualquer validação que você faça no lado do cliente é suceptível a mudanças pelo usuário. Valide tudo no back-end que seja necessário validação e faça testes para que se certifique que o seu resultado seja o esperado. Poderíamos trocar o &lt;code&gt;id&lt;/code&gt; de &lt;code&gt;int&lt;/code&gt; para um &lt;code&gt;UUID&lt;/code&gt;? Depende, se for só pra isso, não é uma boa ideia pois uma validação ja impossibilitaria isso e somente com essa mudança você estaria resolvendo apenas uma parte do problema. Você tem que entender os trade-offs ao se adotar essa técnica. (Recomendo o artigo &lt;a href="https://gist.github.com/rponte/bf362945a1af948aa04b587f8ff332f8" rel="noopener noreferrer"&gt;Pretende usar UUID como PK em vez de Int/BigInt no seu banco de dados? Pense novamente...&lt;/a&gt;, tem alguns insights muito bom)&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Obrigado por ler até aqui, esse é um dos meus posts que faz parte do meu novo jeito de aprender usando learn in public.&lt;/p&gt;

&lt;p&gt;Caso tenha interesse, você pode dar uma conferida sobre o que é isso: &lt;a href="https://www.swyx.io/learn-in-public/" rel="noopener noreferrer"&gt;https://www.swyx.io/learn-in-public/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pretendo continuar fazendo isso e já tenho o próximo post preparado. &lt;/p&gt;

&lt;p&gt;Spoiler: Esse também envolveu minha universidade&lt;/p&gt;

&lt;p&gt;:)&lt;/p&gt;

</description>
      <category>security</category>
      <category>api</category>
      <category>pentest</category>
    </item>
    <item>
      <title>How to emulate iOS on Linux with Docker</title>
      <dc:creator>Iaan Mesquita</dc:creator>
      <pubDate>Wed, 29 Dec 2021 01:06:06 +0000</pubDate>
      <link>https://dev.to/ianito/how-to-emulate-ios-on-linux-with-docker-4gj3</link>
      <guid>https://dev.to/ianito/how-to-emulate-ios-on-linux-with-docker-4gj3</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;NOTE&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;I am currently available for opportunities as a Full-Stack Engineer or Back-End Engineer. If you know of any open positions, please, feel free to contact me on LinkedIn  &lt;a href="https://www.linkedin.com/in/iaanmesquita/" rel="noopener noreferrer"&gt;Iaan Mesquita&lt;/a&gt; :).&lt;/p&gt;




&lt;p&gt;After several unsuccessful attempts, I was finally able to virtualize a macOS to run tests on an iOS app I was working on.&lt;/p&gt;

&lt;p&gt;But before proceeding, it is necessary to know that this is not a stable solution and has several performance issues, however, for my purpose I managed to do what I wanted.&lt;/p&gt;

&lt;p&gt;We'll use QEMU to emulate a mac and inside it  we'll use xCode to emulate an iOS. That process not will be lightweight.&lt;/p&gt;

&lt;p&gt;The repository on github of &lt;a href="https://github.com/sickcodes/Docker-OSX" rel="noopener noreferrer"&gt;Docker OSX&lt;/a&gt; has an explanation of how to use an iPhone via usb instead of emulating, but I don't have iPhone. xD&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;What is Docker OSX&lt;/li&gt;
&lt;li&gt;Hardware Specifications&lt;/li&gt;
&lt;li&gt;Installation&lt;/li&gt;
&lt;li&gt;Running a app with React Native&lt;/li&gt;
&lt;li&gt;Running a app with Cordova&lt;/li&gt;
&lt;li&gt;Creating a connection of folders over SSH&lt;/li&gt;
&lt;li&gt;Final considerations&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What is Docker OSX
&lt;/h2&gt;

&lt;p&gt;The Docker OSX is a docker image that uses QEMU so that we can emulate an operating system.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Read more: &lt;a href="https://www.docker.com/" rel="noopener noreferrer"&gt;What is Docker?&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Hardware Specifications
&lt;/h2&gt;

&lt;p&gt;My computer's specs are considered OK to do this, however, I still managed to notice some lags while using Docker OSX + xCode + Visual Studio Code + Dev Server. (I was even able to heat my room with that much stuff)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;OS:&lt;/strong&gt; Manjaro Linux x86_64 &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Kernel:&lt;/strong&gt; 4.19.220-1-MANJARO &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Shell:&lt;/strong&gt; zsh 5.8 &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resolution:&lt;/strong&gt; 1440x900&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DE:&lt;/strong&gt; GNOME 41.2 &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;WM:&lt;/strong&gt; Mutter &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;WM Theme:&lt;/strong&gt; Orchis-orange-compact &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Icons:&lt;/strong&gt; Win11-purple-dark [GTK2/3] &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Terminal:&lt;/strong&gt; gnome-terminal &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CPU:&lt;/strong&gt; Intel i7-3770 (8) @ 3.900GHz &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GPU:&lt;/strong&gt; NVIDIA GeForce GTX 1050 Ti &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Memory:&lt;/strong&gt; 4105MiB / 15985MiB &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SSD:&lt;/strong&gt; Crucial BX500 240gb (&lt;strong&gt;Highly recommended SSD&lt;/strong&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;

&lt;p&gt;First, is necessary have docker installed on your computer. I use Manajaro, so I just opened the terminal and type: &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Installation Docker&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;pacman -S docker&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Start docker services&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;systemctl start docker.service&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Enable docker services to boot with system&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;systemctl enable docker.service&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Testing docker:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;docker run hello-world&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxgj3c3zue8x13y0tps7c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxgj3c3zue8x13y0tps7c.png" alt="Docker run hello-world" width="800" height="530"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Alright, now we'll download the docker osx and run using the command below:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker run -it --device /dev/kvm -p 50922:10022 -e DEVICE_MODEL="iMacPro1,1" -e WIDTH=1440 -e HEIGHT=900 -e RAM=8 -e INTERNAL_SSH_PORT=23     -e AUDIO_DRIVER=alsa -e CORES=2 -v /tmp/.X11-unix:/tmp/.X11-unix -e "DISPLAY=${DISPLAY:-:0.0}"  -e GENERATE_UNIQUE=true  -e MASTER_PLIST_URL=https://raw.githubusercontent.com/sickcodes/osx-serial-generator/master/config-custom.plist sickcodes/docker-osx:big-sur&lt;/code&gt;&lt;br&gt;
You can check what each flag means at &lt;a href="https://github.com/sickcodes/Docker-OSX" rel="noopener noreferrer"&gt;github of docker osx&lt;/a&gt;.&lt;br&gt;
but briefly, i specified the resolution, memory, cores of processor, version and others things.&lt;/p&gt;

&lt;p&gt;Then, the docker osx will downloaded and initialized.&lt;/p&gt;

&lt;p&gt;When the emulator opens, select option &lt;code&gt;macOS Base System&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffubit7hhx6x50d4rynwe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffubit7hhx6x50d4rynwe.png" alt="Emulador Docker OSX" width="800" height="527"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When system be booted, select &lt;code&gt;Disk Utility&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff5ksa4x7piwfsj4qe291.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff5ksa4x7piwfsj4qe291.png" alt="Emulador Docker OSX" width="800" height="484"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, we'll search the partition that be with most storage space and select the option &lt;code&gt;Erase&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Firj97wizelw0hbfoamql.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Firj97wizelw0hbfoamql.png" alt="Docker OSX apagando sistema" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To format, the chosen options must be strictly equal to this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdrf8gki6wway416rb85h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdrf8gki6wway416rb85h.png" alt="Formatação opções" width="800" height="497"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on &lt;code&gt;Erase&lt;/code&gt;, wait process finish and then you can close the Disk Utility window.&lt;/p&gt;

&lt;p&gt;Next, select the option &lt;code&gt;Reinstall macOS Big Sur&lt;/code&gt;, accept the terms and select the partition we just created &lt;code&gt;macOS&lt;/code&gt; and start installation. (This process can take 30 min ~ 1 hour). &lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frd67yhek2mjer3bkm1h5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frd67yhek2mjer3bkm1h5.png" alt="Docker OSX Instalação" width="800" height="501"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, the system must restart (or not), in my case, I had to do it manually because it didn't restart. In that case, close the QEMU window.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F44eandfh00uh6swzrc0k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F44eandfh00uh6swzrc0k.png" alt="Qemu error" width="800" height="490"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In terminal, we'll type:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker ps -a&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;To know what is ID of our container and next we'll start typing the command below:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker start ID&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft0ythg12xpdnf5x9zhls.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft0ythg12xpdnf5x9zhls.png" alt="Docker IDS" width="800" height="63"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Select &lt;code&gt;macOS Installer&lt;/code&gt; and the installation will continue.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxq39lesxjerdba85w41k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxq39lesxjerdba85w41k.png" alt="Docker OSX Instalação" width="800" height="499"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then, the system will restart automatically (or not), so  close again the QUEMU and start again the container.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxe5lk5aq4xzw55j0afwj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxe5lk5aq4xzw55j0afwj.png" alt="Docker OSX Instalação" width="800" height="531"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When the system boot, select option &lt;code&gt;macOS Installer&lt;/code&gt; and wait the process finish. At end, the system will restart. (Now it's true).&lt;/p&gt;

&lt;p&gt;Well, macOS was installed successfully. Select the option &lt;code&gt;macOS&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwkzdtw9jozj91gi66v2f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwkzdtw9jozj91gi66v2f.png" alt="Docker OSX Inicialização" width="800" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once that's done, it will restart again and you select the same &lt;code&gt;macOS&lt;/code&gt; option.&lt;/p&gt;

&lt;p&gt;Well done, welcome screen appeared. This configuration part is quite slow, but after this process finished, the system will work very well.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fup2vajvs9p2l8g1vq39f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fup2vajvs9p2l8g1vq39f.png" alt="Tela de bem vindo macOS" width="800" height="498"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Configure the system , but don't login your AppleID at this moment.&lt;/p&gt;

&lt;p&gt;When that process done, our desktop will appears and we'll wait until the dock appear because after this, the system will be most stable.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fydprxzwqrnyp88tht3hf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fydprxzwqrnyp88tht3hf.png" alt="Tela de instalação mac OS Sem dock" width="800" height="498"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxoucf5ea5kl7r8cd2zr4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxoucf5ea5kl7r8cd2zr4.png" alt="Tela de instalação mac OS Com dock" width="800" height="498"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, we'll use the &lt;code&gt;brew&lt;/code&gt; for install the packages more fast.&lt;/p&gt;

&lt;p&gt;Open terminal in macOS and install brew with the command below:&lt;br&gt;
&lt;code&gt;/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Insert your password and wait the process finish. &lt;/p&gt;

&lt;p&gt;Now, we'll install &lt;code&gt;xcode&lt;/code&gt; on Apple Store.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzrchopyo4u207fyou05a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzrchopyo4u207fyou05a.png" alt="Apple store xcode" width="800" height="507"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So now, we can login on AppleID.  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Felma6mfjd6us7pst5y0l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Felma6mfjd6us7pst5y0l.png" alt="Login apple store" width="800" height="485"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After that, wait for the installation.&lt;/p&gt;

&lt;p&gt;Then, open &lt;code&gt;xcode&lt;/code&gt; and accept the terms and wait install the dependencies.&lt;/p&gt;

&lt;p&gt;So now, go at &lt;code&gt;Preferences -&amp;gt; Locations -&amp;gt; Command-Line Tools&lt;/code&gt; it will be blank, select the option with the xCode version.&lt;/p&gt;

&lt;p&gt;When the installation done, we'll open the terminal again and install &lt;code&gt;cocoapods&lt;/code&gt; with command below. It serve as packager manager of xCode.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;brew install cocoapods&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Done that, our &lt;code&gt;macOS&lt;/code&gt; will be installed and configured to run the projects.&lt;/p&gt;

&lt;h2&gt;
  
  
  Running a app with React Native
&lt;/h2&gt;

&lt;p&gt;Okay, let's start with a hello world of React Native to check if everything we've done before will work.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I'll only check iOS.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Open the terminal and type:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Install node:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;brew install node&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Install yarn (optional):&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;npm install -g yarn&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Creating a project with RN:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;npx react-native init teste&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If ask you to install cocoapods again, select the option with brew.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Enter at the project directory:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;cd teste&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Enter at ios directory:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;cd ios&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Install dependencies:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;pod install&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Back to root directory:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;cd ..&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;List all simulate availaibles:&lt;/strong&gt; (Optional)&lt;br&gt;
&lt;code&gt;xcrun simctl list devices&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Run the project with xcode:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;npx react-native run-ios --simulator="iPhone 13"&lt;/code&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjq34wwlfr17dubmhcy4s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjq34wwlfr17dubmhcy4s.png" alt="App rodando react native" width="800" height="499"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To a better experience, see section: Creating a connection of folders over SSH&lt;/p&gt;

&lt;h2&gt;
  
  
  Running a app with Cordova
&lt;/h2&gt;

&lt;p&gt;Okay, let's start with a hello world of Quasar to check if everything we've done before will work.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I'll only check iOS.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Quasar uses Cordova/Capacitor for iOS and Android.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Install node:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;brew install node&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Install yarn (opcional):&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;npm install -g yarn&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Install quasar:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;yarn global add @quasar/cli&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Install cordova:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;yarn global add cordova&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;Creating a project with Quasar:&lt;/em&gt;&lt;br&gt;
&lt;code&gt;quasar create teste&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Enter in project directory:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;cd teste&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Add cordova in your project:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;quasar mode add cordova&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Enter in cordova directory:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;cd src-cordova&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Add iOS in project:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;cordova platform add ios&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Verify if everything is okay:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;cordova requirements&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;List all simulate availables:&lt;/strong&gt; (Opcional)&lt;br&gt;
&lt;code&gt;cordova emulate iOS --list&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Install dependencies:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;yarn&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Back to root directory:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;cd ..&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Install dependencies:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;yarn&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Run quasar with development mode on iOS:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;quasar dev -m iOS -e "iPhone 8, 15.2"&lt;/code&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzjoyvlx1pl9u41n9jy15.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzjoyvlx1pl9u41n9jy15.png" alt="macOS quasar" width="800" height="503"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To a better experience, see section: Creating a connection of folders over SSH&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating a connection of folders over SSH
&lt;/h2&gt;

&lt;p&gt;Now our app is already running on macOS, we have a problem: Opening our code editor or IDE inside macOS is a very bad experience because of slowdowns, crashes, keyboard mapping and so on. So I researched a solution to create a file connection using SSH.&lt;/p&gt;

&lt;p&gt;Also, I can open the development server inside macOS and create a connection where I can change files directly from my linux or macOS so that it updates on both sides, like a two-way. This guarantees us to take advantage of some things that exist in development mode, like fast refresh.&lt;/p&gt;

&lt;h3&gt;
  
  
  Connection from linux to mac
&lt;/h3&gt;

&lt;p&gt;First, we need to allow connection via ssh via mac login. To do this, we will open the terminal and type:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Command to open edit ssh configuration file:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;sudo nano /etc/ssh/sshd_config&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Search for &lt;code&gt;PasswordAuthentication&lt;/code&gt; and put &lt;code&gt;yes&lt;/code&gt; and remove &lt;code&gt;#&lt;/code&gt; at beginning line.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3aqms7coe0l4xwdga0j1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3aqms7coe0l4xwdga0j1.png" alt="Configuração sshd" width="800" height="413"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Save file.&lt;/p&gt;

&lt;p&gt;Go to &lt;code&gt;System Preferences -&amp;gt; Sharing -&amp;gt; Remote Login&lt;/code&gt; and active for all users:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F77o3ld5524ufbtvue507.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F77o3ld5524ufbtvue507.png" alt="macOS configuração" width="800" height="496"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Command to restart ssh:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;sudo launchctl stop com.openssh.sshd &amp;amp;&amp;amp; sudo launchctl start com.openssh.sshd&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now, in linux terminal:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Install sshfs:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;sudo pacman -S sshfs&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Get container IP&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' ID_CONTAINER&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Create a folder:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;mkdir projeto&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Command to open a new connection with mac:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;sudo sshfs USER_MAC@IP_CONTAINER:/PATH/OF/PROJECT/ON/MAC /PATH/ON/LINUX -p 23&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgwcd70m354t5hnviy9h9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgwcd70m354t5hnviy9h9.png" alt="Exemplo de conexão" width="800" height="607"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Alright, now we can open the VSCode on linux and update the files updating directly on mac.&lt;/p&gt;

&lt;p&gt;If you have another computer, you can do this connection and let your computer with emulator just emulating.&lt;/p&gt;

&lt;h3&gt;
  
  
  Connection from Mac to Linux
&lt;/h3&gt;

&lt;p&gt;Same process  previously, but the sshfs package on mac can be installed using the command below:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Install sshfs&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;brew install --cask macfuse &amp;amp;&amp;amp; brew install gromgit/fuse/sshfs-mac&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;On Linux:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Command to edit ssh configuration file:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;sudo nano /etc/ssh/sshd_config&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Search for &lt;code&gt;PasswordAuthentication&lt;/code&gt; and put &lt;code&gt;yes&lt;/code&gt; and remove &lt;code&gt;#&lt;/code&gt; at beginning line.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3aqms7coe0l4xwdga0j1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3aqms7coe0l4xwdga0j1.png" alt="Configuração sshd" width="800" height="413"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Save the file.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Command to restart SHH on Manjaro:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;sudo systemctl restart sshd.service&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;On Mac, we'll create a folder to open connection.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Create a folder:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;mkdir projeto&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Command to open a new connection with linux&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;sudo sshfs USER_LINUX@IP_HOST:/PATH/LINUX /PATH/MAC -p 23&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;When we type the command, an error will occur.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffgq3r1245m3s94qe5yql.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffgq3r1245m3s94qe5yql.png" alt="Erro MAC" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Open the preferences and click &lt;code&gt;Allow&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsmhcxmmfcvvxdmrf8ssg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsmhcxmmfcvvxdmrf8ssg.png" alt="MacOS Preferencias" width="800" height="497"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Restart your mac.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Now, we can open the connection:&lt;/strong&gt; (My SSH is opened in a different port, but the default is 22)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwr871w7pezvkz80t1k53.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwr871w7pezvkz80t1k53.png" alt="Conexão SSH OK" width="800" height="506"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once that's done, we can update from either side which will also reflect on both.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final considerations
&lt;/h2&gt;

&lt;p&gt;Thank you very much for reading this tutorial, by the way it's the first one I've published in years. Any questions or suggestions(mostly my english) are always welcome.&lt;/p&gt;

&lt;p&gt;Oh, never update your mac.&lt;/p&gt;

&lt;p&gt;:)&lt;/p&gt;

</description>
      <category>linux</category>
      <category>ios</category>
      <category>virtualization</category>
      <category>xcode</category>
    </item>
    <item>
      <title>Como emular um iOS no Linux utilizando Docker</title>
      <dc:creator>Iaan Mesquita</dc:creator>
      <pubDate>Tue, 28 Dec 2021 21:47:12 +0000</pubDate>
      <link>https://dev.to/ianito/como-emular-um-ios-no-linux-utilizando-docker-3l75</link>
      <guid>https://dev.to/ianito/como-emular-um-ios-no-linux-utilizando-docker-3l75</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;AVISO&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Estou disponível para oportunidades como Desenvolvedor Full-stack ou Desenvolvedor Back-end. Caso conheça algum posição em aberto, sinta-se à vontade para entrar em contato comigo no LinkedIn &lt;a href="https://www.linkedin.com/in/iaanmesquita/" rel="noopener noreferrer"&gt;Iaan Mesquita&lt;/a&gt; :)&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;&lt;em&gt;English version:&lt;/em&gt;&lt;/strong&gt; &lt;a href="https://dev.to/ianito/how-to-emulate-ios-on-linux-with-docker-4gj3"&gt;How to emulate iOS on Linux with Docker&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Depois de várias tentativas sem sucesso, enfim consegui virtualizar um macOS para fazer testes em um aplicativo iOS no qual eu estava trabalhando.&lt;/p&gt;

&lt;p&gt;Mas antes de continuar, é necessário saber que essa não é uma solução estável e possue diversos problemas de desempenho, porém, para meu propósito consegui fazer o que queria.&lt;/p&gt;

&lt;p&gt;Nós utilizaremos o QEMU para emular um macOS e dentro dele, utilizaremos o xCode para emular um iOS, só nisso você já consegue perceber que não vai ser uma coisa leve.&lt;/p&gt;

&lt;p&gt;O repositório no github do &lt;a href="https://github.com/sickcodes/Docker-OSX" rel="noopener noreferrer"&gt;Docker OSX&lt;/a&gt; tem uma explicação de como usar um iPhone via usb ao invés de emular, mas eu não tenho iPhone :p&lt;/p&gt;

&lt;h2&gt;
  
  
  Sumário
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;O que é o Docker OSX&lt;/li&gt;
&lt;li&gt;Especificações de hardware&lt;/li&gt;
&lt;li&gt;Instalação&lt;/li&gt;
&lt;li&gt;Rodando um app com React Native&lt;/li&gt;
&lt;li&gt;Rodando um app com Cordova&lt;/li&gt;
&lt;li&gt;Criando uma conexão de pastas utilizando o sshfs&lt;/li&gt;
&lt;li&gt;Considerações finais&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  O que é o Docker OSX
&lt;/h2&gt;

&lt;p&gt;O Docker OSX é uma docker image que utiliza por debaixo dos panos o QEMU para que possamos emular um sistema operacional.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Leia mais: &lt;a href="https://stack.desenvolvedor.expert/appendix/docker/oquee.html" rel="noopener noreferrer"&gt;O que é docker?&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Minhas especificações de hardware
&lt;/h2&gt;

&lt;p&gt;As especificações do meu computador são consideradas OK pra fazer isso, porém, ainda consegui perceber algumas engasgadas enquanto utilizava o Docker OSX + xCode + Visual Studio Code + Dev Server. (Consegui até aquecer meu quarto com esse tanto de coisa.)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;OS:&lt;/strong&gt; Manjaro Linux x86_64 &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Kernel:&lt;/strong&gt; 4.19.220-1-MANJARO &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Shell:&lt;/strong&gt; zsh 5.8 &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resolution:&lt;/strong&gt; 1440x900&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DE:&lt;/strong&gt; GNOME 41.2 &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;WM:&lt;/strong&gt; Mutter &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;WM Theme:&lt;/strong&gt; Orchis-orange-compact &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Icons:&lt;/strong&gt; Win11-purple-dark [GTK2/3] &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Terminal:&lt;/strong&gt; gnome-terminal &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CPU:&lt;/strong&gt; Intel i7-3770 (8) @ 3.900GHz &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GPU:&lt;/strong&gt; NVIDIA GeForce GTX 1050 Ti &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Memory:&lt;/strong&gt; 4105MiB / 15985MiB &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SSD:&lt;/strong&gt; Crucial BX500 240gb (Altamente recomendado um SSD)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Instalação
&lt;/h2&gt;

&lt;p&gt;Primeiramente, é necessário ter o docker instalado no seu computador. No meu caso eu utilizo Manjaro, então basta abrir o terminal e digitar:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Instalação docker&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;pacman -S docker&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ativando os serviços do docker&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;systemctl start docker.service&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ativando os serviços do docker para iniciar junto com o sistema&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;systemctl enable docker.service&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Testando o docker:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;docker run hello-world&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxgj3c3zue8x13y0tps7c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxgj3c3zue8x13y0tps7c.png" alt="Docker run hello-world" width="800" height="530"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Certo, agora iremos baixar a imagem e executa-la utilizando o comando abaixo:&lt;br&gt;
&lt;code&gt;docker run -it --device /dev/kvm -p 50922:10022 -e DEVICE_MODEL="iMacPro1,1" -e WIDTH=1440 -e HEIGHT=900 -e RAM=8 -e INTERNAL_SSH_PORT=23     -e AUDIO_DRIVER=alsa -e CORES=2 -v /tmp/.X11-unix:/tmp/.X11-unix -e "DISPLAY=${DISPLAY:-:0.0}"  -e GENERATE_UNIQUE=true  -e MASTER_PLIST_URL=https://raw.githubusercontent.com/sickcodes/osx-serial-generator/master/config-custom.plist sickcodes/docker-osx:big-sur&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Você pode conferir o que cada flag significa olhando o repositório no &lt;a href="https://github.com/sickcodes/Docker-OSX" rel="noopener noreferrer"&gt;github do docker osx&lt;/a&gt;, mas resumidamente, especifiquei a resolução, memória ram, cores do processador, versão big-sur do macOS e etc.&lt;/p&gt;

&lt;p&gt;Em seguida, ele irá baixar a imagem e executar.&lt;/p&gt;

&lt;p&gt;Quando abrir o emulador, de enter na opção &lt;code&gt;macOS Base System&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffubit7hhx6x50d4rynwe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffubit7hhx6x50d4rynwe.png" alt="Emulador Docker OSX" width="800" height="527"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Quando carregar o sistema, clicaremos em &lt;code&gt;Disk Utility&lt;/code&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff5ksa4x7piwfsj4qe291.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff5ksa4x7piwfsj4qe291.png" alt="Emulador Docker OSX" width="800" height="484"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agora, procuraremos a partição que está com mais espaço de armazenamento e clicaremos na opção &lt;code&gt;Erase&lt;/code&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Firj97wizelw0hbfoamql.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Firj97wizelw0hbfoamql.png" alt="Docker OSX apagando sistema" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Para formatar é preciso que as opções estejam estritamentes iguais a esta:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdrf8gki6wway416rb85h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdrf8gki6wway416rb85h.png" alt="Formatação opções" width="800" height="497"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Clique em &lt;code&gt;Erase&lt;/code&gt;, aguarde e pode fechar a janela do Disk Utility. &lt;/p&gt;

&lt;p&gt;Em seguida, iremos em &lt;code&gt;Reinstall macOS Big Sur&lt;/code&gt; aceitamos os termos, selecionamos a partição que acabamos de criar &lt;code&gt;macOS&lt;/code&gt; e nisso, ele começará a instação do sistema. (Esse processo geralmente leva 30min ~ 1h). &lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frd67yhek2mjer3bkm1h5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frd67yhek2mjer3bkm1h5.png" alt="Docker OSX Instalação" width="800" height="501"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Aguardado esse tempo, o sistema deve reiniciar (ou não), no meu caso, eu tive que fazer isso de forma manual pois ele não reiniciou. Nesse caso, feche a janela do QEMU.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F44eandfh00uh6swzrc0k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F44eandfh00uh6swzrc0k.png" alt="Qemu error" width="800" height="490"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Novamente no terminal, digitaremos:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker ps -a&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Para saber qual o ID do nosso container, e em seguida iremos inicia-lo com:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker start ID&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft0ythg12xpdnf5x9zhls.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft0ythg12xpdnf5x9zhls.png" alt="Docker IDS" width="800" height="63"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Selecione o &lt;code&gt;macOS Installer&lt;/code&gt; e deixe que a instalação continue.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxq39lesxjerdba85w41k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxq39lesxjerdba85w41k.png" alt="Docker OSX Instalação" width="800" height="499"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Após o processo, ele irá reiniciar automaticamente (ou não), sendo assim, feche novamente o emulador e dê start no container mais uma vez.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxe5lk5aq4xzw55j0afwj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxe5lk5aq4xzw55j0afwj.png" alt="Docker OSX Instalação" width="800" height="531"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ao iniciar, novamente selecione a opção &lt;code&gt;macOS Installer&lt;/code&gt; e aguarde o processo terminar, feito isso ele irá reiniciar. (Agora é verdade).&lt;/p&gt;

&lt;p&gt;Nosso macOS foi instalado, com isso, vamos selecionar a opção &lt;code&gt;macOS&lt;/code&gt;. &lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwkzdtw9jozj91gi66v2f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwkzdtw9jozj91gi66v2f.png" alt="Docker OSX Inicialização" width="800" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Feito isso, irá reiniciar novamente e você selecione a mesma opção &lt;code&gt;macOS&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Show, nossa tela de bem vindo apareceu. Essa parte é bastante lenta, mas após isso irá ficar normal.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fup2vajvs9p2l8g1vq39f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fup2vajvs9p2l8g1vq39f.png" alt="Tela de bem vindo macOS" width="800" height="498"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Configure a sua maneira, mas não faça login no AppleID agora.&lt;/p&gt;

&lt;p&gt;Após esse processo, nossa área de trabalho aparecerá e então iremos aguardar até a dock aparecer, pois após isso o sistema fica mais fluído.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fydprxzwqrnyp88tht3hf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fydprxzwqrnyp88tht3hf.png" alt="Tela de instalação mac OS Sem dock" width="800" height="498"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxoucf5ea5kl7r8cd2zr4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxoucf5ea5kl7r8cd2zr4.png" alt="Tela de instalação mac OS Com dock" width="800" height="498"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agora iremos utilizar o gerenciador &lt;code&gt;brew&lt;/code&gt; para instalar as coisas mais rapidamente.&lt;/p&gt;

&lt;p&gt;Abra o terminal no macOS e instale o brew com o comando:&lt;br&gt;
&lt;code&gt;/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Irá pedir sua senha definida anteriormente para instalar.&lt;/p&gt;

&lt;p&gt;Agora iremos instalar o &lt;code&gt;xcode&lt;/code&gt; na apple store.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzrchopyo4u207fyou05a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzrchopyo4u207fyou05a.png" alt="Apple store xcode" width="800" height="507"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agora sim, podemos fazer o login da nossa conta AppleID. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Felma6mfjd6us7pst5y0l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Felma6mfjd6us7pst5y0l.png" alt="Login apple store" width="800" height="485"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Feito isso, aguarde a instalação. &lt;br&gt;
Em seguida, abra o xcode e aceite os termos e aguarde instalar as dependências.&lt;/p&gt;

&lt;p&gt;Em seguida, vá em &lt;code&gt;Preferences -&amp;gt; Locations -&amp;gt; Command-Line Tools&lt;/code&gt; vai estar vazio, selecione a opção com a versão do xcode.&lt;/p&gt;

&lt;p&gt;Quando a instalação terminar, abriremos o terminal novamente e instalaremos o cocoapods. Ele serve como um gerenciador de dependências do xCode.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;brew install cocoapods&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Feito isso, nosso macOS está instalado e configurado para rodar os projetos.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rodando um app com React Native
&lt;/h2&gt;

&lt;p&gt;Vamos rodar um hello world do React Native para ver se está tudo certo, lembrando que não irei testar o android somente o iOS.&lt;/p&gt;

&lt;p&gt;Abra o terminal&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Instalação no node:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;brew install node&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Instalação do yarn (opcional):&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;npm install -g yarn&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Criando um projeto react native:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;npx react-native init teste&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Se pedir pra instalar o cocoapods novamente, selecione a opção com brew.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Entrando no diretório do react native:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;cd teste&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Entrando no diretório do ios:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;cd ios&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Instalando as dependências:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;pod install&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Voltando para o diretório raiz:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;cd ..&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Listando os simuladores disponíveis:&lt;/strong&gt; (Opcional)&lt;br&gt;
&lt;code&gt;xcrun simctl list devices&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rodando o projeto utilizando xcode:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;npx react-native run-ios --simulator="iPhone 13"&lt;/code&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjq34wwlfr17dubmhcy4s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjq34wwlfr17dubmhcy4s.png" alt="App rodando react native" width="800" height="499"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Para uma experiência melhor, veja a seção: Criando uma conexão de pastas utilizando o sshfs&lt;/p&gt;

&lt;h2&gt;
  
  
  Rodando um app com Cordova
&lt;/h2&gt;

&lt;p&gt;Vamos rodar um hello world do Quasar para ver se está tudo certo, lembrando que não irei testar o android somente o iOS.&lt;/p&gt;

&lt;p&gt;Lembrando que o Quasar usa o Cordova/Capacitor pro iOS e Android.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Instalação no node:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;brew install node&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Instalação do yarn (opcional):&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;npm install -g yarn&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Instalação do quasar:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;yarn global add @quasar/cli&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Instalação do cordova:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;yarn global add cordova&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Criando um projeto com Quasar-CLI:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;quasar create teste&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Entrando no diretório do projeto:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;cd teste&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Adicionando cordova ao projeto:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;quasar mode add cordova&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Entrar no diretório do cordova:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;cd src-cordova&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Adicionar o iOS ao projeto:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;cordova platform add ios&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Verificar se está tudo certo:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;cordova requirements&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Listar emuladores disponíveis:&lt;/strong&gt; (Opcional)&lt;br&gt;
&lt;code&gt;cordova emulate iOS --list&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Instalar as dependências do projeto:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;yarn&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Voltar ao diretório raiz:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;cd ..&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Instalar as dependências do projeto:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;yarn&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rodar o quasar no modo desenvolvimento ioS:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;quasar dev -m iOS -e "iPhone 8, 15.2"&lt;/code&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzjoyvlx1pl9u41n9jy15.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzjoyvlx1pl9u41n9jy15.png" alt="macOS quasar" width="800" height="503"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Para uma experiência melhor, veja a seção: Criando uma conexão de pastas utilizando o sshfs&lt;/p&gt;

&lt;h2&gt;
  
  
  Criando uma conexão de pastas utilizando o sshfs
&lt;/h2&gt;

&lt;p&gt;Agora que fizemos tudo e nosso app já está rodando no macOS, temos um problema: Abrir nosso editor de código ou IDE dentro do macOS é uma experiência muito ruim por causa da lentidão, glitches, mapping do teclado e etc. Dessa forma, eu pesquisei uma solução para criar uma conexão de arquivos utilizando o SSH.&lt;/p&gt;

&lt;p&gt;Ou seja, eu posso abrir o servidor de desenvolvimento dentro do macOS e criar uma conexão em que eu possa alterar os arquivos direto do meu linux ou do macOS, de forma que atualize em ambos os lados, como uma via dupla. Isso nos garante tirar o proveito de algumas coisas que existem no modo desenvolvimento, como o fast refresh.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conexão do Linux para o Mac
&lt;/h3&gt;

&lt;p&gt;Primeiramente, precisamos permitir a conexão via ssh por login no mac. Para isso, abriremos o terminal e digitaremos:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Comando para abrir editar o arquivo de configuração do ssh:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;sudo nano /etc/ssh/sshd_config&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Busque por &lt;code&gt;PasswordAuthentication&lt;/code&gt; e coloque a configuração como &lt;code&gt;yes&lt;/code&gt; e remova o &lt;code&gt;#&lt;/code&gt; no começo da linha.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3aqms7coe0l4xwdga0j1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3aqms7coe0l4xwdga0j1.png" alt="Configuração sshd" width="800" height="413"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Salve o arquivo.&lt;br&gt;
Vá para em &lt;code&gt;System Preferences -&amp;gt; Sharing -&amp;gt; Remote Login&lt;/code&gt; e ative para todos os usuários:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F77o3ld5524ufbtvue507.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F77o3ld5524ufbtvue507.png" alt="macOS configuração" width="800" height="496"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Comando para reiniciar o ssh:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;sudo launchctl stop com.openssh.sshd &amp;amp;&amp;amp; sudo launchctl start com.openssh.sshd&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Agora, no terminal do nosso Linux:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Instalação do sshfs:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;sudo pacman -S sshfs&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pegando o IP do nosso container&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' ID_CONTAINER&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Criar uma pasta:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;mkdir projeto&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Comando para abrir a conexão:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;sudo sshfs USER_MAC@IP_CONTAINER:/CAMINHO/DO/PROJETO/NO/MAC /CAMINHO/NO/LINUX -p 23&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exemplo:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgwcd70m354t5hnviy9h9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgwcd70m354t5hnviy9h9.png" alt="Exemplo de conexão" width="800" height="607"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pronto, agora eu posso abrir o visual studio code no meu Linux e atualizar diretamente no Mac.&lt;/p&gt;

&lt;p&gt;Se você tiver um outro computador, pode fazer essa conexão também e deixar o seu principal apenas pra emular.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conexão do Mac para o Linux
&lt;/h3&gt;

&lt;p&gt;Mesmo processo anteriormente, só que o pacote do ssfs no mac pode ser instalado pelo comando abaixo.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Instalação sshfs no mac&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;brew install --cask macfuse &amp;amp;&amp;amp; brew install gromgit/fuse/sshfs-mac&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;No Linux:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Comando para abrir editar o arquivo de configuração do ssh:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;sudo nano /etc/ssh/sshd_config&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Busque por &lt;code&gt;PasswordAuthentication&lt;/code&gt; e coloque a configuração como &lt;code&gt;yes&lt;/code&gt; e remova o &lt;code&gt;#&lt;/code&gt; no começo da linha.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3aqms7coe0l4xwdga0j1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3aqms7coe0l4xwdga0j1.png" alt="Configuração sshd" width="800" height="413"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Salve o arquivo.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Comando para reiniciar o SSH no Manjaro:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;sudo systemctl restart sshd.service&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;De volta ao mac, criaremos uma pasta e abriremos a conexão.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Criar uma pasta:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;mkdir projeto&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Comando para abrir a conexão:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;sudo sshfs USER_LINUX@IP_HOST:/CAMINHO/LINUX /CAMINHO/MAC -p 23&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Após rodar o comando, irá acontecer um erro:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffgq3r1245m3s94qe5yql.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffgq3r1245m3s94qe5yql.png" alt="Erro MAC" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Abra as prefêrencias e clique em &lt;code&gt;Allow&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsmhcxmmfcvvxdmrf8ssg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsmhcxmmfcvvxdmrf8ssg.png" alt="MacOS Preferencias" width="800" height="497"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Reincie o mac.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Agora podemos abrir nossa conexão:&lt;/strong&gt; (Meu SSH está com uma porta diferente, mas a padrão é 22)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwr871w7pezvkz80t1k53.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwr871w7pezvkz80t1k53.png" alt="Conexão SSH OK" width="800" height="506"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Feito isso, podemos atualizar de qualquer lado que também irá atualizar.&lt;/p&gt;

&lt;h2&gt;
  
  
  Considerações finais
&lt;/h2&gt;

&lt;p&gt;Muito obrigado por ler este tutorial, que aliás, é o primeiro que publico depois de anos. Qualquer dúvida ou sugestão é sempre bem vinda.&lt;/p&gt;

&lt;p&gt;Ah, nunca atualize o mac.&lt;/p&gt;

&lt;p&gt;:)&lt;/p&gt;

</description>
      <category>linux</category>
      <category>ios</category>
      <category>virtualization</category>
      <category>xcode</category>
    </item>
  </channel>
</rss>
