<?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: Md. Asif Rahman</title>
    <description>The latest articles on DEV Community by Md. Asif Rahman (@asifzcpe).</description>
    <link>https://dev.to/asifzcpe</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%2F237563%2Fcfbfc8e6-aa3e-42c9-9b27-3fea7c5580f5.jpg</url>
      <title>DEV Community: Md. Asif Rahman</title>
      <link>https://dev.to/asifzcpe</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/asifzcpe"/>
    <language>en</language>
    <item>
      <title>Mastering Background Job Processing with Supervisor and Laravel Queues</title>
      <dc:creator>Md. Asif Rahman</dc:creator>
      <pubDate>Tue, 24 Dec 2024 12:01:05 +0000</pubDate>
      <link>https://dev.to/asifzcpe/mastering-background-job-processing-with-supervisor-and-laravel-queues-1onb</link>
      <guid>https://dev.to/asifzcpe/mastering-background-job-processing-with-supervisor-and-laravel-queues-1onb</guid>
      <description>&lt;p&gt;In complex systems where large-scale background processing is essential—like fetching weather data for multiple cities or processing customer transactions —tools such as Supervisor and Laravel queues are indispensable. They help you manage long-running processes efficiently, ensuring jobs run continuously, restart automatically when they fail, and scale dynamically. This article dives deep into how Supervisor works, including its interaction with the Linux kernel, and explores how to optimize job processing for maximum performance.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is Supervisor, and Why Should You Care?
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Supervisor Overview
&lt;/h4&gt;

&lt;p&gt;Supervisor is a process control system that helps manage background processes on Unix-based systems. Think of it as a system manager that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ensures jobs continue running.&lt;/li&gt;
&lt;li&gt;Restarts jobs if they fail.&lt;/li&gt;
&lt;li&gt;Logs output and errors for easier debugging.&lt;/li&gt;
&lt;li&gt;Monitors system resources to prevent overload.&lt;/li&gt;
&lt;li&gt;It's like having an experienced manager who ensures tasks in your team are executed and adjusted when things go wrong.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Key Features of Supervisor
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Process Management:&lt;/strong&gt; Supervisor keeps processes running by starting, stopping, and restarting them when needed. It ensures long-running tasks stay up and running, even after crashes or failures.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Logging:&lt;/strong&gt; It tracks the output and error logs of processes, which helps in debugging and monitoring.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Notifications:&lt;/strong&gt; Alerts you when a process crashes or restarts, providing vital insights into system health.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Scalability:&lt;/strong&gt; You can configure multiple worker processes (instances) to handle high loads and ensure timely task processing.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Still, if you are not clear about what Supervisor is, have a look on the following analogy to grab it well in mind.&lt;/p&gt;

&lt;h3&gt;
  
  
  Analogy: Supervisor as a Factory Manager
&lt;/h3&gt;

&lt;p&gt;Imagine a factory that manufactures cars. The factory has multiple assembly lines (processes), and the manager (Supervisor) ensures each line is operational:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Each Line (Process):&lt;/strong&gt; Handles a specific task—such as assembling the chassis, attaching the wheels, and painting the car.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Manager:&lt;/strong&gt; Ensures the lines are always active. If a worker (process) falls behind or crashes, the manager replaces them. When the workload increases (more cars to build), the manager hires more workers (processes).&lt;/p&gt;

&lt;p&gt;I hope now, you are totally clear about what supervisor actually is.&lt;/p&gt;

&lt;p&gt;Now, lets have a dive into how it works on the kernel level.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Supervisor Works on the Kernel Level
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Supervisor&lt;/strong&gt; interacts closely with the &lt;strong&gt;Linux kernel&lt;/strong&gt; to manage system resources effectively. Understanding this interaction is crucial for optimizing Supervisor's performance.&lt;/p&gt;

&lt;h3&gt;
  
  
  Kernel Process Management
&lt;/h3&gt;

&lt;p&gt;At its core, the &lt;strong&gt;Linux kernel&lt;/strong&gt; is responsible for managing system resources, such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Process Scheduling&lt;/strong&gt;: Determines which processes get CPU time and for how long.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resource Allocation&lt;/strong&gt;: Ensures each process gets access to memory and CPU without interfering with others.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Process Termination and Restart&lt;/strong&gt;: The kernel tracks processes and terminates or restarts them if necessary.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Supervisor’s Interaction with the Kernel
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Supervisor Process&lt;/strong&gt;: Supervisor itself is a process managed by the kernel. It spawns other processes (workers) and monitors their state using kernel system calls.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Process Control&lt;/strong&gt;: Supervisor uses the kernel’s process control functions to start, stop, and restart worker processes based on your configuration (e.g., &lt;code&gt;autostart=true&lt;/code&gt; and &lt;code&gt;autorestart=true&lt;/code&gt;).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Resource Management&lt;/strong&gt;: Supervisor can adjust the number of worker processes (using &lt;code&gt;numprocs&lt;/code&gt;) based on system resources like available CPU cores and memory. It can also set resource limits to prevent workers from overconsuming resources.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Kernel Signals&lt;/strong&gt;: When a process crashes or stops, Supervisor sends kernel signals (&lt;code&gt;SIGTERM&lt;/code&gt; to stop, &lt;code&gt;SIGKILL&lt;/code&gt; to forcefully kill) to handle failed workers.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  How to Set Up Supervisor for Laravel Queues
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Basic Configuration
&lt;/h2&gt;

&lt;p&gt;To configure &lt;strong&gt;Supervisor&lt;/strong&gt; for Laravel queue workers, follow these steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Create a configuration file at &lt;code&gt;/etc/supervisor/conf.d/laravel-worker.conf&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add the following setup to the configuration file:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="nn"&gt;[program:laravel-worker]&lt;/span&gt;
&lt;span class="py"&gt;command&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;php /path/to/your/laravel/artisan queue:work --sleep=3 --tries=3&lt;/span&gt;
&lt;span class="py"&gt;autostart&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;true&lt;/span&gt;
&lt;span class="py"&gt;autorestart&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;true&lt;/span&gt;
&lt;span class="py"&gt;stderr_logfile&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;/var/log/laravel-worker.err.log&lt;/span&gt;
&lt;span class="py"&gt;stdout_logfile&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;/var/log/laravel-worker.out.log&lt;/span&gt;
&lt;span class="py"&gt;numprocs&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;4&lt;/span&gt;
&lt;span class="py"&gt;process_name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;%(program_name)s_%(process_num)02d&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Explanation
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;command&lt;/code&gt;&lt;/strong&gt;: Specifies the command to run the Laravel queue worker.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Example: &lt;code&gt;php artisan queue:work&lt;/code&gt; executes the Laravel queue.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;numprocs&lt;/code&gt;&lt;/strong&gt;: Defines how many worker processes should run simultaneously. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Example: Setting &lt;code&gt;numprocs=4&lt;/code&gt; runs four worker processes.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;autostart&lt;/code&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;code&gt;autorestart&lt;/code&gt;&lt;/strong&gt;: Ensure that workers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Start automatically when Supervisor starts.&lt;/li&gt;
&lt;li&gt;Restart automatically if they crash.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;stderr_logfile&lt;/code&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;code&gt;stdout_logfile&lt;/code&gt;&lt;/strong&gt;: Specify log files for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Error logs (e.g., &lt;code&gt;/var/log/laravel-worker.err.log&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Standard output logs (e.g., &lt;code&gt;/var/log/laravel-worker.out.log&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;process_name&lt;/code&gt;&lt;/strong&gt;: Uniquely identifies each worker process.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Example: Workers are named &lt;code&gt;laravel-worker_00&lt;/code&gt;, &lt;code&gt;laravel-worker_01&lt;/code&gt;, etc., based on the &lt;code&gt;process_num&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Save and Apply Configuration
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Save the configuration file.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Update Supervisor to recognize the new configuration:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;supervisorctl reread
&lt;span class="nb"&gt;sudo &lt;/span&gt;supervisorctl update
&lt;span class="nb"&gt;sudo &lt;/span&gt;supervisorctl start laravel-worker:&lt;span class="k"&gt;*&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Monitor Workers
&lt;/h2&gt;

&lt;p&gt;To check the status of your workers, use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;supervisorctl status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What Happens When You Have Too Many Jobs?
&lt;/h2&gt;

&lt;p&gt;Let’s consider an example where you are processing &lt;strong&gt;100 jobs&lt;/strong&gt; (e.g., fetching weather data for 100 cities), but your &lt;strong&gt;Supervisor configuration&lt;/strong&gt; only allows &lt;strong&gt;13 workers&lt;/strong&gt; (&lt;code&gt;numprocs=13&lt;/code&gt;). Here’s how the system manages it:&lt;/p&gt;

&lt;h4&gt;
  
  
  1. FIFO Queueing
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Supervisor handles jobs using a &lt;strong&gt;First In, First Out (FIFO)&lt;/strong&gt; queue.&lt;/li&gt;
&lt;li&gt;With 13 workers, only &lt;strong&gt;13 jobs can run simultaneously&lt;/strong&gt;, while the remaining &lt;strong&gt;87 jobs&lt;/strong&gt; wait in the queue.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  2. Batch Processing
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Once a worker completes a task, it immediately picks up another job from the queue.&lt;/li&gt;
&lt;li&gt;This creates a &lt;strong&gt;continuous cycle&lt;/strong&gt; where jobs are processed in batches until all are completed.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  3. Time to Completion
&lt;/h4&gt;

&lt;p&gt;To calculate the approximate total time required to process all jobs, use this formula:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Total Jobs&lt;/strong&gt;: 100
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Number of Workers&lt;/strong&gt;: 13
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Time per Job&lt;/strong&gt;: 5 seconds
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Total Time = (Total Jobs ÷ Number of Workers) × Time per Job
Total Time = (100 ÷ 13) × 5 = ~38.46 seconds
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Does &lt;code&gt;numprocs&lt;/code&gt; Equal CPU Cores?
&lt;/h3&gt;

&lt;p&gt;No, &lt;code&gt;numprocs&lt;/code&gt; does not directly correlate with CPU cores.&lt;/p&gt;

&lt;h4&gt;
  
  
  For CPU-Intensive Tasks:
&lt;/h4&gt;

&lt;p&gt;If your tasks are &lt;strong&gt;CPU-bound&lt;/strong&gt; (e.g., data processing, video encoding), the number of workers should be &lt;strong&gt;limited to the number of available CPU cores&lt;/strong&gt; to avoid overloading the system.&lt;/p&gt;

&lt;h4&gt;
  
  
  For I/O-Intensive Tasks:
&lt;/h4&gt;

&lt;p&gt;If your tasks are &lt;strong&gt;I/O-bound&lt;/strong&gt; (e.g., making API calls, reading from disk), you can run &lt;strong&gt;more workers than the number of cores&lt;/strong&gt;, since these tasks spend much of their time waiting for I/O operations to complete.&lt;/p&gt;

&lt;h4&gt;
  
  
  Example:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;On an &lt;strong&gt;8-core machine&lt;/strong&gt;, you might run &lt;strong&gt;16 workers&lt;/strong&gt; for API-heavy jobs.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  To check the number of CPU cores:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;nproc&lt;/span&gt;   &lt;span class="c"&gt;# Shows the number of CPU cores.&lt;/span&gt;
lscpu   &lt;span class="c"&gt;# Provides detailed CPU information.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Scaling Your Job Processing in Laravel
&lt;/h3&gt;

&lt;p&gt;Scaling your job processing setup ensures your system remains responsive under heavy workloads. Below are key strategies for scaling:&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Add More Workers
&lt;/h4&gt;

&lt;p&gt;Increase the number of worker processes (&lt;code&gt;numprocs&lt;/code&gt;) to handle more jobs simultaneously. However, be mindful of resource consumption:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="py"&gt;numprocs&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;20&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ensure the server has adequate resources (CPU, memory) to handle the extra load.&lt;/p&gt;

&lt;h4&gt;
  
  
  2. Prioritize Critical Jobs
&lt;/h4&gt;

&lt;p&gt;You can create separate queues for different job priorities. This ensures that critical tasks are processed first:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="nn"&gt;[program:high-priority-worker]&lt;/span&gt;
&lt;span class="py"&gt;command&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;php artisan queue:work --queue=high&lt;/span&gt;
&lt;span class="py"&gt;numprocs&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;6&lt;/span&gt;

&lt;span class="nn"&gt;[program:low-priority-worker]&lt;/span&gt;
&lt;span class="py"&gt;command&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;php artisan queue:work --queue=low&lt;/span&gt;
&lt;span class="py"&gt;numprocs&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;7&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  3. Scale Horizontally
&lt;/h4&gt;

&lt;p&gt;Distribute job processing across multiple servers to balance the load. Use a shared queue system like Redis to allow all servers to pull jobs from the same queue:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Set up multiple Supervisor instances on different servers.&lt;/li&gt;
&lt;li&gt;Use a distributed queue (e.g., Redis) to synchronize jobs between servers.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  4. Monitor and Adjust Configurations
&lt;/h4&gt;

&lt;p&gt;Use tools like &lt;a href="https://laravel.com/docs/10.x/horizon" rel="noopener noreferrer"&gt;Laravel Horizon&lt;/a&gt; to monitor your queue workers' performance in real-time. Horizon provides visual insights into job processing, queue lengths, and resource consumption, allowing you to fine-tune configurations as needed.&lt;/p&gt;

&lt;p&gt;Finally, given below is a pictorial presentation on how supervisor works:&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%2Fa1nom7wbm3jxkc4tncys.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%2Fa1nom7wbm3jxkc4tncys.png" alt="Image description" width="800" height="711"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Supervisor is a powerful tool for managing background processes in large-scale systems. When paired with Laravel’s queue system, it ensures tasks are processed efficiently and reliably, even during peak workloads. By understanding its configuration options, interaction with the Linux kernel, and scaling strategies, you can optimize job processing, ensuring minimal downtime and smooth operations for your users.&lt;/p&gt;

&lt;p&gt;By following best practices and leveraging tools like Laravel Horizon and Redis, you can ensure your system remains responsive, scalable, and reliable.&lt;/p&gt;

</description>
      <category>supervisor</category>
      <category>laravelqueues</category>
      <category>backgroundjobs</category>
      <category>processmanagement</category>
    </item>
    <item>
      <title>Commit vs. Rollback: Database Transaction Essentials</title>
      <dc:creator>Md. Asif Rahman</dc:creator>
      <pubDate>Tue, 25 Jun 2024 19:25:07 +0000</pubDate>
      <link>https://dev.to/asifzcpe/demystifying-database-transactions-how-commit-and-rollback-ensure-smooth-data-handling-2mo2</link>
      <guid>https://dev.to/asifzcpe/demystifying-database-transactions-how-commit-and-rollback-ensure-smooth-data-handling-2mo2</guid>
      <description>&lt;p&gt;In the world of databases, transactions are akin to journeys—comprising a series of steps or operations performed as a single, cohesive unit of work. Whether you're booking a flight, ordering groceries online, or transferring funds between accounts, transactions play a vital role in ensuring that database operations are reliable, consistent, and resilient. Let's take on a journey through the commit and rollback processes in database transactions, exploring each step with relatable analogies to make the journey more understandable, followed by the technical details.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Commit Process
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.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%2Ftqigcmd72esqh95mrmdx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Ftqigcmd72esqh95mrmdx.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Initiating the Journey: Begin Transaction
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Analogy:
&lt;/h4&gt;

&lt;p&gt;Think of it as the moment you decide to embark on a trip. You gather your essentials and map out your route before setting off. This planning phase ensures that you're prepared for the journey ahead.&lt;/p&gt;

&lt;h4&gt;
  
  
  Technical Detail:
&lt;/h4&gt;

&lt;p&gt;A transaction begins with the BEGIN TRANSACTION statement. This marks the start of a series of operations that must be executed atomically. All changes made during the transaction are initially tentative and only become permanent upon commit.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Logging the Voyage: Write-Ahead Logging (WAL)
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Analogy:
&lt;/h4&gt;

&lt;p&gt;Before setting sail, it's wise to create a list of everything you're bringing along. Similarly, the WAL records all changes made by the transaction in a log before they're applied to the database. This log serves as a safety net, allowing for recovery in case of unforeseen circumstances—much like referring back to your list if you forget something during your journey.&lt;/p&gt;

&lt;h4&gt;
  
  
  Technical Detail:
&lt;/h4&gt;

&lt;p&gt;Before making any changes to the database, the system writes these changes to a write-ahead log (WAL). The WAL is a sequential record of all modifications. By logging changes before they are applied, the database can ensure durability and support recovery in case of a crash.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Planning the Itinerary: In-Memory Data Modification
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Analogy:
&lt;/h4&gt;

&lt;p&gt;With your journey underway, you begin planning your itinerary and mentally preparing for the adventure. It's akin to mapping out your route and making mental notes of the places you'll visit before physically setting foot on your journey.&lt;/p&gt;

&lt;h4&gt;
  
  
  Technical Detail:
&lt;/h4&gt;

&lt;p&gt;Changes are initially made in-memory, within the database's buffer cache. This allows for quick response times and reduces the immediate need for disk I/O. The in-memory data structures are updated first, and these changes are later propagated to the disk.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Securing the Record: Log Flush
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Analogy:
&lt;/h4&gt;

&lt;p&gt;Just as you ensure your list is safely stored in your backpack before hitting the road, the database flushes the log entries to disk to ensure they're durably recorded. This step guarantees that there's a persistent record of the transaction's changes, providing a safety net in case of unexpected detours or interruptions along the way.&lt;/p&gt;

&lt;h4&gt;
  
  
  Technical Detail:
&lt;/h4&gt;

&lt;p&gt;The log entries recorded in the WAL are flushed to disk to ensure their durability. This means writing the log entries from memory to stable storage, ensuring that they are not lost even if there is a system crash.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Confirming the Voyage: Commit Record
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Analogy:
&lt;/h4&gt;

&lt;p&gt;As you progress on your journey and decide to commit to the adventure, you officially confirm your plans by signing your name on a travel document. Similarly, in a database, a special commit record is written to the log to mark the transaction as complete. This commitment ensures that the changes made by the transaction are finalized and applied to the database.&lt;/p&gt;

&lt;h4&gt;
  
  
  Technical Detail:
&lt;/h4&gt;

&lt;p&gt;A commit record is written to the WAL to indicate that the transaction has been successfully completed. This commit record marks the point at which all changes made by the transaction become permanent.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Ensuring Durability: Data Page Flush (Deferred)
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Analogy:
&lt;/h4&gt;

&lt;p&gt;While you've committed to your journey, you may not immediately load all your belongings onto the transport. Similarly, in a database, modified data pages in the buffer cache are eventually flushed to disk, but not necessarily immediately. This delayed flushing optimizes performance while still ensuring durability, much like waiting for the right moment to load your belongings for maximum efficiency.&lt;/p&gt;

&lt;h4&gt;
  
  
  Technical Detail:
&lt;/h4&gt;

&lt;p&gt;While the commit ensures the changes are durable, the actual data pages containing the changes might not be immediately written to disk. The database employs a lazy writing strategy, flushing these pages to disk at a later time, optimizing for performance.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Rollback Process
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.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%2F5fpv8vwz33idi34kc9h1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F5fpv8vwz33idi34kc9h1.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Identifying Uncommitted Changes: Identifying Mistakes in Your List
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Analogy:
&lt;/h4&gt;

&lt;p&gt;Suppose you suddenly realize you've forgotten to pack something essential. You identify the items you haven't packed yet. In a database, this means identifying changes made by the transaction that need to be undone.&lt;/p&gt;

&lt;h4&gt;
  
  
  Technical Detail:
&lt;/h4&gt;

&lt;p&gt;If a transaction needs to be rolled back, the database first identifies all changes made by the transaction that have not been committed. This involves scanning the WAL to find all operations that need to be undone.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F1trfwjr6z7qz1wn4ybgh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F1trfwjr6z7qz1wn4ybgh.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Undo Log Entries: Erasing Mistakes
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Analogy:
&lt;/h4&gt;

&lt;p&gt;You refer back to your packing list to see what items you haven't yet packed and need to remove. Similarly, in a database, undo log entries are used to find information to undo each change made by the transaction.&lt;/p&gt;

&lt;h4&gt;
  
  
  Technical Detail:
&lt;/h4&gt;

&lt;p&gt;The database uses the WAL to undo each change made by the transaction. For each operation recorded in the WAL, a corresponding undo operation is performed to revert the data to its previous state.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fqocea0zu69eq0ercdul2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fqocea0zu69eq0ercdul2.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Apply Undo Operations: Fixing Mistakes
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Analogy:
&lt;/h4&gt;

&lt;p&gt;You unpack the items you previously packed incorrectly, ensuring you're only taking what you need for the trip. In a database, undo operations are applied to in-memory data structures to reverse the changes made by the transaction.&lt;/p&gt;

&lt;h4&gt;
  
  
  Technical Detail:
&lt;/h4&gt;

&lt;p&gt;The database applies the undo operations to the in-memory data structures, effectively rolling back the changes. This ensures that the database is returned to its state prior to the start of the transaction.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fxsy37xueb9y30vx694mk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fxsy37xueb9y30vx694mk.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Log Rollback: Recording the Change of Plans
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Analogy:
&lt;/h4&gt;

&lt;p&gt;You make a note in your travel log that you've decided not to proceed with the trip, keeping a record of the change in plans. Similarly, in a database, a rollback log entry indicates that the transaction was rolled back.&lt;/p&gt;

&lt;h4&gt;
  
  
  Technical Detail:
&lt;/h4&gt;

&lt;p&gt;A rollback log entry may be written to indicate that the transaction has been rolled back. This helps in maintaining an accurate log for recovery purposes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F3ms6otvcs0fo50vu8vie.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F3ms6otvcs0fo50vu8vie.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Release Locks: Freeing Resources
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Analogy:
&lt;/h4&gt;

&lt;p&gt;Any reservations or bookings you made for the trip are canceled, freeing up resources for others to use. In a database, releasing locks ensures that other transactions can access the database and make changes without any problems.&lt;/p&gt;

&lt;h4&gt;
  
  
  Technical Detail:
&lt;/h4&gt;

&lt;p&gt;Any locks held by the transaction on database objects are released. This allows other transactions to access these objects and proceed with their operations.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fjtytzubjicdnglqtm946.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fjtytzubjicdnglqtm946.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion:
&lt;/h3&gt;

&lt;p&gt;In the domain of databases, transactions are like well-planned voyages. Just as you prepare for a trip by packing your essentials and mapping out your route, databases begin transactions by organizing the changes they need to make.&lt;/p&gt;

&lt;p&gt;During transaction’s journey, data changes are logged so that nothing gets lost along the way. For example, this log acts as a safety net for databases helping them in recovering after something unexpected happens.&lt;/p&gt;

&lt;p&gt;When it is time for a transaction to be committed, it’s just like finalizing plans and making them official. The database ensures all changes are securely saved.&lt;/p&gt;

&lt;p&gt;However, if there is an error and a rollback is required it’s just like changing your mind about taking a journey after all. The database cancels out any modifications made by the transaction and restores everything back to how it was before.&lt;/p&gt;

&lt;p&gt;Releasing locks at the end of a transaction is like canceling reservations freeing up resources for others to use.&lt;/p&gt;

&lt;p&gt;Understanding these processes will help you maintain smooth running of your database systems, reliable data, consistent operations. Whether using apps or shopping online or managing finances those background processes matter which can keep thing running smoothly. Thus next time you communicate with a data base remember committing and rolling back- ensuring you&lt;/p&gt;

</description>
      <category>mysql</category>
      <category>commit</category>
      <category>rollback</category>
      <category>database</category>
    </item>
    <item>
      <title>A Thorough Guide to Redis Data Persistence: Mastering AOF and RDB Configuration</title>
      <dc:creator>Md. Asif Rahman</dc:creator>
      <pubDate>Mon, 15 Apr 2024 06:15:18 +0000</pubDate>
      <link>https://dev.to/asifzcpe/a-thorough-guide-to-redis-data-persistence-mastering-aof-and-rdb-configuration-a3f</link>
      <guid>https://dev.to/asifzcpe/a-thorough-guide-to-redis-data-persistence-mastering-aof-and-rdb-configuration-a3f</guid>
      <description>&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;Redis is a highly efficient, in-memory data structure store that delivers exceptional performance and throughput. However, as an in-memory database, it faces the potential risk of data loss in the event of unexpected server shutdowns. To get rid of this issue, Redis offers two built-in persistence mechanisms: &lt;code&gt;Append Only File (AOF)&lt;/code&gt; and &lt;code&gt;Redis Database file (RDB)&lt;/code&gt;. This article will help you navigate the ins and outs of configuring AOF and RDB for optimal data durability, performance, and reliability.&lt;/p&gt;

&lt;h3&gt;
  
  
  Redis Persistence: A Closer Look
&lt;/h3&gt;

&lt;p&gt;AOF and RDB are complementary persistence methods with different strengths and trade-offs:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. AOF Persistence:&lt;/strong&gt; AOF maintains a log of every write operation performed on the Redis server and uses this log to reconstruct the dataset upon server restart. It's well-suited for applications requiring minimal data loss, as AOF can be fine-tuned to minimize potential data loss.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. RDB Persistence:&lt;/strong&gt; RDB generates periodic snapshots of your Redis dataset or based on specific conditions. With its faster operation, RDB is suitable for applications where occasional data loss is acceptable.&lt;/p&gt;

&lt;h3&gt;
  
  
  Setting Up AOF Persistence
&lt;/h3&gt;

&lt;p&gt;Configure AOF persistence using the following steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Open the Redis configuration file &lt;code&gt;(redis.conf)&lt;/code&gt; with a text editor.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Search for the &lt;code&gt;appendonly&lt;/code&gt; directive.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Set appendonly to &lt;code&gt;yes&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;appendonly &lt;span class="nb"&gt;yes&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;4.Specify a file path for the AOF file using &lt;code&gt;appendfilename&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;appendfilename &lt;span class="s2"&gt;"appendonly.aof"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;5.Optionally, set &lt;code&gt;appendfsync&lt;/code&gt; to control how often the AOF file is synced to disk (always, everysec, or no):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;appendfsync everysec
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;6.Save the changes and exit the text editor.&lt;/p&gt;

&lt;h3&gt;
  
  
  Configuring RDB Persistence
&lt;/h3&gt;

&lt;p&gt;Enable RDB persistence by modifying the redis.conf file as follows:&lt;br&gt;
1.Find the &lt;code&gt;save&lt;/code&gt; directive in &lt;code&gt;redis.conf&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;2.Set the desired conditions for RDB snapshots. For instance, to save the dataset every 15 minutes if at least 1 key has been changed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;save 900 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3.Add additional save directives for other conditions, such as &lt;code&gt;save 300 10&lt;/code&gt;. It tells redis server to create a snapshot if at least 10 modifications (writes or deletions) have occurred within 300 seconds (5 minutes):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;save 900 1
save 300 10
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;4.Save the changes and exit the text editor.&lt;/p&gt;

&lt;p&gt;After updating &lt;code&gt;redis.conf&lt;/code&gt;, restart the Redis server for the new settings to take effect.&lt;/p&gt;

&lt;h3&gt;
  
  
  Optimizing Performance and Durability
&lt;/h3&gt;

&lt;p&gt;Redis allows you to simultaneously utilize AOF and RDB persistence for increased data durability. This combination can minimize data loss by employing AOF for write operations and RDB for accelerating recovery times. Fine-tune AOF's appendfsync and RDB's save directives to achieve a balance between performance and durability.&lt;/p&gt;

&lt;h3&gt;
  
  
  Monitoring and Backup Strategies
&lt;/h3&gt;

&lt;p&gt;Regularly monitor Redis' performance and disk usage to ensure persistence mechanisms function optimally. Additionally, consider implementing periodic external backups as an extra precautionary measure to enhance data safety.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Configuring AOF and RDB persistence in Redis is essential to ensure data integrity and reliability. This comprehensive guide offers the knowledge and best practices needed for a high-performing Redis deployment. By fine-tuning persistence settings, monitoring performance, and implementing backup strategies, you can create a secure and efficient Redis environment.&lt;/p&gt;

</description>
      <category>redis</category>
      <category>redisscaling</category>
      <category>redispersistence</category>
      <category>config</category>
    </item>
    <item>
      <title>The JavaScript Riddle: Cracking the Code of typeof null</title>
      <dc:creator>Md. Asif Rahman</dc:creator>
      <pubDate>Mon, 13 Nov 2023 17:21:16 +0000</pubDate>
      <link>https://dev.to/asifzcpe/the-javascript-riddle-cracking-the-code-of-typeof-null-512i</link>
      <guid>https://dev.to/asifzcpe/the-javascript-riddle-cracking-the-code-of-typeof-null-512i</guid>
      <description>&lt;h1&gt;
  
  
  Introduction:
&lt;/h1&gt;

&lt;p&gt;JavaScript, a language known for its versatility, has a little surprise that can puzzle developers. It has to do with the &lt;code&gt;typeof&lt;/code&gt; operator when used with the value &lt;code&gt;null&lt;/code&gt;. Oddly, instead of saying &lt;code&gt;null&lt;/code&gt;, it says &lt;code&gt;object&lt;/code&gt;. In this article, we'll dig into why this happens, where it came from, and how developers can deal with this unexpected twist.&lt;/p&gt;

&lt;h1&gt;
  
  
  Historical Context:
&lt;/h1&gt;

&lt;p&gt;In the early days of JavaScript, the language was crafted with a simple set of types: "undefined," "boolean," "number," "string," "object," and "function." When the null value was introduced to represent the intentional absence of any object or primitive value, a small design mistake (or perhaps a necessity at that time) occurred. Consequently, when using typeof with null, instead of identifying it as null, it mistakenly reports "object" due to this historical design hiccup.&lt;/p&gt;

&lt;p&gt;Despite recognizing this as a mistake, correcting it poses challenges. JavaScript has a commitment to maintaining backward compatibility, and altering the behavior of typeof null might break existing code that relies on this historical quirk. So, developers are encouraged to be aware of this behavior and use other means, such as strict equality (===), to accurately check for null values. This reflects the evolution of the language and the complexities that can arise from decisions made in its early development stages.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;According to the ECMAScript specification (the rules that govern JavaScript), null is officially defined as the special value that represents the deliberate absence of any object (you can find this in ECMA-262, section 11.4.3).&lt;br&gt;
&lt;a href="https://262.ecma-international.org/5.1/#sec-11.4.3"&gt;ECMA-262 - section 11.4.3&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Let's inspect what the NULL actually is:
&lt;/h1&gt;

&lt;p&gt;Even though the result of &lt;code&gt;typeof null&lt;/code&gt; might seem odd, it's crucial to know that &lt;code&gt;null&lt;/code&gt; isn't really an object like other things in JavaScript. It's a basic value, a special one that shows there's no specific object available. So, despite what &lt;code&gt;typeof&lt;/code&gt; might say, null is more like a simple placeholder for the absence of an object.&lt;/p&gt;

&lt;h3&gt;
  
  
  Have a look at the below code snippets:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// Outputs: "object"&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// Outputs: false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;instanceof&lt;/code&gt; operator, commonly used for determining an object's type, reveals that null is not an instance of the Object constructor.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion:
&lt;/h1&gt;

&lt;p&gt;Let's sum it up in simpler terms. The odd behavior we observed is like a peculiar artifact from JavaScript's past. Don't let it throw you off! Think of it as a little surprise left by the language's creators.&lt;/p&gt;

&lt;p&gt;So, how do you handle it? Well, just use a trick you probably already know: strict equality. Instead of relying on typeof, stick with === when you want to check if something is null. It's like saying, "Hey, are you exactly null? No funny business!"&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>typeofnull</category>
      <category>javascriptmystery</category>
      <category>codequirk</category>
    </item>
    <item>
      <title>A real life example of using Late Static Binding in PHP.</title>
      <dc:creator>Md. Asif Rahman</dc:creator>
      <pubDate>Wed, 27 Sep 2023 08:42:06 +0000</pubDate>
      <link>https://dev.to/asifzcpe/a-real-life-example-of-using-late-static-binding-in-php-h6b</link>
      <guid>https://dev.to/asifzcpe/a-real-life-example-of-using-late-static-binding-in-php-h6b</guid>
      <description>&lt;h2&gt;
  
  
  Introduction:
&lt;/h2&gt;

&lt;p&gt;In the world of software development, creating flexible and dynamic systems is most important. One essential feature of a dynamic system is the ability for subclasses to override and customize functionality inherited from a base class. In PHP, Late Static Binding is a powerful feature that enables this flexibility, allowing subclasses to access their own static properties and methods, even when called through the base class. In this article, we will explore the concept of Late Static Binding through a practical example of a dynamic database query system.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding Late Static Binding:
&lt;/h2&gt;

&lt;p&gt;Late Static Binding (LSB) is a feature in PHP that allows a child class to reference its parent class's static properties or methods using the static keyword. This feature opens the door to dynamic behavior within your classes. It's especially useful when dealing with inheritance and customization of functionality in subclasses.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Scenario:
&lt;/h2&gt;

&lt;p&gt;Consider a scenario where you are developing a web application with a database. You have a base Database class that contains common functionality for interacting with the database, such as querying and data retrieval. Additionally, you have two subclasses, User and Product, each representing a different entity in your application. These subclasses need to perform database queries specific to their respective tables.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementing Late Static Binding:
&lt;/h2&gt;

&lt;p&gt;Let's dive into the code to see how Late Static Binding can help us achieve dynamic database queries:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Database&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="nv"&gt;$tableName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;getTableName&lt;/span&gt;&lt;span class="p"&gt;()&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;static&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nv"&gt;$tableName&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$tableName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;getTableName&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;"SELECT * FROM &lt;/span&gt;&lt;span class="nv"&gt;$tableName&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;User&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Database&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="nv"&gt;$tableName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'users'&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;Product&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Database&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="nv"&gt;$tableName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'products'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;//Example usage:&lt;/span&gt;
&lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Outputs: SELECT * FROM users&lt;/span&gt;
&lt;span class="nc"&gt;Product&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Outputs: SELECT * FROM products&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Explanation:
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;In the Database class, we define a static property $tableName, which represents the name of the database table.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The getTableName() method returns the table name using Late Static Binding with static::$tableName.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The query() method constructs and returns a query string that includes the specific table name obtained using static::getTableName()&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;Late Static Binding in PHP is a powerful tool that allows developers to create flexible and dynamic systems. In the example provided, we demonstrated how to use Late Static Binding to implement dynamic database queries in a web application. This feature empowers subclasses to access their own static properties and methods while maintaining a clear and organized class hierarchy. Incorporating Late Static Binding in your PHP applications can greatly enhance their flexibility and maintainability, ultimately leading to more robust and adaptable codebases.&lt;/p&gt;

</description>
      <category>php</category>
      <category>latestaticbinding</category>
      <category>static</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>When to use Repository and Service layer and when NOT</title>
      <dc:creator>Md. Asif Rahman</dc:creator>
      <pubDate>Wed, 27 Sep 2023 07:50:33 +0000</pubDate>
      <link>https://dev.to/asifzcpe/when-to-use-repository-and-service-layer-and-when-not-2d54</link>
      <guid>https://dev.to/asifzcpe/when-to-use-repository-and-service-layer-and-when-not-2d54</guid>
      <description>&lt;p&gt;Are you building RESTful APIs and wondering when to leverage the repository and service layer? Let's dive into this topic!&lt;/p&gt;

&lt;p&gt;🔍 Repository Layer: The repository layer acts as an intermediary between your API and the data storage mechanism. It handles data access operations like retrieval, creation, updating, and deletion. It ensures code modularity and provides a consistent interface. &lt;/p&gt;

&lt;p&gt;💡 Service Layer: The service layer implements the core business logic of your API. It coordinates different components and enforces business rules, workflows, and data integrity. It also handles authentication and authorization. #BusinessLogic&lt;/p&gt;

&lt;p&gt;🚫 When to Avoid Repository and Service Layers:&lt;/p&gt;

&lt;p&gt;✅ Lightweight Operations: Simple CRUD operations can be handled directly in your API endpoints or controllers to keep things simple. &lt;/p&gt;

&lt;p&gt;✅ External Integrations: Directly make API calls without introducing layers unless there are complex rules or transformations involved.&lt;/p&gt;

&lt;p&gt;✅ Middleware: Implement middleware functions without the layers if they don't require complex data access or business logic.&lt;/p&gt;

&lt;p&gt;🔎 When to Use Repository and Service Layers:&lt;/p&gt;

&lt;p&gt;✅ Complex Business Logic: Use the service layer for intricate business rules, validations, and workflows beyond basic CRUD. #ComplexLogic&lt;/p&gt;

&lt;p&gt;✅ Modularity and Reusability: Layers promote code modularity and reuse. Encapsulate common data access or operations within repositories for consistency.&lt;/p&gt;

&lt;p&gt;✅ Unit Testing: Separate concerns aid unit testing. Mock the repository layer for focused, granular tests of service layer logic. #UnitTesting&lt;/p&gt;

&lt;p&gt;Strike a balance between code organization, maintainability, and performance in your REST API projects. Happy coding! 😄🚀&lt;/p&gt;

</description>
      <category>restapi</category>
      <category>codestructure</category>
      <category>bestpractices</category>
      <category>repositoryvsservice</category>
    </item>
    <item>
      <title>Implementing Payment Gateways with the Liskov Substitution Principle</title>
      <dc:creator>Md. Asif Rahman</dc:creator>
      <pubDate>Fri, 15 Sep 2023 12:40:07 +0000</pubDate>
      <link>https://dev.to/asifzcpe/empowering-your-laravel-application-mastering-payment-gateways-with-the-liskov-substitution-principle-30pg</link>
      <guid>https://dev.to/asifzcpe/empowering-your-laravel-application-mastering-payment-gateways-with-the-liskov-substitution-principle-30pg</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In Laravel, integrating payment gateways while maintaining clean, maintainable, and extensible code can be simplified by applying the Liskov Substitution Principle (LSP), one of the SOLID principles of Object-Oriented Programming (OOP).&lt;/p&gt;

&lt;p&gt;LSP suggests that objects of a derived class should be able to replace objects of the base class without affecting the correctness of the program. In the context of Laravel payment gateway integration, you can achieve this by creating a common interface or abstract class for all payment gateways. This ensures that different payment gateways can be easily swapped in and out without disrupting the core functionality of your application.&lt;/p&gt;

&lt;p&gt;So, did you get anything? &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fz3xb9ac0u4sak742d43y.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fz3xb9ac0u4sak742d43y.gif" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ok, No problem. &lt;br&gt;
Let's do it practically. I am using Laravel here but concept is the same for other languages and frameworks.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Scenario: Processing Payments
&lt;/h2&gt;

&lt;p&gt;Imagine you are building an e-commerce platform, and you need to support multiple payment gateways, such as credit card payments and PayPal. You want to ensure that you can seamlessly switch between these gateways without making extensive changes to your codebase.&lt;/p&gt;

&lt;h3&gt;
  
  
  Folder Structure:
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fwgojnsb86witb4ha726p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fwgojnsb86witb4ha726p.png" alt="Image description"&gt;&lt;/a&gt;&lt;br&gt;
Note: You can follow any folder structure as per your need&lt;/p&gt;

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

&lt;h3&gt;
  
  
  1. Create a Base PaymentGateway Class
&lt;/h3&gt;

&lt;p&gt;Start by creating a base PaymentGateway class that defines the common payment processing logic:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;

&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;App\Components\PaymentGateways&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;PaymentGateway&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;processPayment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Common payment processing logic&lt;/span&gt;
        &lt;span class="nv"&gt;$transactionId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;generateTransactionId&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;logPayment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$transactionId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$amount&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;"Processed a payment of $$amount with Transaction ID: &lt;/span&gt;&lt;span class="nv"&gt;$transactionId&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="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;generateTransactionId&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Generate a unique transaction ID&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;uniqid&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;logPayment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$transactionId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Log payment details&lt;/span&gt;
        &lt;span class="c1"&gt;// Example: Log to a database or external service&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;In base PaymentGateway class, we have added common payment processing logic, including generating a unique transaction ID and logging payment details. This common logic will be shared by all payment gateway subclasses.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Implement Subclasses for Payment Gateways
&lt;/h3&gt;

&lt;p&gt;The subclasses are CreditCardPaymentGateway and PaypalPaymentGateway.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CreditCardPaymentGateway Class:&lt;/strong&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;

&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;App\Components\PaymentGateways&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;App\Components\PaymentGateways\PaymentGateway&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;CreditCardPaymentGateway&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;PaymentGateway&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;processPayment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Credit card payment specific logic&lt;/span&gt;
        &lt;span class="nv"&gt;$creditCardFee&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;calculateCreditCardFee&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$amount&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Call the parent class's processPayment method to execute common logic&lt;/span&gt;
        &lt;span class="nv"&gt;$result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;parent&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;processPayment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$amount&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nv"&gt;$creditCardFee&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Additional credit card specific logic can be added here if necessary&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;calculateCreditCardFee&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Calculate and return credit card processing fee&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$amount&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.03&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// 3% fee as an example&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;In this code, we've defined the CreditCardPaymentGateway class, which serves as a specialized payment gateway for handling credit card payments within our Laravel application. It inherits from the PaymentGateway base class, which likely encapsulates shared payment processing functionality.&lt;/p&gt;

&lt;p&gt;The primary function within this class is the processPayment($amount) method. Here, we introduce credit card-specific processing logic. Notably, it calculates a credit card processing fee by invoking the calculateCreditCardFee($amount) method. In this example, we've applied a 3% fee rate for illustrative purposes.&lt;/p&gt;

&lt;p&gt;Additionally, the CreditCardPaymentGateway class adheres to the Liskov Substitution Principle (LSP) by calling the processPayment method of the parent class (PaymentGateway). This ensures that any common payment processing logic, such as logging or transaction tracking, from the base class is also executed.&lt;/p&gt;

&lt;p&gt;Let's create another subclass called PaypalPaymentGateway&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PayPalPaymentGateway Class:&lt;/strong&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;

&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;App\Components\PaymentGateways&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;App\Components\PaymentGateways\PaymentGateway&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;PaypalPaymentGateway&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;PaymentGateway&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;processPayment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// PayPal payment specific logic&lt;/span&gt;
        &lt;span class="nv"&gt;$paypalFee&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;calculatePayPalFee&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$amount&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Call the parent class's processPayment method to execute common logic&lt;/span&gt;
        &lt;span class="nv"&gt;$result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;parent&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;processPayment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$amount&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nv"&gt;$paypalFee&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Additional PayPal specific logic can be added here if necessary&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;calculatePayPalFee&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Calculate and return PayPal processing fee&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$amount&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.02&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// 2% fee as an example&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;Similarly, we've implemented the PayPalPaymentGateway class to manage PayPal payments within our Laravel application. This class extends the PaymentGateway base class to leverage shared payment processing capabilities.&lt;/p&gt;

&lt;p&gt;The focal point of this class is the processPayment($amount) method, where we've incorporated PayPal-specific processing steps. It calculates the PayPal processing fee by making use of the calculatePayPalFee($amount) method, which assumes a 2% fee rate as an example.&lt;/p&gt;

&lt;p&gt;Just like the CreditCardPaymentGateway, the PayPalPaymentGateway class adheres to the Liskov Substitution Principle (LSP) by invoking the processPayment method of the parent class (PaymentGateway). This ensures that common payment processing logic shared across various payment gateways is consistently executed.&lt;/p&gt;

&lt;p&gt;These two classes provide a structured and extensible approach for integrating different payment gateways into our Laravel application, promoting code maintainability and ease of use.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Configure the payment gateways in Laravel's route service provider as we pass gateway name from url.
&lt;/h3&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;

&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;App\Providers&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Illuminate\Cache\RateLimiting\Limit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Illuminate\Foundation\Support\Providers\RouteServiceProvider&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nc"&gt;ServiceProvider&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Illuminate\Http\Request&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Illuminate\Support\Facades\RateLimiter&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Illuminate\Support\Facades\Route&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Illuminate\Support\Str&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;RouteServiceProvider&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;ServiceProvider&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="cd"&gt;/**
     * The path to your application's "home" route.
     *
     * Typically, users are redirected here after authentication.
     *
     * @var string
     */&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="no"&gt;HOME&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'/home'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="cd"&gt;/**
     * Define your route model bindings, pattern filters, and other route configuration.
     */&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;boot&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;

        &lt;span class="nc"&gt;RateLimiter&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'api'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Request&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;Limit&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;perMinute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;by&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;user&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;?-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;?:&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;

        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;Route&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;middleware&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'api'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;prefix&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'api'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;group&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;base_path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'routes/api.php'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

            &lt;span class="nc"&gt;Route&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;middleware&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'web'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;group&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;base_path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'routes/web.php'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;

        &lt;span class="c1"&gt;//Here is the logic to bind route params to respective class to intentiate gateway classes&lt;/span&gt;

        &lt;span class="nc"&gt;Route&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'gateway'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$gateway&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Define the namespace where your payment gateway classes reside.&lt;/span&gt;
            &lt;span class="nv"&gt;$namespace&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'App\\Components\\PaymentGateways\\'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

            &lt;span class="c1"&gt;// Create the fully qualified class name based on the route parameter.&lt;/span&gt;
            &lt;span class="nv"&gt;$className&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$namespace&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="nc"&gt;Str&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;studly&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$gateway&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="s1"&gt;'PaymentGateway'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

            &lt;span class="c1"&gt;// Check if the class exists.&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;class_exists&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$className&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="c1"&gt;// Instantiate the class dynamically.&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;app&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;make&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$className&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="c1"&gt;// Handle the case when the provided $gateway parameter does not correspond to a valid class.&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;abort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;404&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Or any other appropriate action.&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;h3&gt;
  
  
  Step 4: Create a route to handle the payment
&lt;/h3&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;

&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Illuminate\Support\Facades\Route&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;App\Http\Controllers\CheckoutController&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nc"&gt;Route&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;view&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'welcome'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nc"&gt;Route&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/checkout/{gateway}'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nc"&gt;CheckoutController&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'processPayment'&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;



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

&lt;/div&gt;
&lt;h3&gt;
  
  
  Step 5: Create a CheckoutController to process the payment.
&lt;/h3&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;

&lt;span class="c1"&gt;// app/Http/Controllers/CheckoutController.php&lt;/span&gt;
&lt;span class="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;App\Http\Controllers&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Illuminate\Http\Request&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;App\PaymentGateway&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;CheckoutController&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Controller&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;processPayment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Request&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;PaymentGateway&lt;/span&gt; &lt;span class="nv"&gt;$gateway&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Common checkout logic&lt;/span&gt;

        &lt;span class="nv"&gt;$amount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Example amount&lt;/span&gt;

        &lt;span class="c1"&gt;// Process payment using the provided gateway&lt;/span&gt;
        &lt;span class="nv"&gt;$result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$gateway&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;processPayment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$amount&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;view&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'checkout'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'result'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$result&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;h3&gt;
  
  
  Step 6: Create a view file just to see the result
&lt;/h3&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

&amp;lt;!-- resources/views/checkout.blade.php --&amp;gt;
&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;title&amp;gt;Checkout Result&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
    &amp;lt;h1&amp;gt;Payment Result&amp;lt;/h1&amp;gt;
    &amp;lt;p&amp;gt;{{ $result }}&amp;lt;/p&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;


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

&lt;/div&gt;

&lt;p&gt;With this code, you can now make payments using different gateways by specifying the gateway in the URL. For example, /checkout/credit-card or /checkout/paypal. The controller will use the appropriate payment gateway without needing to change the controller's code, demonstrating the Liskov Substitution Principle.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;In this practical guide, we've demonstrated how to integrate payment gateways into a Laravel application while adhering to the principles of Object-Oriented Programming (OOP), specifically the Liskov Substitution Principle (LSP). By following these steps, you can maintain clean, maintainable, and extensible code for handling payments in your e-commerce platform.&lt;/p&gt;

&lt;h3&gt;
  
  
  Summary of Achievements
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1. Created a Base PaymentGateway Class:&lt;/strong&gt; We established a &lt;code&gt;PaymentGateway&lt;/code&gt; base class containing common payment processing logic, such as generating transaction IDs and logging payment details. This base class acts as a blueprint for all payment gateway implementations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Implemented Subclasses for Payment Gateways:&lt;/strong&gt; We developed two specialized payment gateway subclasses, &lt;code&gt;CreditCardPaymentGateway&lt;/code&gt; and &lt;code&gt;PayPalPaymentGateway&lt;/code&gt;. These subclasses extend the &lt;code&gt;PaymentGateway&lt;/code&gt; base class and provide payment-specific logic while preserving the ability to replace one gateway with another seamlessly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Configured Payment Gateways:&lt;/strong&gt; Laravel's service provider was utilized to bind instances of the payment gateway classes. This setup allows for easy switching between payment gateways by changing configuration settings.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Created a Route and Controller:&lt;/strong&gt; We defined a route that accepts the selected payment gateway as a parameter and a controller that handles the payment processing. The controller utilizes the selected payment gateway instance to process payments.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Developed a Checkout View:&lt;/strong&gt; A simple view was created to display the payment processing result to the user.&lt;/p&gt;

&lt;p&gt;By applying the Liskov Substitution Principle and following these steps, your Laravel application can accommodate various payment gateways without extensive code changes, enhancing code maintainability, extensibility, and flexibility in handling payments for your e-commerce platform. This approach simplifies the integration of new payment gateways in the future, ensuring a smooth payment processing experience for your users.&lt;/p&gt;

&lt;p&gt;Now, you have a solid foundation to expand your payment processing capabilities and adapt to changing payment methods or providers as your business needs evolve.&lt;/p&gt;

&lt;p&gt;Here is the code &lt;a href="https://github.com/asifzcpe/laravel-solid-principles" rel="noopener noreferrer"&gt;https://github.com/asifzcpe/laravel-solid-principles&lt;/a&gt;&lt;/p&gt;

</description>
      <category>liskov</category>
      <category>lsp</category>
      <category>liskovsubstitutionprinciple</category>
      <category>solid</category>
    </item>
    <item>
      <title>Resetting MySQL Root Password in Ubuntu: A Step-by-Step Guide</title>
      <dc:creator>Md. Asif Rahman</dc:creator>
      <pubDate>Tue, 25 Jul 2023 22:14:18 +0000</pubDate>
      <link>https://dev.to/asifzcpe/resetting-mysql-root-password-in-ubuntu-a-step-by-step-guide-3gnd</link>
      <guid>https://dev.to/asifzcpe/resetting-mysql-root-password-in-ubuntu-a-step-by-step-guide-3gnd</guid>
      <description>&lt;p&gt;&lt;strong&gt;&lt;em&gt;Introduction:&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
Losing or forgetting the MySQL root password can be a stressful situation, but don't worry; there's a way to regain access to your MySQL database in Ubuntu. In this article, I will walk you through a step-by-step guide on how to reset the MySQL root password on your Ubuntu system. We will use a method that involves stopping the MySQL service, creating a temporary configuration file, and setting a new password for the root user.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Stop the MySQL Service&lt;/strong&gt;&lt;br&gt;
The first step is to stop the MySQL service to ensure we can safely proceed with the password reset process. Open your terminal and run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo service mysql stop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 2: Create a Temporary Configuration File&lt;/strong&gt;&lt;br&gt;
Next, we'll create a temporary configuration file to start the MySQL service without password authentication. This will allow us to reset the root password. Run the following command to create the file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo nano /etc/mysql/mysql.conf.d/reset-mysql-password.cnf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 3: Add Configuration to the File&lt;/strong&gt;&lt;br&gt;
In the nano editor, add the following lines to the reset-mysql-password.cnf file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[mysqld]
skip-grant-tables
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To save the changes and exit the editor, press CTRL + X, then type Y, and finally, press Enter.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4: Start MySQL Service in Safe Mode&lt;/strong&gt;&lt;br&gt;
With the temporary configuration file in place, start the MySQL service in safe mode:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo mysqld_safe --skip-grant-tables &amp;amp;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Step 5: Connect to MySQL Without Password&lt;/em&gt;&lt;br&gt;
Now, we can connect to the MySQL server without entering a password. Open a new terminal window and run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mysql -u root

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 6: Set a New Password for Root User&lt;/strong&gt;&lt;br&gt;
Once you are connected to the MySQL prompt, it's time to set a new password for the root user. Execute the following SQL commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FLUSH PRIVILEGES;
ALTER USER 'root'@'localhost' IDENTIFIED BY 'YOUR_NEW_PASSWORD';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace 'YOUR_NEW_PASSWORD' with your desired password. The FLUSH PRIVILEGES; command ensures that the changes take effect immediately.&lt;/p&gt;

&lt;p&gt;If you get the following error while using weak password&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ERROR 1819 (HY000): Your password does not satisfy the current policy requirements
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can fix this like below, if you want to use weak password(Not recommended)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SHOW VARIABLES LIKE 'validate_password%';
SET GLOBAL validate_password.policy=LOW;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now again run the password update sql:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 7: Exit MySQL and Remove the Configuration File&lt;/strong&gt;&lt;br&gt;
After setting the new password, exit the MySQL prompt:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;exit;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Remove the temporary configuration file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo rm /etc/mysql/mysql.conf.d/reset-mysql-password.cnf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 8: Restart MySQL Service&lt;/strong&gt;&lt;br&gt;
Finally, restart the MySQL service to apply the changes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo service mysql restart
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Congratulations! You have successfully reset the MySQL root password on your Ubuntu system. Now you can access your MySQL database using the new password you set. Always make sure to keep your MySQL root password secure .&lt;/p&gt;

</description>
      <category>mysqlpasswordreset</category>
      <category>mysql</category>
      <category>ubuntu</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Choosing Between Static and Non-Static Methods in PHP: Real-World Use Cases and Code Examples</title>
      <dc:creator>Md. Asif Rahman</dc:creator>
      <pubDate>Fri, 07 Jul 2023 19:18:52 +0000</pubDate>
      <link>https://dev.to/asifzcpe/choosing-between-static-and-non-static-methods-in-php-real-world-use-cases-and-code-examples-1gi2</link>
      <guid>https://dev.to/asifzcpe/choosing-between-static-and-non-static-methods-in-php-real-world-use-cases-and-code-examples-1gi2</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In PHP development, selecting between static and non-static methods holds significant importance when it comes to code organization and functionality. Both approaches provide unique benefits and are applicable in different scenarios. This article aims to examine the utilization of static and non-static methods in PHP using practical illustrations. By comprehending the appropriate usage of each approach, you can design code that is more effective and easier to maintain.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scenarios to use static methods:
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Data validation utility:&lt;/strong&gt;&lt;br&gt;
Demonstrating a static method for email validation, which can be accessed without instantiating the class.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fzj7672bxg58g66cft05j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fzj7672bxg58g66cft05j.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Logging utility:&lt;/strong&gt;&lt;br&gt;
Implementing a static method to handle logging functionality for easy access throughout the application.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fictd6nkgy8nkdaij1mv4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fictd6nkgy8nkdaij1mv4.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Factory Methods:&lt;/strong&gt;&lt;br&gt;
Static methods can be used as factory methods to create instances of a class, encapsulating the object creation logic.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F1nyw9fr0upqxo2udtnwn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F1nyw9fr0upqxo2udtnwn.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Configuration Handling:&lt;/strong&gt;*&lt;br&gt;
Static methods can be useful for handling configuration settings or retrieving values from a configuration file.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fikt9lp013ia3888la4bq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fikt9lp013ia3888la4bq.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Scenarios to use non-static methods:
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Order Processing:&lt;/strong&gt;&lt;br&gt;
Illustrating a non-static method to add items to an order and process the order using instance-specific data.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fbrc59n7rs25kf8s1k21b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fbrc59n7rs25kf8s1k21b.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, now you may have a question here, something like - what would happen, if we used static methods here.&lt;br&gt;
Don't worry, here is the reason :&lt;/p&gt;

&lt;p&gt;If we were to use static methods in the Order class instead of non-static methods, several consequences would arise. Firstly, static methods do not have access to instance-specific data, such as the items array, as they operate at the class level rather than on individual objects. This would lead to shared data among all instances of the class, making it impossible to maintain separate order details. Secondly, encapsulation and re-usability would be compromised, as static methods cannot encapsulate functionality and data within specific instances, hindering code organization and modularity. Lastly, static methods lack the flexibility of dependency management, as they are not designed to handle dynamic dependencies, making it difficult to inject additional services or dependencies. &lt;/p&gt;

&lt;p&gt;In summary, using static methods would result in shared data, reduced encapsulation, limited re-usability, and inadequate dependency management within the Order class.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Database Connection Wrapper:&lt;/strong&gt;&lt;br&gt;
Creating a non-static method to establish a database connection and perform queries using the instance-specific connection.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fbwddyz3tt4bobdo3zfav.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fbwddyz3tt4bobdo3zfav.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So far, I have shown the example code for static and non-static methods separately. Now, it is turn to show an example code to use both static and non-static methods together:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fgnc3npa03fxkbvrrtn1f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fgnc3npa03fxkbvrrtn1f.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I hope, by this far, you have understood when to use static method and when not to use. &lt;/p&gt;

&lt;p&gt;I can share with you one more scenario that we have faced or face many times while writing code in for example, service classes. We need to think which methods in a service class will be static or non-static. So, here is a check list to identify if you need to write a method static or non-static:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use Non-Static Methods When:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Instance-Specific Data: When you need to access or modify data specific to each object instance.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Encapsulation and Reusability: When you want to encapsulate functionality and data within individual instances, promoting better code organization and modularity.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Independent Processing: When each object should be able to perform operations independently without affecting other instances.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Dependency Management: When you require the flexibility of injecting additional services or dependencies as constructor arguments or method parameters.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Use Static Methods When:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Class-Level Operations: When the functionality does not depend on or modify instance-specific data and can be performed at the class level.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Utility Functions: When the method provides common utility functions that do not rely on instance state.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Global Operations: When the functionality is applicable across multiple instances and does not require individual data.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;By taking these guidelines into consideration, you can make well-informed choices regarding the usage of static or non-static methods that align with the specific requirements of your PHP code.&lt;/p&gt;

</description>
      <category>static</category>
      <category>nonstatic</category>
      <category>php</category>
      <category>staticvsnonstaticmethodsinphp</category>
    </item>
    <item>
      <title>Enhancing Memory Efficiency in Ecommerce Applications with the Flyweight Pattern</title>
      <dc:creator>Md. Asif Rahman</dc:creator>
      <pubDate>Sun, 11 Jun 2023 20:45:31 +0000</pubDate>
      <link>https://dev.to/asifzcpe/enhancing-memory-efficiency-in-ecommerce-applications-with-the-flyweight-pattern-2aj5</link>
      <guid>https://dev.to/asifzcpe/enhancing-memory-efficiency-in-ecommerce-applications-with-the-flyweight-pattern-2aj5</guid>
      <description>&lt;p&gt;&lt;strong&gt;Introduction:&lt;/strong&gt;&lt;br&gt;
Efficient memory management is essential for building high-performing ecommerce applications that can handle large product catalogs and provide a seamless user experience. One powerful design pattern that can significantly improve memory efficiency is the Flyweight pattern. By leveraging this pattern, ecommerce applications can reduce memory consumption by sharing common data among similar objects. In this article, we will explore how the Flyweight pattern can be implemented in a real-world ecommerce application using code examples.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Understanding the Flyweight Pattern:&lt;/strong&gt;&lt;br&gt;
The Flyweight pattern is a structural design pattern that focuses on minimizing memory usage by sharing data between objects. It achieves this by splitting object state into intrinsic and extrinsic parts. The intrinsic state, which is shared among multiple objects, is stored externally and can be accessed by these objects. The extrinsic state, which is unique to each object, is stored separately. This separation eliminates the need to duplicate the intrinsic state, resulting in significant memory savings.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Flyweight Pattern in Ecommerce:&lt;/strong&gt;&lt;br&gt;
In an ecommerce application, product images are an integral part of the user experience. However, if multiple products share the same image, storing individual instances of the image for each product can lead to memory wastage. Let's consider a simplified example of an ecommerce product listing page to demonstrate the implementation of the Flyweight pattern.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Product&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nv"&gt;$name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nv"&gt;$price&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nv"&gt;$image&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$price&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$image&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;price&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$price&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$image&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Other methods...&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;display&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Product: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;, Price: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;, Image: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getUrl&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\n&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;Image&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nv"&gt;$url&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$url&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;getUrl&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;url&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;ImageFlyweightFactory&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nv"&gt;$images&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;getImage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$url&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="o"&gt;!&lt;/span&gt;&lt;span class="k"&gt;isset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;images&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;$url&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;images&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;$url&lt;/span&gt;&lt;span class="p"&gt;]&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;Image&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$url&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;images&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;$url&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="c1"&gt;// Client code&lt;/span&gt;
&lt;span class="nv"&gt;$imageFactory&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;ImageFlyweightFactory&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nv"&gt;$products&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;Product&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Product 1'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;19.99&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$imageFactory&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getImage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'product1.jpg'&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;Product&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Product 2'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;29.99&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$imageFactory&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getImage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'product1.jpg'&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;Product&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Product 3'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;39.99&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$imageFactory&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getImage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'product2.jpg'&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$products&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nv"&gt;$product&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$product&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;display&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;In this example, the Product class represents a product with attributes such as name, price, and an image. The Image class encapsulates the image data, and the &lt;strong&gt;ImageFlyweightFactory&lt;/strong&gt; acts as the flyweight factory, managing the creation and sharing of image instances.&lt;/p&gt;

&lt;p&gt;When creating product objects, we utilize the flyweight factory to retrieve image instances. If the image with a specific URL has not been created before, the factory creates a new instance and stores it for future use. If the image has already been created, the existing instance is retrieved and reused.&lt;/p&gt;

&lt;p&gt;By sharing image instances among products, the Flyweight pattern eliminates the need to duplicate image data, resulting in reduced memory consumption. The display() method in the Product class demonstrates how the shared image instance is used for displaying product information.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Benefits of Using the Flyweight Pattern in Ecommerce:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Memory Optimization:&lt;/em&gt;&lt;/strong&gt; The Flyweight pattern significantly reduces memory consumption by sharing common data among objects, leading to efficient memory usage, especially when dealing with large product catalogs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Improved Performance:&lt;/em&gt;&lt;/strong&gt; By eliminating redundant data storage and duplication, the Flyweight pattern enhances application performance, resulting in faster response times and a smoother user experience.&lt;/p&gt;

&lt;p&gt;Scalability: With reduced memory overhead, ecommerce applications can handle increased traffic and larger product catalogs without sacrificing performance or exhausting system resources.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion:&lt;/strong&gt;&lt;br&gt;
Efficient memory management is crucial for building high-performing ecommerce applications. The Flyweight pattern offers an elegant solution by minimizing memory consumption through the sharing of common data among objects. By implementing the Flyweight pattern in an ecommerce application, developers can optimize memory usage, improve performance, and provide a seamless shopping experience for users.&lt;/p&gt;

</description>
      <category>php</category>
      <category>designpatterns</category>
      <category>flyweight</category>
      <category>memoryefficinecy</category>
    </item>
    <item>
      <title>Crafting Custom Furniture and Seamless Database Queries: Unlocking the Power of the Builder Design Pattern</title>
      <dc:creator>Md. Asif Rahman</dc:creator>
      <pubDate>Thu, 25 May 2023 19:15:19 +0000</pubDate>
      <link>https://dev.to/asifzcpe/crafting-custom-furniture-and-seamless-database-queries-unlocking-the-power-of-the-builder-design-pattern-20f6</link>
      <guid>https://dev.to/asifzcpe/crafting-custom-furniture-and-seamless-database-queries-unlocking-the-power-of-the-builder-design-pattern-20f6</guid>
      <description>&lt;p&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;br&gt;
The Builder design pattern is a powerful tool in software development that facilitates the creation of complex objects in a step-by-step manner. While its application is often seen in software projects, the Builder pattern can also be applied to real-life scenarios, such as calculating the price of custom-made furniture. In this article, we will explore how the Builder pattern can simplify furniture price calculation by allowing customers to select different parts and configurations for their furniture pieces.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Understanding the Builder Design Pattern&lt;/strong&gt;&lt;br&gt;
The Builder design pattern is a creational pattern that separates the construction of an object from its representation. It allows the step-by-step creation of objects, where each step involves configuring different parts or aspects of the object. By utilizing method chaining, the Builder pattern provides an intuitive and readable way to construct complex objects.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Real-Life Example: Furniture Price Calculation&lt;/strong&gt;&lt;br&gt;
Imagine a furniture store that offers custom-made furniture, allowing customers to select different parts and configurations to build their ideal piece. Let's consider a furniture price calculator that applies the Builder pattern to calculate the price based on the selected parts. Here's an example implementation in JavaScript:&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Result:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wtAnkI8P--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6z9xepa1x8kpqjct9tka.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wtAnkI8P--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6z9xepa1x8kpqjct9tka.png" alt="Image description" width="800" height="687"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Explanation of the Code&lt;/strong&gt;&lt;br&gt;
In this example, we have a FurnitureBuilder class that represents the furniture price calculator. Here's a breakdown of the code:&lt;/p&gt;

&lt;p&gt;The FurnitureBuilder class has methods to add different parts of the furniture and update the price accordingly.&lt;/p&gt;

&lt;p&gt;addFrame(frame), addSeat(seat), and addBackrest(backrest) are methods to add the corresponding parts to the furniture.&lt;br&gt;
Each part object has properties such as type, material, or style to represent different configurations.&lt;/p&gt;

&lt;p&gt;The build() method returns an object with the selected parts and the total price of the furniture.&lt;br&gt;
By using the Builder pattern, customers can select the desired parts for their furniture, such as the frame, seat, and backrest, and the price calculator automatically updates the price based on the selections.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Let's see another real life example of builder design pattern&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Creating Query Builders for Database Interactions&lt;/strong&gt;&lt;br&gt;
The Builder pattern is also beneficial when constructing database queries dynamically. Let's explore an example using JavaScript and demonstrate the creation of a query builder for SQL database interactions:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CDQNFJdG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8et6vrgfcta68bvdbahs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CDQNFJdG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8et6vrgfcta68bvdbahs.png" alt="Image description" width="608" height="1065"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this example, the QueryBuilder class provides methods for constructing SQL queries step by step. Customers can specify the select fields, the table to query from, conditions for filtering, and the order of the results. The exec() method returns the final constructed query as a string. By utilizing the Builder pattern, the creation of dynamic and complex database queries becomes more readable and maintainable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The Builder design pattern offers flexibility and maintainability in various real-life scenarios. By applying the Builder pattern, customers can easily create custom furniture with different parts and configurations. Additionally, developers can construct dynamic database queries using query builders, simplifying the process of interacting with databases. Whether it's building physical objects or constructing software components, the Builder pattern provides an elegant solution for step-by-step construction and customization.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Improving Your E-Commerce Shipping Module Efficiency: A Guide to Dynamic Class Instantiation using the Strategy Pattern in PHP</title>
      <dc:creator>Md. Asif Rahman</dc:creator>
      <pubDate>Tue, 21 Mar 2023 16:18:19 +0000</pubDate>
      <link>https://dev.to/asifzcpe/improving-your-e-commerce-shipping-module-efficiency-a-guide-to-dynamic-class-instantiation-using-the-strategy-pattern-in-php-3hne</link>
      <guid>https://dev.to/asifzcpe/improving-your-e-commerce-shipping-module-efficiency-a-guide-to-dynamic-class-instantiation-using-the-strategy-pattern-in-php-3hne</guid>
      <description>&lt;p&gt;In e-commerce platforms, shipping is an important part of the overall business strategies. The shipping module of an e-commerce platform needs to be designed in a way that allows for flexibility in shipping methods and pricing. This is where the strategy pattern can be used. In this blog post, we'll explore the strategy pattern in PHP using the shipping module of an e-commerce platform as an example.&lt;/p&gt;

&lt;p&gt;Let's first try to understand what problems strategy design pattern solves.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Strategy Pattern&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The strategy pattern is a design pattern that allows you to define a family of algorithms, encapsulate each one, and make them interchangeable. This pattern lets the algorithm vary independently from the clients that use it. In other words, it allows you to interchange different algorithms without changing the code that uses them.&lt;/p&gt;

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

&lt;p&gt;The shipping module of an e-commerce platform is a perfect use case for the strategy pattern. There are many different ways to handle shipping, and each method has its own set of rules and calculations. By using the strategy pattern, you can define each shipping method as a separate algorithm, and the e-commerce platform can easily switch between them without changing the code that handles the shipping.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Implementing the Strategy Pattern in PHP&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To implement the strategy pattern in PHP, we'll need to create a few classes. First, we'll create an interface called ShippingStrategy. This interface will define the methods that all shipping strategies must implement.&lt;/p&gt;

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

&lt;p&gt;Next, we'll create a class for each shipping method that implements the ShippingStrategy interface. For example, we could create a class called StandardShipping that implements the ShippingStrategy interface and handles the logic for standard shipping.&lt;/p&gt;

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

&lt;p&gt;We may have another class for DomesticShipping and InternationalShipping that implements the ShippingStrategy interface and handles the logic for standard shipping.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;DomesticShipping Class&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7qr-frKF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/da6brupn49lp3v0nrt0r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7qr-frKF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/da6brupn49lp3v0nrt0r.png" alt="Image description" width="800" height="552"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;InternationalShipping Class&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uIrUm5GL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n8875myneo7o3kcil3wj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uIrUm5GL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n8875myneo7o3kcil3wj.png" alt="Image description" width="800" height="552"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, we will class a Shipping class that will calculate the shipping cost and estimated delivery date on the basis of the shipping type provided via its __construct() method.&lt;/p&gt;

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

&lt;p&gt;In above image, the "Shipping" class represents a shipping service that calculates the shipping cost and estimates the delivery date based on the chosen shipping type. It uses the strategy pattern to dynamically select the appropriate shipping strategy based on the given shipping type, and delegates the calculation of the shipping cost and estimated delivery date to the selected strategy object.&lt;/p&gt;

&lt;p&gt;Let's see how to use this class.&lt;/p&gt;

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

&lt;p&gt;Here, we are passing $shippingType that can be of any type/strategy that we have implemented. &lt;/p&gt;

&lt;p&gt;Here, you can find the github repo link to understand it in better way.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/asifzcpe/desing-patterns/tree/main/strategy-pattern"&gt;Gihub Repo&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
