Repaso: procesador de pagos
Parte de la sección Programación Orientada a Objetos del Journey de PHP de Coddy. Lección 37 de 91.
Desafío
FácilConstruyamos un sistema completo de procesamiento de pagos que reúna todo lo que has aprendido sobre polimorfismo. Crearás una arquitectura basada en interfaces en la que se puedan procesar diferentes métodos de pago mediante un único procesador unificado: demostrando cómo el polimorfismo hace que el código sea flexible y extensible.
Organizarás tu código en cinco archivos:
PaymentMethod.php: Define una interfazPaymentMethodcon dos firmas de método:process(float $amount): stringpara gestionar el pago, y un método estáticogetMethodName(): stringque devuelve el nombre del tipo de pago. Este contrato garantiza que cualquier método de pago pueda procesarse de manera uniforme.CreditCard.php: Crea una claseCreditCardque implementePaymentMethod. Incluye el archivo de la interfaz. La clase debe tener una propiedad privada$lastFourDigitsestablecida mediante el constructor. Implementaprocess()para que devuelva"Processing $[amount] via Credit Card ending in [lastFourDigits]"(formatea el importe con 2 decimales). Implementa el método estáticogetMethodName()mediante enlace estático tardío para que devuelva"Credit Card".PayPal.php: Crea una clasePayPalque implementePaymentMethod. Incluye el archivo de la interfaz. La clase debe tener una propiedad privada$emailestablecida mediante el constructor. Implementaprocess()para que devuelva"Processing $[amount] via PayPal account [email]"(formatea el importe con 2 decimales). Implementa el método estáticogetMethodName()para que devuelva"PayPal".PaymentProcessor.php: Crea una clasePaymentProcessorque coordine los pagos. Incluye el archivo de la interfaz. Añade un métodoexecutePayment(PaymentMethod $method, float $amount): stringque use la declaración de tipo de la interfaz para aceptar cualquier método de pago. Este método debe devolver el resultado de llamar aprocess()en el método de pago. Añade otro métododescribeMethod(PaymentMethod $method): stringque devuelva"Payment via: [methodName]"usando el método estáticogetMethodName()de la clase del método de pago proporcionado.main.php: Incluye todos los archivos de las clases de pago y el procesador. Crea una instancia dePaymentProcessor. Recibirás tres entradas: los últimos cuatro dígitos de una tarjeta de crédito, una dirección de correo electrónico de PayPal y un importe de pago. Crea una instancia deCreditCardy otra dePayPalcon sus identificadores correspondientes. Convierte el importe a un valor float. Usa el procesador para ejecutar primero un pago con la tarjeta de crédito y después uno con PayPal. Imprime cada resultado en su propia línea. Finalmente, imprime la descripción del método correspondiente al método de pago de PayPal.
La ventaja de este diseño es que tu PaymentProcessor no sabe nada específicamente sobre las tarjetas de crédito ni sobre PayPal. Solo conoce la interfaz PaymentMethod. Mañana podrías añadir una clase BankTransfer o Cryptocurrency, y el procesador las gestionaría sin ninguna modificación. ¡Ese es el poder del polimorfismo basado en interfaces combinado con el enlace estático tardío!
Pruébalo tú mismo
<?php
// Incluir todos los archivos requeridos
require_once 'CreditCard.php';
require_once 'PayPal.php';
require_once 'PaymentProcessor.php';
// Leer las entradas
$lastFourDigits = trim(fgets(STDIN));
$paypalEmail = trim(fgets(STDIN));
$amount = floatval(trim(fgets(STDIN)));
// TODO: Crear una instancia de PaymentProcessor
// TODO: Crear una instancia de CreditCard con los últimos cuatro dígitos
// TODO: Crear una instancia de PayPal con el email
// TODO: Ejecutar el pago con tarjeta de crédito e imprimir el resultado
// TODO: Ejecutar el pago con PayPal e imprimir el resultado
// TODO: Imprimir la descripción del método para el método de pago de PayPal
?>Todas las lecciones de Programación Orientada a Objetos
1Fundamentos de la POO
Archivos externosIntroducción a la POOClases frente a objetosLa palabra clave $thisMétodosPropiedadesConstructor (__construct)Destructor (__destruct)Repaso: calculadora simple4Herencia
Herencia básicaLa palabra clave parent::Sobrescritura de métodosLa palabra clave finalClases abstractasRepaso - Jerarquía de empleados7Encapsulación
Público, protegido, privadoModificadores de acceso en profundidadGetters y settersOcultación de la informaciónPromoción del constructor (8.0)Repaso: sistema de registros de estudiantes10Conceptos avanzados de OOP
Composición vs. herenciaInyección de dependenciasClases anónimasEnums (PHP 8.1)Fibras (PHP 8.1)Análisis profundo de la clonación de objetosGeneradores e iteradores13Patrones de diseño Parte 2
Patrón CommandPatrón AdapterPatrón DecoratorPatrón Template MethodPatrón StatePatrón CompositePatrón Repository2Namespaces y carga automática
Introducción a los NamespacesLa palabra clave useEstándar de carga automática PSR-4Autoloader de ComposerRepaso: proyecto organizado5Interfaces y contratos
Introducción a las interfacesImplementación de interfacesImplementación de múltiples interfacesInterfaces vs. clase abstractaTipado con interfacesRepaso - Calculadora de formas8Métodos mágicos
Introducción a los métodos mágicos__toString y __debugInfo__get, __set, __isset, __unset__call y __callStatic__clone y clonación de objetos__serialize y __unserializeRepaso: colección personalizada3Propiedades de clase
Propiedades de instancia vs. estáticasConstantes en clasesMétodos y propiedades estáticosPropiedades privadas y protegidasPropiedades de solo lectura (PHP 8.1)Repaso: gestor de cuentas bancarias6Polimorfismo
Repaso de la sobrescritura de métodosPolimorfismo mediante interfacesAnotaciones de tipo y tipos uniónEnlace estático tardíoRepaso: procesador de pagos9Traits
Introducción a los TraitsUso de múltiples TraitsResolución de conflictos entre TraitsMétodos abstractos en TraitsTraits frente a la herencia12Patrones de diseño, parte 1
Introducción a los patrones de diseñoPatrón SingletonPatrón FactoryPatrón ObserverPatrón StrategyPractica por tu cuenta: Compilador de PHP online