<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>SOLID &#8211; Web Development &amp; Digital Marketing Agency </title>
	<atom:link href="https://keytech.dev/blog/tag/solid/feed/" rel="self" type="application/rss+xml" />
	<link>https://keytech.dev</link>
	<description>KeyTech </description>
	<lastBuildDate>Fri, 04 Aug 2023 18:28:05 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9</generator>

<image>
	<url>https://keytech.dev/wp-content/uploads/2023/07/cropped-logo-32x32.png</url>
	<title>SOLID &#8211; Web Development &amp; Digital Marketing Agency </title>
	<link>https://keytech.dev</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Implementing the SOLID Principles in Laravel: A Comprehensive Example</title>
		<link>https://keytech.dev/blog/implementing-the-solid-principles-in-laravel-a-comprehensive-example/</link>
		
		<dc:creator><![CDATA[KeyTech Developer]]></dc:creator>
		<pubDate>Fri, 04 Aug 2023 18:17:41 +0000</pubDate>
				<category><![CDATA[Laravel]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[SOLID]]></category>
		<guid isPermaLink="false">https://darkgrey-chimpanzee-552275.hostingersite.com/blog/implementing-the-solid-principles-in-laravel-a-comprehensive-example/</guid>

					<description><![CDATA[SOLID is a set of principles for object-oriented software development. It stands for the following principles: Single Responsibility Principle (SRP) Open-Closed Principle (OCP) Liskov Substitution...]]></description>
										<content:encoded><![CDATA[<div>
<p>SOLID is a set of principles for object-oriented software development. It stands for the following principles:</p>
<ul>
<li>
<p><strong>Single Responsibility Principle (SRP)</strong></p>
</li>
<li>
<p><strong>Open-Closed Principle (OCP)</strong></p>
</li>
<li>
<p><strong>Liskov Substitution Principle (LSP)</strong></p>
</li>
<li>
<p><strong>Interface Segregation Principle (ISP)</strong></p>
</li>
<li>
<p><strong>Dependency Inversion Principle (DIP)</strong></p>
</li>
</ul>
<p>These principles help ensure that software is maintainable, reusable, and extensible.</p>
<p>Here&#8217;s how to achieve SOLID in Laravel with examples:</p>
<ol>
<li>
<p>S<strong>ingle Responsibility Principle (SRP)</strong> This principle states that a class should have only one reason to change. In other words, a class should have only one responsibility.</p>
<p> Example: Consider a class called <code>Order</code>. Instead of having all the functionality related to an order in one class, we can break it down into smaller classes like <code>OrderCalculator</code>, <code>OrderRepository</code>, and <code>OrderMailer</code>.</p>
</li>
<li>
<p>O<strong>pen-Closed Principle (OCP)</strong> This principle states that a class should be open for extension but closed for modification. In other words, we should be able to add new functionality without modifying existing code.</p>
<p> Example: Consider a class called <code>PaymentGateway</code>. Instead of modifying this class every time we add a new payment method, we can create a new class for each payment method that extends the <code>PaymentGateway</code> class.</p>
</li>
<li>
<p>L<strong>iskov Substitution Principle (LSP)</strong> This principle states that objects of a superclass should be able to be replaced with objects of a subclass without affecting the correctness of the program.</p>
<p> Example: Consider a class called <code>Shape</code> with subclasses <code>Circle</code>, <code>Rectangle</code>, and <code>Square</code>. If we have a function that takes an object of type <code>Shape</code>, we should be able to pass in objects of type <code>Circle</code>, <code>Rectangle</code>, or <code>Square</code> without affecting the behavior of the function.</p>
</li>
<li>
<p>I<strong>nterface Segregation Principle (ISP)</strong> This principle states that clients should not be forced to depend on methods they do not use.</p>
<p> Example: Consider an interface called <code>PaymentMethod</code> with methods like <code>pay</code>, <code>refund</code>, and <code>getTransactions</code>. Instead of having all these methods in one interface, we can create separate interfaces for each method and have classes implement only the interfaces they need.</p>
</li>
<li>
<p>D<strong>ependency Inversion Principle (DIP)</strong> This principle states that high-level modules should not depend on low-level modules. Both should depend on abstractions.</p>
<p> Example: Consider a class called <code>Order</code> that depends on a class called <code>OrderRepository</code>. Instead of directly instantiating <code>OrderRepository</code> in <code>Order</code>, we can use dependency injection to inject an instance of <code>OrderRepository</code> into <code>Order</code>.</p>
</li>
</ol>
<p>By following these SOLID principles in Laravel, we can write clean, maintainable, and extensible code.</p>
<p>To further illustrate how to achieve SOLID principles in Laravel, let&#8217;s take a look at a practical example.</p>
<p>Suppose we have an application that allows users to place orders for products. We want to implement the functionality to calculate the total price of an order, and send an email to the customer with the order details. We can achieve this by following SOLID principles.</p>
<ol>
<li>
<h3 id="heading-single-responsibility-principle-srp"><strong>Single Responsibility Principle (SRP)</strong></h3>
</li>
</ol>
<p>To follow SRP, we can create separate classes for calculating the total price of an order and sending an email to the customer. For example:</p>
<pre><code class="lang-bash">class OrderCalculator
{
    public <span class="hljs-keyword">function</span> calculateTotal(Order <span class="hljs-variable">$order</span>): <span class="hljs-built_in">float</span>
    {
        // Calculate total price of order
    }
}

class OrderMailer
{
    public <span class="hljs-keyword">function</span> sendEmail(Order <span class="hljs-variable">$order</span>, User <span class="hljs-variable">$user</span>)
    {
        // Send email to customer with order details
    }
}
</code></pre>
<ol>
<li>
<h3 id="heading-open-closed-principle-ocp">Open-Closed Principle (OCP)</h3>
</li>
</ol>
<p>To follow OCP, we can use Laravel&#8217;s service container and dependency injection to create a flexible system that allows us to add new functionality without modifying existing code. For example:</p>
<pre><code class="lang-bash">interface PaymentGateway
{
    public <span class="hljs-keyword">function</span> pay(Order <span class="hljs-variable">$order</span>): bool;
}

class PayPalGateway implements PaymentGateway
{
    public <span class="hljs-keyword">function</span> pay(Order <span class="hljs-variable">$order</span>): bool
    {
        // Process payment using PayPal API
    }
}

class StripeGateway implements PaymentGateway
{
    public <span class="hljs-keyword">function</span> pay(Order <span class="hljs-variable">$order</span>): bool
    {
        // Process payment using Stripe API
    }
}

class OrderProcessor
{
    private PaymentGateway <span class="hljs-variable">$gateway</span>;

    public <span class="hljs-keyword">function</span> __construct(PaymentGateway <span class="hljs-variable">$gateway</span>)
    {
        <span class="hljs-variable">$this</span>-&gt;gateway = <span class="hljs-variable">$gateway</span>;
    }

    public <span class="hljs-keyword">function</span> process(Order <span class="hljs-variable">$order</span>): void
    {
        // Process order using PaymentGateway
    }
}

// In application service provider
<span class="hljs-variable">$this</span>-&gt;app-&gt;<span class="hljs-built_in">bind</span>(PaymentGateway::class, StripeGateway::class);
</code></pre>
<p>Here, we have created a <code>PaymentGateway</code> interface and two implementations for PayPal and Stripe. We then create an <code>OrderProcessor</code> class that takes a <code>PaymentGateway</code> instance through its constructor. In the application service provider, we bind the <code>PaymentGateway</code> interface to the <code>StripeGateway</code> implementation, but we can easily change it to use the <code>PayPalGateway</code> implementation if needed.</p>
<ol>
<li>
<h3 id="heading-liskov-substitution-principle-lsp">Liskov Substitution Principle (LSP)</h3>
</li>
</ol>
<p>To follow LSP, we need to ensure that any subclasses of a superclass can be used in place of the superclass without affecting the behavior of the program. In our example, we can ensure this by using type hinting and interfaces. For example:</p>
<pre><code class="lang-bash">interface OrderRepository
{
    public <span class="hljs-keyword">function</span> save(Order <span class="hljs-variable">$order</span>): void;
}

class DatabaseOrderRepository implements OrderRepository
{
    public <span class="hljs-keyword">function</span> save(Order <span class="hljs-variable">$order</span>): void
    {
        // Save order to database
    }
}

class InMemoryOrderRepository implements OrderRepository
{
    public <span class="hljs-keyword">function</span> save(Order <span class="hljs-variable">$order</span>): void
    {
        // Save order to in-memory cache
    }
}

class OrderService
{
    private OrderRepository <span class="hljs-variable">$repository</span>;

    public <span class="hljs-keyword">function</span> __construct(OrderRepository <span class="hljs-variable">$repository</span>)
    {
        <span class="hljs-variable">$this</span>-&gt;repository = <span class="hljs-variable">$repository</span>;
    }

    public <span class="hljs-keyword">function</span> placeOrder(Order <span class="hljs-variable">$order</span>): void
    {
        // Place order and save to repository
    }
}

// In application service provider
<span class="hljs-variable">$this</span>-&gt;app-&gt;<span class="hljs-built_in">bind</span>(OrderRepository::class, DatabaseOrderRepository::class);
</code></pre>
<p>Here, we have created an <code>OrderRepository</code> interface and two implementations for a database and in-memory cache. We then create an <code>OrderService</code> class that takes an <code>OrderRepository</code> instance through its constructor. In the application service provider, we bind the <code>OrderRepository</code> interface to the <code>DatabaseOrderRepository</code> implementation, but we can easily change it to use the <code>InMemoryOrderRepository</code> implementation if needed, without affecting the behavior of the program.</p>
<ol>
<li><strong>Interface Segregation Principle (ISP)</strong></li>
</ol>
<p>To follow ISP, we should not force clients to depend on interfaces they do not use. In our example, we can ensure this by creating smaller, more focused interfaces instead of large, monolithic ones. For example:</p>
<pre><code class="lang-bash">interface OrderTotalCalculator
{
    public <span class="hljs-keyword">function</span> calculateTotal(Order <span class="hljs-variable">$order</span>): <span class="hljs-built_in">float</span>;
}

interface OrderEmailSender
{
    public <span class="hljs-keyword">function</span> sendEmail(Order <span class="hljs-variable">$order</span>, User <span class="hljs-variable">$user</span>);
}

class OrderProcessor
{
    private OrderTotalCalculator <span class="hljs-variable">$calculator</span>;
    private OrderEmailSender <span class="hljs-variable">$mailer</span>;

    public <span class="hljs-keyword">function</span> __construct(OrderTotalCalculator <span class="hljs-variable">$calculator</span>, OrderEmailSender <span class="hljs-variable">$mailer</span>)
    {
        <span class="hljs-variable">$this</span>-&gt;calculator = <span class="hljs-variable">$calculator</span>;
        <span class="hljs-variable">$this</span>-&gt;mailer = <span class="hljs-variable">$mailer</span>;
    }

    public <span class="hljs-keyword">function</span> process(Order <span class="hljs-variable">$order</span>, User <span class="hljs-variable">$user</span>): void
    {
        <span class="hljs-variable">$total</span> = <span class="hljs-variable">$this</span>-&gt;calculator-&gt;calculateTotal(<span class="hljs-variable">$order</span>);
        <span class="hljs-variable">$this</span>-&gt;mailer-&gt;sendEmail(<span class="hljs-variable">$order</span>, <span class="hljs-variable">$user</span>);
        // Process order using total and mailer
    }
}
</code></pre>
<p>Here, we have created two smaller interfaces for calculating the total price of an order and sending an email, respectively. We then modify the <code>OrderProcessor</code> class to take instances of these interfaces instead of a single, large interface. This allows clients to depend only on the interfaces they need, rather than being forced to depend on a large, monolithic interface.</p>
<ol>
<li><strong>Dependency Inversion Principle (DIP)</strong></li>
</ol>
<p>To follow DIP, we should depend on abstractions instead of concrete implementations. In our example, we can achieve this by using dependency injection and interfaces throughout our code. For example:</p>
<pre><code class="lang-bash">interface PaymentGateway
{
    public <span class="hljs-keyword">function</span> pay(Order <span class="hljs-variable">$order</span>): bool;
}

interface OrderRepository
{
    public <span class="hljs-keyword">function</span> save(Order <span class="hljs-variable">$order</span>): void;
}

interface OrderTotalCalculator
{
    public <span class="hljs-keyword">function</span> calculateTotal(Order <span class="hljs-variable">$order</span>): <span class="hljs-built_in">float</span>;
}

interface OrderEmailSender
{
    public <span class="hljs-keyword">function</span> sendEmail(Order <span class="hljs-variable">$order</span>, User <span class="hljs-variable">$user</span>);
}

class OrderProcessor
{
    private PaymentGateway <span class="hljs-variable">$gateway</span>;
    private OrderRepository <span class="hljs-variable">$repository</span>;
    private OrderTotalCalculator <span class="hljs-variable">$calculator</span>;
    private OrderEmailSender <span class="hljs-variable">$mailer</span>;

    public <span class="hljs-keyword">function</span> __construct(
        PaymentGateway <span class="hljs-variable">$gateway</span>,
        OrderRepository <span class="hljs-variable">$repository</span>,
        OrderTotalCalculator <span class="hljs-variable">$calculator</span>,
        OrderEmailSender <span class="hljs-variable">$mailer</span>
    ) {
        <span class="hljs-variable">$this</span>-&gt;gateway = <span class="hljs-variable">$gateway</span>;
        <span class="hljs-variable">$this</span>-&gt;repository = <span class="hljs-variable">$repository</span>;
        <span class="hljs-variable">$this</span>-&gt;calculator = <span class="hljs-variable">$calculator</span>;
        <span class="hljs-variable">$this</span>-&gt;mailer = <span class="hljs-variable">$mailer</span>;
    }

    public <span class="hljs-keyword">function</span> process(Order <span class="hljs-variable">$order</span>, User <span class="hljs-variable">$user</span>): void
    {
        <span class="hljs-variable">$total</span> = <span class="hljs-variable">$this</span>-&gt;calculator-&gt;calculateTotal(<span class="hljs-variable">$order</span>);
        <span class="hljs-variable">$this</span>-&gt;mailer-&gt;sendEmail(<span class="hljs-variable">$order</span>, <span class="hljs-variable">$user</span>);
        <span class="hljs-variable">$this</span>-&gt;gateway-&gt;pay(<span class="hljs-variable">$order</span>);
        <span class="hljs-variable">$this</span>-&gt;repository-&gt;save(<span class="hljs-variable">$order</span>);
        // Process order using gateway, repository, calculator, and mailer
    }
}
</code></pre>
<p>Here, we have created interfaces for all our dependencies, and modified the <code>OrderProcessor</code> class to take instances of these interfaces through its constructor. This allows us to easily swap out implementations at runtime, and allows us to depend on abstractions instead of concrete implementations.</p>
<p>In summary, we can achieve SOLID principles in Laravel by using dependency injection, interfaces, and the Laravel service container to create a flexible, maintainable system that is easy to modify and extend.</p>
</div>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
