【S4】問7

 このコードでは、クレジットカード支払いとPayPal支払いをシミュレートしています。。
支払い可能な方法を増やしにくい状況で、既存のコードにも影響を与えてしまう状況になっています。
以下のソースコードをリファクタリングし拡張性と保守性を改善しなさい。

<?php

/**
 * 支払いクラス
 */
class Purchase
{
    private $payment;

    public function __construct(string $paymentMethod, ?int $id = null, ?string $email = null, ?int $cardNumber = null, ?DateTime $expire = null, int $securityCode = null)
    {
        if ($paymentMethod === 'creditCard') {
            $this->payment = new CreditCardPayment($cardNumber, $expire, $securityCode);
        } else {
            $this->payment = new PayPalPayment($id, $email);
        }
    }

    public function checkout($amount): void
    {
        if ($this->payment instanceof CreditCardPayment) {
            $this->payment->payCreditCard($amount);
        } elseif ($this->payment instanceof PayPalPayment) {
            $this->payment->payPayPal($amount);
        }
    }
}
                    
<?php

/**
 * クレジットカード支払い
 */
class CreditCardPayment
{
    private int $cardNumber;

    private DateTime $expire;

    private int $securityCode;

    public function __construct(int $cardNumber, DateTime $expire, int $securityCode)
    {
        $this->cardNumber = $cardNumber;
        $this->expire = $expire;
        $this->securityCode = $securityCode;
    }

    public function payCreditCard(int $amount): void
    {
        echo "クレジットカードで支払いました。金額: $amount" . PHP_EOL;
    }

    public function getCardNumber(): int
    {
        return $this->cardNumber;
    }

    public function getExpire(): DateTime
    {
        return $this->expire;
    }

    public function getSecurityCode(): int
    {
        return $this->securityCode;
    }
}
                    
<?php

/**
 * PayPal支払い
 */
class PayPalPayment
{
    private int $id;

    private string $email;

    public function __construct(int $id, string $email)
    {
        $this->id = $id;
        $this->email = $email;
    }

    public function payPayPal(int $amount): void
    {
        echo "PayPalで支払いました。金額: $amount" . PHP_EOL;
    }

    public function getId(): int
    {
        return $this->id;
    }

    public function getEmail(): string
    {
        return $this->email;
    }
}
                    
<?php

// クレジットカードでの支払い
$creditCardPurchase = new Purchase('creditCard', null, null, 1234_5678_9012_3456, new DateTime('2024-12-31'), 123);
$creditCardPurchase->checkout(100.00);

// ペイパルでの支払い
$paypalPurchase = new Purchase('payPal', 12345, 'johndoe@example.com');
$paypalPurchase->checkout(50.00);