Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using strategy pattern with environment variable laravel

I am currently learning about design patterns and I came across strategy pattern. I understood it, but now I want to know what would be the best solution to change strategy at runtime. Is it good solution to use ENV variables? Example:

interface Logger{
    public function log();
}


class SomeOtherLogger implements Logger {

public function log(){
    echo "Logging to something else";
 }
}


class FileLogger implements Logger {

public function log(){
    echo "Logging to file";
 }
}

class Main{
public function doSomething(Loggers $logger){
    $logger->log();    
 }
}

$main = new main();
$main->doSomething(new FileLogger);

One thing that came across my mind is to use environment variable, but I am not sure what is the best way to do it, this one doesn't seem right to me.

$loggingStrategy = env('LOGGING_TYPE') . 'Logger';
$main = new main();
$main->doSomething(new $loggingStrategy);
like image 584
Alex Avatar asked Jun 04 '26 21:06

Alex


2 Answers

If you are using Laravel I have a better solution. I hope it works for you:

Laravel has a Manager base class that you can use to implement a strategy pattern. Consider we want to great users depends on their languages.

First, let's implement our language classes:

namespace App\Welcome;

class English
{
    public function great()
    {
        return 'Hi!';
    }
}

and for German:

namespace App\Welcome;

class German
{
    public function great()
    {
        return 'Halo!';
    }
}

Now we create Welcome class that extends Laravel Manager base class:

namespace App;

use App\Welcome\English;
use App\Welcome\German;
use Illuminate\Support\Manager;

class Welcome extends Manager
{
    public function getDefaultDriver()
    {
        return 'english';
    }

    public function createGermanDriver()
    {
        return new German();
    }

    public function createEnglishDriver()
    {
        return new English();
    }
}

Now you can you can use strategy pattern and define a default driver for your Welcome class. If you want to change the driver at runtime you can use driver method on the welcome class:

$greater = app(Welcome::class);
return $greater->driver('german')->great();

Although in this way, you use Laravel IOC container too. But if you want to be more convenient, combine this pattern with Laravel Facade feature. For instance, in our example, you should only add Facades prefix to the welcome class use keyword. The final code would be like this:

use Facades\App\Welcome; // <-- Laravel automatically would implement facade on the welcome class
  
Route::get('/', function () {
    return Welcome::driver('german')->great();
});
like image 163
Mahdi Jedari Avatar answered Jun 07 '26 11:06

Mahdi Jedari


StrategyController.php

<?php
namespace App\Http\Controllers\DesignPattern\Strategy;

use App\Traits\ApiResponser;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Strategy\Sorting\SortingStrategyContext;

class StrategyController extends Controller
{
    use ApiResponser;
    public function sortingTest(Request $request)
    {
        $items = [5, 3, 2, 4, 1];

        $sortingstrategycontext = new SortingStrategyContext('quicksort');
        $sortedItems = $sortingstrategycontext->sort($items);

        return $this->set_response($sortedItems, 200,'success', ['Sorting!']);
    }
}

SortingStrategy.php

<?php

namespace App\Strategy\Sorting;

interface SortingStrategy
{
    public function sort(array $items): array;
}

SortingStrategyContext.php

<?php

namespace App\Strategy\Sorting;

use App\Strategy\Sorting\SortingStrategy;
use App\Strategy\Sorting\BubbleSortStrategy;
use App\Strategy\Sorting\QuickSortStrategy;

class SortingStrategyContext
{
    private SortingStrategy $strategy;

    public function __construct( string $sortingStrategy )
    {
        switch ($sortingStrategy) {
            case 'bubblesort':
                $this->strategy = new BubbleSortStrategy();
                break;
            case 'quicksort':
                $this->strategy = new QuickSortStrategy();
                break;
            default:
                $this->strategy = new QuickSortStrategy();
                break;
        }
    }

    public function sort($items)
    {
        return $this->strategy->sort($items);
    }
}

BubbleSortStrategy.php

<?php

namespace App\Strategy\Sorting;

use App\Strategy\Sorting\SortingStrategy;

class BubbleSortStrategy implements SortingStrategy
{
    public function sort(array $items): array
    {
        $count = count($items);
        for ($i = 0; $i < $count; $i++) {
            for ($j = 0; $j < $count - $i - 1; $j++) {
                if ($items[$j] > $items[$j + 1]) {
                    $temp = $items[$j];
                    $items[$j] = $items[$j + 1];
                    $items[$j + 1] = $temp;
                }
            }
        }
        return $items;
    }
}

QuickSortStrategy.php

<?php

namespace App\Strategy\Sorting;

use App\Strategy\Sorting\SortingStrategy;

class QuickSortStrategy implements SortingStrategy
{
    public function sort(array $items): array
    {
        if (count($items) <= 1) {
            return $items;
        }

        $pivot = array_shift($items);
        $left = $right = array();
        foreach ($items as $item) {
            if ($item < $pivot) {
                $left[] = $item;
            } else {
                $right[] = $item;
            }
        }

        return array_merge($this->sort($left), array($pivot), $this->sort($right));
    }
}

like image 23
Md. Saifur Rahman Avatar answered Jun 07 '26 12:06

Md. Saifur Rahman



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!