Laravel框架中现有Manager模式的实现。

v3.0.1 2023-07-07 07:34 UTC

This package is auto-updated.

Last update: 2024-08-27 08:59:45 UTC


README

Build Status Code Coverage Latest Version on Packagist

DeGraciaMathieu/Manager

Laravel框架中现有Manager模式的实现。

安装

composer require degraciamathieu/manager

使用方法

此包提供了一个抽象类 DeGraciaMathieu\Manager\Manager,需要扩展以实现各种Driver类的创建

namespace App\Managers;

use DeGraciaMathieu\Manager\Manager;

class WeatherManager extends Manager {

    public function createOpenweathermapDriver() 
    {
        return new Openweathermap();
    }

    public function getDefaultDriver(): string
    {
        return 'openweathermap';
    }
}

驱动是一个类,集成了所有实现的逻辑,在我们的示例中是与Openweathermap API的交互

namespace App\Managers;

class Openweathermap {

    public function itsRainingNow(string $city): bool
    {   
        // call Openweathermap api to know if it is raining in this city

        return true;
    }
}

从现在起,您可以直接从管理器中调用驱动的方法

(new WeatherManager())->itsRainingNow('Paris'); // true

管理器将调用默认驱动程序的itsRainingNow方法,默认驱动程序由getDefaultDriver方法配置。

您也可以从管理器的driver方法调用任何驱动程序

(new WeatherManager())->driver('openweathermap')->itsRainingNow('Paris');

现在,如果您想创建一个新的实现,例如,如果您想使用Aerisweather API,您只需在您的管理器中创建一个新的驱动程序即可

namespace App\Managers;

use DeGraciaMathieu\Manager\Manager;

class WeatherManager extends Manager {

    public function createOpenweathermapDriver()
    {
        return new Openweathermap();
    }

    public function createAerisweatherDriver()
    {
        return new Aerisweather();
    }

    public function getDefaultDriver(): string
    {
        return 'openweathermap';
    }
}

提示,getDefaultDriver方法是使用配置或环境变量的理想场所!

为驱动程序添加接口

为了提高一致性,建议实现不同驱动程序的接口

namespace App\Managers;

interface Driver {
    public function itsRainingNow(string $city): bool;
}

显然,您需要将此接口添加到您的驱动程序中。

namespace App\Managers;

use DeGraciaMathieu\Manager\Manager;

class WeatherManager extends Manager {

    public function createOpenweathermapDriver(): Driver
    {
        return new Openweathermap();
    }

    public function createAerisweatherDriver(): Driver
    {
        return new Aerisweather();
    }

    public function getDefaultDriver(): string
    {
        return 'openweathermap';
    }
}

现在您将确保管理器实例化的每个驱动程序都具有相同的接口。

仓库类

为了控制驱动程序的外部效应,建议创建一个封装驱动程序实例的类,此类通常称为Repository

namespace App\Managers;

use DeGraciaMathieu\Manager\Manager;

class WeatherManager extends Manager {

    public function createOpenweathermapDriver(): Repository
    {
        $driver = new Openweathermap();

        return new Repository($driver);
    }

    public function createAerisweatherDriver(): Repository
    {
        $driver = new Aerisweather();

        return new Repository($driver);
    }

    public function getDefaultDriver(): string
    {
        return 'openweathermap';
    }
}

仓库是一个提供应用程序与驱动程序之间桥梁的类

namespace App\Managers;

class Repository {

    public function __construct(
        private Driver $driver,
    ){}

    public function itsRainingNow(string $city): bool
    {
        return $this->driver->itsRainingNow($city);
    }
}

此仓库类是一个反腐败层

因此,您的应用程序将永远不会知道它正在处理哪个驱动程序,因为它将始终封装在仓库类中。

如果需要对所有驱动程序添加特定的逻辑,仓库也是一个不错的选择。

与单例一起工作

您还可以使用$singleton属性缓存驱动程序的创建。

使用singleton属性,您将只创建一个Openweathermap驱动程序的实例

<?php

$weatherManager = new WeatherManager(singleton: true);

$weatherManager->driver('openweathermap')->itsRainingNow('Paris');
$weatherManager->driver('openweathermap')->itsRainingNow('Paris');
$weatherManager->driver('openweathermap')->itsRainingNow('Paris');

默认情况下,singleton属性值是False

Laravel示例

Laravel项目中模式管理器的使用示例