【S4】問7解答例

 このコードではPurchaseクラスのコンストラクタの引数にPaymentInterfaceインターフェイスを指定しています。
また、CreditCardPaymentPayPalPaymentpayメソッドでそれぞれの処理を実装しています。
これにより、支払い方法の種類を増やす際は既存クラスに一切手を入れずに新規のPaymentInterfaceを実装したクラスを用意するだけでよくなりました。

<?php

/**
 * インターフェース
 */
interface PaymentInterface
{
    public function pay($amount): void;
}
                    
<?php

/**
 * クレジットカード
 */
class CreditCardPayment implements PaymentInterface
{
    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 pay($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 implements PaymentInterface
{
    private int $id;

    private string $email;

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

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

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

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

/**
 * 購入クラス
 */
class Purchase
{
    private PaymentInterface $payment;

    public function __construct(PaymentInterface $payment)
    {
        $this->payment = $payment;
    }

    public function checkout(int $amount): void
    {
        $this->payment->pay($amount);
    }
}
                    
<?php

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

// PayPalでの支払い
$paypalPayment = new PayPalPayment(456, 'example@example.com');
$purchase = new Purchase($paypalPayment);
$purchase->checkout(50.00);