Factory Method

This commit is contained in:
Yevhen Odynets 2025-07-03 19:35:54 +03:00
parent 91f8ded888
commit 0f4618edf5
24 changed files with 409 additions and 31 deletions

File diff suppressed because one or more lines are too long

58
code/factory_method.php Normal file
View File

@ -0,0 +1,58 @@
<?php
/**
* @package: patterns
* @author: Yevhen Odynets
* @date: 2025-07-03
* @time: 12:16
*/
declare(strict_types = 1);
use Pattern\Creational\FactoryMethod\{CashlessPayment, CashPayment, Order, PaymentHelper};
use Random\RandomException;
function execute(string $scope): void
{
echo '<hr/>' . ucfirst($scope) . ' App Payments:<hr/>' . PHP_EOL;
try {
$orderData = [
[
'order' => new Order(getFloatRange()),
'paymentType' => 'privat',
],
[
'order' => new Order(getFloatRange()),
'paymentType' => 'raiffeisen',
],
[
'order' => new Order(getFloatRange()),
'paymentType' => 'ing',
],
[
'order' => new Order(getFloatRange()),
'paymentType' => 'otp',
]
];
if ($scope === 'web') {
$orderData[] = [
'order' => new Order(getFloatRange()),
'paymentType' => 'cash',
];
}
foreach ($orderData as $orderDataItem) {
['order' => $order, 'paymentType' => $type] = $orderDataItem;
$payment = PaymentHelper::getPaymentFactory($type)->createPayment();
$payment->pay($order);
}
} catch (RandomException $e) {
echo $e->getMessage();
}
}
execute('web');
execute('mobile');

View File

@ -9,7 +9,7 @@
declare(strict_types = 1);
use Pattern\Creational\{Singleton, Sub\Single};
use Pattern\Creational\{Singleton\Single, Singleton\Singleton};
/**
* The client code.

View File

@ -1,4 +1,7 @@
<!doctype html>
<?php
require '../vendor/autoload.php';
require '../src/helpers.php';
?><!doctype html>
<html lang="uk">
<head>
<meta charset="UTF-8">
@ -10,31 +13,49 @@
<script src="assets/js/highlight.min.js"></script>
<script src="assets/js/stylus.min.js"></script>
<style>
html, body {
position: relative;
width: 100%;
height: 100dvh;
margin: 0;
padding: 0;
background: #ddd;
color: #1c1b19;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
}
main {
box-shadow: -1px 1px 5px 0 rgba(123, 123, 123, 1);
-webkit-box-shadow: -1px 1px 5px 0 rgba(123, 123, 123, 1);
-moz-box-shadow: -1px 1px 5px 0 rgba(123, 123, 123, 1);
position: absolute;
width: 100%;
max-width: 1280px;
margin: 0 auto;
outline: dotted 1px #a9a49f;
padding: 1rem;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
pre {
font-family: Consolas, monospace;
align-self: center;
}
</style>
</head>
<body>
<main>
<?php
<main>
<?php
/** Creational patterns **/
use Pattern\Creational\Singleton;
require '../vendor/autoload.php';
require '../src/helpers.php';
// Creational patterns
require '../code/singleton.php';
?>
</main>
<script>hljs.highlightAll();</script>
// require '../code/singleton.php';
require '../code/factory_method.php';
?>
</main>
<script>hljs.highlightAll()</script>
</body>
</html>

View File

@ -0,0 +1,21 @@
<?php
/**
* @package: patterns
* @author: Yevhen Odynets
* @date: 2025-07-03
* @time: 12:52
*/
declare(strict_types = 1);
namespace Pattern\Creational\FactoryMethod;
class CashPayment implements PaymentInterface
{
public function pay(Order $order): void
{
/** @noinspection ForgottenDebugOutputInspection */
dump("Cash payment success, amount: {$order->getSum()}");
}
}

View File

@ -0,0 +1,20 @@
<?php
/**
* @package: patterns
* @author: Yevhen Odynets
* @date: 2025-07-03
* @time: 17:55
*/
declare(strict_types = 1);
namespace Pattern\Creational\FactoryMethod;
class CashPaymentFactory implements PaymentFactoryInterface
{
public static function createPayment(): PaymentInterface
{
return new CashPayment();
}
}

View File

@ -0,0 +1,21 @@
<?php
/**
* @package: patterns
* @author: Yevhen Odynets
* @date: 2025-07-03
* @time: 19:22
*/
declare(strict_types = 1);
namespace Pattern\Creational\FactoryMethod;
class IngPayment implements PaymentInterface
{
public function pay(Order $order): void
{
/** @noinspection ForgottenDebugOutputInspection */
dump("ING Bank payment success, amount: {$order->getSum()}");
}
}

View File

@ -0,0 +1,20 @@
<?php
/**
* @package: patterns
* @author: Yevhen Odynets
* @date: 2025-07-03
* @time: 18:01
*/
declare(strict_types = 1);
namespace Pattern\Creational\FactoryMethod;
class IngPaymentFactory implements PaymentFactoryInterface
{
public static function createPayment(): PaymentInterface
{
return new IngPayment();
}
}

View File

@ -0,0 +1,22 @@
<?php
/**
* @package: patterns
* @author: Yevhen Odynets
* @date: 2025-07-03
* @time: 12:08
*/
declare(strict_types = 1);
namespace Pattern\Creational\FactoryMethod;
final readonly class Order
{
public function __construct(private float $sum) {}
public function getSum(): float
{
return $this->sum;
}
}

View File

@ -0,0 +1,21 @@
<?php
/**
* @package: patterns
* @author: Yevhen Odynets
* @date: 2025-07-03
* @time: 19:21
*/
declare(strict_types = 1);
namespace Pattern\Creational\FactoryMethod;
class OtpPayment implements PaymentInterface
{
public function pay(Order $order): void
{
/** @noinspection ForgottenDebugOutputInspection */
dump("Otp Bank payment success, amount: {$order->getSum()}");
}
}

View File

@ -0,0 +1,20 @@
<?php
/**
* @package: patterns
* @author: Yevhen Odynets
* @date: 2025-07-03
* @time: 18:02
*/
declare(strict_types = 1);
namespace Pattern\Creational\FactoryMethod;
class OtpPaymentFactory implements PaymentFactoryInterface
{
public static function createPayment(): PaymentInterface
{
return new OtpPayment();
}
}

View File

@ -0,0 +1,18 @@
<?php
/**
* @package: patterns
* @author: Yevhen Odynets
* @date: 2025-07-03
* @time: 14:17
*/
//phpcs:ignore
declare(strict_types = 1);
namespace Pattern\Creational\FactoryMethod;
interface PaymentFactoryInterface
{
public static function createPayment(): PaymentInterface;
}

View File

@ -0,0 +1,34 @@
<?php
/**
* @package: patterns
* @author: Yevhen Odynets
* @date: 2025-07-03
* @time: 18:04
*/
declare(strict_types = 1);
namespace Pattern\Creational\FactoryMethod;
use RuntimeException;
class PaymentHelper
{
/**
* @param string $paymentType
*
* @return PaymentFactoryInterface
*/
public static function getPaymentFactory(string $paymentType): PaymentFactoryInterface
{
return match ($paymentType) {
'privat' => new PrivatPaymentFactory(),
'raiffeisen' => new RaiffeisenPaymentFactory(),
'ing' => new IngPaymentFactory(),
'otp' => new OtpPaymentFactory(),
'cash' => new CashPaymentFactory(),
default => throw new RuntimeException("Payment type '{$paymentType}' is unknown")
};
}
}

View File

@ -0,0 +1,17 @@
<?php
/**
* @package: patterns
* @author: Yevhen Odynets
* @date: 2025-07-03
* @time: 16:57
*/
declare(strict_types = 1);
namespace Pattern\Creational\FactoryMethod;
interface PaymentInterface
{
public function pay(Order $order): void;
}

View File

@ -0,0 +1,21 @@
<?php
/**
* @package: patterns
* @author: Yevhen Odynets
* @date: 2025-07-03
* @time: 19:18
*/
declare(strict_types = 1);
namespace Pattern\Creational\FactoryMethod;
class PrivatPayment implements PaymentInterface
{
public function pay(Order $order): void
{
/** @noinspection ForgottenDebugOutputInspection */
dump("Privatbank payment success, amount: {$order->getSum()}");
}
}

View File

@ -0,0 +1,20 @@
<?php
/**
* @package: patterns
* @author: Yevhen Odynets
* @date: 2025-07-03
* @time: 17:57
*/
declare(strict_types = 1);
namespace Pattern\Creational\FactoryMethod;
class PrivatPaymentFactory implements PaymentFactoryInterface
{
public static function createPayment(): PaymentInterface
{
return new PrivatPayment();
}
}

View File

@ -0,0 +1,21 @@
<?php
/**
* @package: patterns
* @author: Yevhen Odynets
* @date: 2025-07-03
* @time: 19:12
*/
declare(strict_types = 1);
namespace Pattern\Creational\FactoryMethod;
class RaiffeisenPayment implements PaymentInterface
{
public function pay(Order $order): void
{
/** @noinspection ForgottenDebugOutputInspection */
dump("Raiffeisen Bank payment success, amount: {$order->getSum()}");
}
}

View File

@ -0,0 +1,20 @@
<?php
/**
* @package: patterns
* @author: Yevhen Odynets
* @date: 2025-07-03
* @time: 17:59
*/
declare(strict_types = 1);
namespace Pattern\Creational\FactoryMethod;
class RaiffeisenPaymentFactory implements PaymentFactoryInterface
{
public static function createPayment(): PaymentInterface
{
return new RaiffeisenPayment();
}
}

View File

@ -9,7 +9,7 @@
declare(strict_types = 1);
namespace Contracts;
namespace Pattern\Creational\Singleton;
interface Loggable
{

View File

@ -12,10 +12,8 @@
declare(strict_types = 1);
namespace Service;
namespace Pattern\Creational\Singleton;
use Contracts\Loggable;
use Psr\Log\LoggerInterface;
use RuntimeException;
use function in_array;

View File

@ -9,10 +9,7 @@
//phpcs:ignore
declare(strict_types = 1);
namespace Pattern\Creational\Sub;
use Contracts\SingleInterface;
use Pattern\Creational\Singleton;
namespace Pattern\Creational\Singleton;
class Single extends Singleton implements SingleInterface
{

View File

@ -9,7 +9,7 @@
declare(strict_types = 1);
namespace Contracts;
namespace Pattern\Creational\Singleton;
interface SingleInterface
{

View File

@ -9,7 +9,7 @@
declare(strict_types = 1);
namespace Pattern\Creational;
namespace Pattern\Creational\Singleton;
use RuntimeException;

View File

@ -34,3 +34,11 @@ function trace(): string
return sprintf('%s@%s:%d', $traced['function'], $traced['file'], $traced['line']);
}
/**
* @throws \Random\RandomException
*/
function getFloatRange(): float
{
return (float)random_int(1000, 999999) / 100;
}