Commit 33146da5 authored by Jan Kuchař's avatar Jan Kuchař

added example: migrating legacy code to `\Grifart\Enum`

parent dbfe027d
# Migrating legacy code to `\Grifart\Enum`
This is step-by-step guide how to migrate you legacy code to `\Grifart\Enum`.
We will start with non-type safe enum represented by class with constants. [[full source code](step0.phpt)]
```php
class OrderState {
public const NEW = 'new';
public const PROCESSING = 'processing';
}
```
Our business logic is this:
```php
$result = '';
switch ($state) {
// your business logic
case OrderState::NEW:
$result = 'new';
break;
case OrderState::PROCESSING:
$result = 'processing';
break;
}
```
## Step 1: add new type-safe API [[source](step1.phpt)]
This is done by
- extending `\Grifart\Enum\Enum` class
- by automatically implementing enum values by including `use \Grifart\Enum\AutoInstances;` trait
- and by adding magic methods annotations
When you do this there is not backward incompatible change introduced. But... Now you can use new API.
```php
/**
* @method static OrderState NEW()
* @method static OrderState PROCESSING()
*/
class OrderState extends \Grifart\Enum\Enum {
use \Grifart\Enum\AutoInstances;
public const NEW = 'new';
public const PROCESSING = 'processing';
}
```
## Step 2: Migrating code and discontinuing old API [[source](step2.phpt)]
Migrating old code to new API is usually easy, just add parenthesis `()` when you access value.
```php
$state = OrderState::NEW();
$result = '';
switch ($state) {
// your business logic
case OrderState::NEW():
$result = 'new';
break;
case OrderState::PROCESSING():
$result = 'processing';
break;
}
Assert::same('new', $result);
```
Please note, that you will need to handle some cases manually as `OrderState::NEW()` returns object, enum instance, not a string.
So when you are finally ready to remove old API, just change constant visibility to `private`.
```php
/**
* @method static OrderState NEW()
* @method static OrderState PROCESSING()
*/
class OrderState extends \Grifart\Enum\Enum {
use \Grifart\Enum\AutoInstances;
private const NEW = 'new';
private const PROCESSING = 'processing';
}
```
# Step 3: Enjoy new features [[source](step3.phpt)]
Now, when you decide that you what to move your business logic into enum, you are free to do so. Or you can split logic using composition.
<?php declare(strict_types=1);
namespace MigratingOldCode;
require __DIR__ . '/../../bootstrap.php';
use Tester\Assert;
class OrderState {
public const NEW = 'new';
public const PROCESSING = 'processing';
}
$state = OrderState::NEW;
$result = '';
switch ($state) {
// your business logic
case OrderState::NEW:
$result = 'new';
break;
case OrderState::PROCESSING:
$result = 'processing';
break;
}
Assert::same('new', $result);
<?php declare(strict_types=1);
namespace MigratingOldCode;
require __DIR__ . '/../../bootstrap.php';
use Tester\Assert;
/**
* @method static OrderState NEW()
* @method static OrderState PROCESSING()
*/
class OrderState extends \Grifart\Enum\Enum {
use \Grifart\Enum\AutoInstances;
public const NEW = 'new';
public const PROCESSING = 'processing';
}
// code bellow is untouched:
$state = OrderState::NEW;
$result = '';
switch ($state) {
// your business logic
case OrderState::NEW:
$result = 'new';
break;
case OrderState::PROCESSING:
$result = 'processing';
break;
}
Assert::same('new', $result);
<?php declare(strict_types=1);
namespace MigratingOldCode;
require __DIR__ . '/../../bootstrap.php';
use Tester\Assert;
/**
* @method static OrderState NEW()
* @method static OrderState PROCESSING()
*/
class OrderState extends \Grifart\Enum\Enum {
use \Grifart\Enum\AutoInstances;
private const NEW = 'new';
private const PROCESSING = 'processing';
}
$state = OrderState::NEW();
$result = '';
switch ($state) {
// your business logic
case OrderState::NEW():
$result = 'new';
break;
case OrderState::PROCESSING():
$result = 'processing';
break;
}
Assert::same('new', $result);
<?php declare(strict_types=1);
namespace MigratingOldCode;
require __DIR__ . '/../../bootstrap.php';
use Tester\Assert;
/**
* @method static OrderState NEW()
* @method static OrderState PROCESSING()
*/
class OrderState extends \Grifart\Enum\Enum {
use \Grifart\Enum\AutoInstances;
private const NEW = 'new';
private const PROCESSING = 'processing';
public function doBusinessLogic(): string
{
switch ($this) {
// your business logic
case self::NEW():
return 'new';
break;
case self::PROCESSING():
return 'processing';
break;
}
throw new \LogicException('should never happen');
}
}
$state = OrderState::NEW();
$result = $state->doBusinessLogic();
Assert::same('new', $result);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment