https://github.com/degraciamathieu/manager
Implementation of the Manager pattern existing in Laravel framework
https://github.com/degraciamathieu/manager
design-patterns laravel manager package php
Last synced: 12 months ago
JSON representation
Implementation of the Manager pattern existing in Laravel framework
- Host: GitHub
- URL: https://github.com/degraciamathieu/manager
- Owner: DeGraciaMathieu
- Created: 2020-02-28T16:54:28.000Z (about 6 years ago)
- Default Branch: master
- Last Pushed: 2023-12-27T07:43:20.000Z (over 2 years ago)
- Last Synced: 2025-04-09T16:17:51.804Z (12 months ago)
- Topics: design-patterns, laravel, manager, package, php
- Language: PHP
- Homepage:
- Size: 97.7 KB
- Stars: 90
- Watchers: 2
- Forks: 2
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# DeGraciaMathieu/Manager
Implementation of the Manager pattern existing in Laravel framework.
* [Installation](#installation)
* [Usage](#usage)
* [Work with singleton](#work-with-singleton)
* [Example with Laravel](#example-with-laravel)
## Installation
| Manager | 3.* | 2.* | 1.* |
|-------------|--------------------|--------------------|--------------------|
| php ^8.1 | :white_check_mark: | :x: | :x: |
| php 8.0.* | :white_check_mark: | :white_check_mark: | :x: |
| php 7.* | :x: | :x: | :white_check_mark: |
```
composer require degraciamathieu/manager
```
## Usage
This package offers an abstract class `DeGraciaMathieu\Manager\Manager` which needs to be extended to implement the creation of various Driver classes :
```php
namespace App\Managers;
use DeGraciaMathieu\Manager\Manager;
class WeatherManager extends Manager {
public function createOpenweathermapDriver()
{
return new Openweathermap();
}
public function getDefaultDriver(): string
{
return 'openweathermap';
}
}
```
A driver is a class integrating all the logic of an implementation, in our examples the interactions with the APIs of [Openweathermap](https://openweathermap.org/api) :
```php
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;
}
}
```
From now on, you can directly call the method of a driver directly from the manager :
```php
(new WeatherManager())->itsRainingNow('Paris'); // true
```
The manager will call the `itsRainingNow` method of the default driver configured by the `getDefaultDriver` method.
You can also call any driver from the manager's `driver` method :
```php
(new WeatherManager())->driver('openweathermap')->itsRainingNow('Paris');
```
Now if you want to create a new implementation, for example if you want to use [Aerisweather](https://www.aerisweather.com/develop/api/) APIs, you just have to create a new driver in your manager :
```php
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';
}
}
```
> Tip, the `getDefaultDriver` method is the perfect place to use a configuration or environment variable !
## Add an interface to the drivers
For more consistency it is advisable to implement an interface to the different drivers :
```php
namespace App\Managers;
interface Driver {
public function itsRainingNow(string $city): bool;
}
```
You obviously need to add this interface to your drivers.
```php
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';
}
}
```
Now you will be assured that each driver instantiated by the manager will have the same interface.
## Repository class
To control side effects of drivers, it is advisable to create a class encapsulating the instance of a driver, this class is usually called `Repository` :
```php
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';
}
}
```
The repository is a class providing a bridge between your application and the driver :
```php
namespace App\Managers;
class Repository {
public function __construct(
private Driver $driver,
){}
public function itsRainingNow(string $city): bool
{
return $this->driver->itsRainingNow($city);
}
}
```
> This repository class is an anti-corruption layer
Thus, your application will never be aware of which driver it is handling, because it will always be encapsulated in a class repository.
The repository is also a good place if you need to add specific logic for all drivers.
## Work with singleton
You can also cache the creation of Drivers with the `$singleton` property.
With the `singleton` property you will only create one instance of `Openweathermap` driver :
```php
driver('openweathermap')->itsRainingNow('Paris');
$weatherManager->driver('openweathermap')->itsRainingNow('Paris');
$weatherManager->driver('openweathermap')->itsRainingNow('Paris');
```
> by default, singleton property value is False
## Example with Laravel
[Usage example](https://github.com/DeGraciaMathieu/manager-laravel-10-examples) of the pattern manager in a Laravel project.

