<?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: Ali khajehpour</title>
    <description>The latest articles on DEV Community by Ali khajehpour (@ali72110).</description>
    <link>https://dev.to/ali72110</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%2F1132823%2Fd4da8ef7-140a-4601-ae3e-2ce9e7ec7e2c.png</url>
      <title>DEV Community: Ali khajehpour</title>
      <link>https://dev.to/ali72110</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ali72110"/>
    <language>en</language>
    <item>
      <title>Proxy Design Pattern in Swift</title>
      <dc:creator>Ali khajehpour</dc:creator>
      <pubDate>Mon, 07 Aug 2023 15:17:51 +0000</pubDate>
      <link>https://dev.to/ali72110/proxy-design-pattern-in-swift-1nhj</link>
      <guid>https://dev.to/ali72110/proxy-design-pattern-in-swift-1nhj</guid>
      <description>&lt;h2&gt;
  
  
  Preface
&lt;/h2&gt;

&lt;p&gt;Nearly all actual projects don’t require us to write every module from scratch; instead, we use third-party libraries to solve our issues, speed up development, and let us focus on our key features.&lt;/p&gt;

&lt;p&gt;In order to use the features of third-party libraries, especially when importing them as modules through Cocoapod or SPM, you must import them everywhere.&lt;/p&gt;

&lt;p&gt;Imagine, however, that after using &lt;a href="https://github.com/onevcat/Kingfisher"&gt;Kingfisher&lt;/a&gt; for image loading for a while, you find that &lt;a href="https://github.com/kean/Nuke"&gt;Nuke&lt;/a&gt; or &lt;a href="https://github.com/SDWebImage/SDWebImage"&gt;SDWebImage&lt;/a&gt; performs much better for your needs.&lt;/p&gt;

&lt;p&gt;If this is the case, you must replace the old module with the new one in all of your files. the situation will get even worse when you have to replace or remove all of the old module functions from your project because you are using so many of them.&lt;/p&gt;

&lt;p&gt;In such a case, you can use the &lt;strong&gt;Proxy&lt;/strong&gt; &lt;strong&gt;design&lt;/strong&gt; &lt;strong&gt;pattern&lt;/strong&gt; as a savior.&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GdbkB4k5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dbnbanga813l6zj6u2z5.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GdbkB4k5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dbnbanga813l6zj6u2z5.gif" alt="savior mime" width="480" height="358"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Definition
&lt;/h2&gt;

&lt;p&gt; &lt;br&gt;
The proxy design pattern is a structural design pattern that we use to provide a placeholder for another object and control access to it.&lt;/p&gt;

&lt;p&gt;To explain it better, first, take a look at the logical diagram of proxy:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--O-dgq3E2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/85mu8wkauco99woo7rai.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--O-dgq3E2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/85mu8wkauco99woo7rai.png" alt="logical diagram of proxy" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see, we have blocked all client access to the real object since they can only communicate with the proxy object. with this approach, we &lt;strong&gt;protect&lt;/strong&gt; and &lt;strong&gt;hide&lt;/strong&gt; all of the real object’s functions and variables from other project components.&lt;/p&gt;




&lt;h2&gt;
  
  
  Applicability
&lt;/h2&gt;

&lt;p&gt; &lt;br&gt;
In general, there are three different types of proxy design patterns:&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Remote proxy&lt;/strong&gt;: Represents actual objects in a different space. for example, REST APIs create objects on the server, and clients use REST requests to access those objects.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--y4B5hVuE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mcw2yzbcaw0w71h2fg5a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--y4B5hVuE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mcw2yzbcaw0w71h2fg5a.png" alt="remote proxy image" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Virtual proxy&lt;/strong&gt;: Creates expensive objects on demand.in this approach, proxy objects stand as a substitute for the real object but act in a different way to delay its creation.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3_vnORKL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z7hwueiqfrmdxlg125wr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3_vnORKL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z7hwueiqfrmdxlg125wr.png" alt="virtual proxy image" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Protection proxy&lt;/strong&gt;: controls access to the real object. the protection proxy is also useful when the real object needs various access roles for every client object or component.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Jrf6-Dos--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4xlckiknb3qimhzdsr1h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Jrf6-Dos--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4xlckiknb3qimhzdsr1h.png" alt="protection proxy image" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Implementation
&lt;/h2&gt;

&lt;p&gt; &lt;br&gt;
First, let me show the &lt;strong&gt;remote&lt;/strong&gt; proxy in the code:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sabjNAcP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6sdi0jhuadz7jpbkqftt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sabjNAcP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6sdi0jhuadz7jpbkqftt.png" alt="implementation api image" width="800" height="435"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see from the code, the real object was created on the server side and sent to the client after serialization. It wasn’t created in our app. The client obtained this object, deserialized it, and used it within the app. If we assume that the client only requests updates or receives the most recent value, then the &lt;strong&gt;user&lt;/strong&gt; object is a remote proxy object, and the API class serves as our proxy to access the user object.&lt;/p&gt;

&lt;p&gt;Next, let's look at the &lt;strong&gt;virtual&lt;/strong&gt; proxy in the code:&lt;/p&gt;

&lt;p&gt; &lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FHn6rneG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xjjkuuw9r1lwsi49lch7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FHn6rneG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xjjkuuw9r1lwsi49lch7.png" alt="virtual proxy image" width="800" height="871"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;As you can see from the code above, the placeholder image is returned if the getImage function is called before the image is prepared to display. Until the actual image process (downloading or drawing) is complete, a placeholder image is a virtual object that stands in for a real image. Following that, calling the getImage or getSize functions will result in a real image being returned.&lt;/p&gt;

&lt;p&gt;Finally, we must specify how other objects can access our actual objects in order to implement a &lt;strong&gt;protection&lt;/strong&gt; proxy.&lt;/p&gt;

&lt;p&gt;As we discussed in the introduction to this article, let’s solve the image loader issue. This problem can be resolved by first using a protocol to specify how other objects can access our image loader.&lt;/p&gt;

&lt;p&gt; &lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1Ur7ESUa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nlv87v8nxbnqx67jwfen.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1Ur7ESUa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nlv87v8nxbnqx67jwfen.png" alt="protection proxy image" width="800" height="237"&gt;&lt;/a&gt;&lt;br&gt;
 &lt;/p&gt;

&lt;p&gt;As you see, all input and output of the &lt;em&gt;loadImage&lt;/em&gt; function are Swift features or Apple’s first-party libraries for the iOS platform (like UIKit).&lt;/p&gt;

&lt;p&gt; &lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PXq1ra5u--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/23uh6wsas76vnce45tz9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PXq1ra5u--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/23uh6wsas76vnce45tz9.png" alt="ImageLoaderPorotocol image" width="800" height="452"&gt;&lt;/a&gt;&lt;br&gt;
 &lt;/p&gt;

&lt;p&gt;Now, we create another file and import the required third-party library inside it and implement &lt;em&gt;ImageLoaderPorotocol&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;You can even use this technique when using &lt;strong&gt;RxSwift&lt;/strong&gt; or &lt;strong&gt;Combine&lt;/strong&gt;. here is an example of the RxSwift version:&lt;/p&gt;

&lt;p&gt; &lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8dxKNtjv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y820p7rs5uxzaabtyott.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8dxKNtjv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y820p7rs5uxzaabtyott.png" alt="rx image proxy" width="800" height="302"&gt;&lt;/a&gt;&lt;br&gt;
 &lt;/p&gt;

&lt;p&gt;As you can see, the codes above use the Nuke image loader but instead return a regular image.&lt;/p&gt;

&lt;p&gt;With this method, we don’t have to import Nuke into each and every file that needs to load an image, and you can swap out the Nuke library whenever you like with any other image loader by simply implementing the ImageLoaderProtocol function with a new image loader library (like KingFisher or SDWebImage).&lt;/p&gt;




&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h3&gt;
  
  
  When should we use the proxy design pattern?
&lt;/h3&gt;

&lt;p&gt;Proxy design patterns are typically used when we try to limit access to a specific object via API and hide it from other parts of a project (protection proxy). but as you can see in the example above, you can use proxy design patterns when you want to virtualize your real object with a placeholder to defer the real object’s cost of creation (virtual proxy) or use an object that is placed in another space rather than your code (remote proxy).&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h3&gt;
  
  
  What’s different between the Proxy and Decorator design patterns? (Proxy vs Decorator)
&lt;/h3&gt;

&lt;p&gt;While the Decorator design pattern wraps the real object and gives it more responsibility, the primary purpose of using a proxy design pattern is to hide and conceal the real object from clients.&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h3&gt;
  
  
  What’s different between the Proxy and Adaptor design patterns? (Proxy vs Adaptor)
&lt;/h3&gt;

&lt;p&gt;The adaptor design pattern is primarily used to adapt to incompatible and legacy codes. It wraps and provides a different interface for the real object.&lt;/p&gt;

&lt;p&gt;For example, if your app uses multiple login methods (such as Google, Apple, Facebook, etc.), all of them must confirm the login protocol. By using this method, you can communicate with your login systems effectively and without a boilerplate.&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h3&gt;
  
  
  What’s different between Proxy and facade design patterns? (Proxy vs facade)
&lt;/h3&gt;

&lt;p&gt;The facade design pattern is primarily used to simplify the use of complex objects or libraries. While a proxy will wrap only one object to control access to it, a facade wraps one or more objects to simplify their complex behavior or creation.&lt;/p&gt;

&lt;p&gt;In summary, the facade reduces communication and dependencies between objects, whereas the proxy serves as a bridge between the client and the wrapped object.&lt;/p&gt;




&lt;p&gt;My &lt;a href="https://github.com/Ali72"&gt;Github&lt;/a&gt;&lt;br&gt;
 My &lt;a href="https://ali72.github.io/"&gt;Personal website&lt;/a&gt;&lt;/p&gt;

</description>
      <category>swift</category>
      <category>ios</category>
      <category>designpatterns</category>
      <category>architecture</category>
    </item>
  </channel>
</rss>
