Resumen - Procesador de pagos
Parte de la sección Programación Orientada a Objetos del Journey de GO de Coddy — lección 46 de 107.
Desafío
FácilVamos a construir un sistema de procesamiento de pagos completo que reúna todos los conceptos de polimorfismo de este capítulo. Crearás diferentes métodos de pago que funcionan a través de una interfaz unificada, un procesador que acepta cualquier método de pago mediante inyección de dependencias y procesarás múltiples pagos a través de una colección polimórfica.
Organizarás tu código en cuatro archivos:
payment.go: Define una interfazPaymentMethodque requiere un métodoProcess(amount float64) string. Este es el contrato que todos los tipos de pago deben cumplir.methods.go: Crea tres tipos de pago que implementen cada uno la interfazPaymentMethod:CreditCardcon los camposCardNumber(string) yHolderName(string); su métodoProcessdevuelve"Credit Card [last 4 digits of CardNumber] charged $[amount] to [HolderName]"PayPalcon un campoEmail; su métodoProcessdevuelve"PayPal payment of $[amount] from [Email]"BankTransfercon los camposBankNameyAccountNumber; su métodoProcessdevuelve"Bank transfer of $[amount] via [BankName] (***[last 3 digits of AccountNumber])"
processor.go: Crea una estructuraPaymentProcessorque contenga unPaymentMethod(dependencia inyectada). Incluye un constructorNewPaymentProcessorque acepte unPaymentMethod. Añade un métodoExecutePayment(amount float64) stringque delegue en el método de pago inyectado. También crea una funciónProcessAll(payments []PaymentMethod, amount float64) []stringque procese la misma cantidad a través de cada método de pago en el slice y devuelva todos los resultados.main.go: Lee los detalles del pago de la entrada, crea los tres tipos de pago y demuestra tanto la inyección de dependencias como las colecciones polimórficas. Primero, usaNewPaymentProcessorcon la tarjeta de crédito y ejecuta un pago. Luego, agrupa los tres métodos de pago en un slice y usaProcessAllpara procesarlos todos con una segunda cantidad. Imprime cada resultado en su propia línea.
Se proporcionarán las siguientes entradas:
- Línea 1: Número de tarjeta de crédito (por ejemplo,
4532015112830366) - Línea 2: Nombre del titular de la tarjeta
- Línea 3: Correo electrónico de PayPal
- Línea 4: Nombre del banco
- Línea 5: Número de cuenta (por ejemplo,
987654321) - Línea 6: Primera cantidad de pago (para el procesador individual)
- Línea 7: Segunda cantidad de pago (para el procesamiento por lotes)
Formatea las cantidades con dos decimales. Por ejemplo, dados 4532015112830366, John Smith, john@email.com, Chase, 987654321, 99.99, y 50, tu salida debería ser:
Credit Card 0366 charged $99.99 to John Smith
Credit Card 0366 charged $50.00 to John Smith
PayPal payment of $50.00 from john@email.com
Bank transfer of $50.00 via Chase (***321)La primera línea muestra el pago único a través del procesador inyectado. Las tres líneas restantes muestran el procesamiento por lotes a través de la colección polimórfica: la misma función ProcessAll maneja todos los tipos de pago de manera uniforme, demostrando cómo las interfaces permiten sistemas de pago flexibles y extensibles.
Pruébalo tú mismo
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
func main() {
reader := bufio.NewReader(os.Stdin)
// Leer entrada
cardNumber, _ := reader.ReadString('\n')
cardNumber = strings.TrimSpace(cardNumber)
holderName, _ := reader.ReadString('\n')
holderName = strings.TrimSpace(holderName)
email, _ := reader.ReadString('\n')
email = strings.TrimSpace(email)
bankName, _ := reader.ReadString('\n')
bankName = strings.TrimSpace(bankName)
accountNumber, _ := reader.ReadString('\n')
accountNumber = strings.TrimSpace(accountNumber)
amount1Str, _ := reader.ReadString('\n')
amount1Str = strings.TrimSpace(amount1Str)
amount1, _ := strconv.ParseFloat(amount1Str, 64)
amount2Str, _ := reader.ReadString('\n')
amount2Str = strings.TrimSpace(amount2Str)
amount2, _ := strconv.ParseFloat(amount2Str, 64)
// TODO: Crear los tres tipos de pago (CreditCard, PayPal, BankTransfer)
// TODO: Crear un PaymentProcessor con la tarjeta de crédito usando NewPaymentProcessor
// y ejecutar un pago con amount1, luego imprimir el resultado
// TODO: Crear un slice de PaymentMethod que contenga los tres tipos de pago
// TODO: Usar ProcessAll para procesar todos los pagos con amount2
// e imprimir cada resultado en su propia línea
}
Todas las lecciones de Programación Orientada a Objetos
1Fundamentos de POO en Go
Archivos externosEspacio de trabajo y módulos de GoPaquetes e importacionesNombres exportados vs. no exportadosIntroducción a la POO en GoStructs como clasesDefinición de métodos en structsReceptores de puntero vs. de valorInicialización de structsFunciones constructorasResumen - Calculadora simple4Interfaces
Introducción a las interfacesImplementación implícitaLa interfaz como contratoInterfaz vacía (any)Type AssertionType SwitchComposición de interfacesInterfaces Stringer y ErrorResumen: Calculadora de figuras7Encapsulamiento
Campos exportados vs. no exportadosEncapsulamiento a nivel de paqueteMétodos Getter y SetterOcultamiento de información en GoResumen - Registros de estudiantes10Genéricos (Go 1.18+)
Introducción a los GenéricosParámetros de tipoRestricciones de tipoStructs genéricosSolución alternativa para métodos genéricosResumen - Colección genérica13Patrones de diseño - Parte 1
Introducción a los patrones de diseñoPatrón SingletonPatrón FactoryPatrón Abstract FactoryPatrón ObserverPatrón Strategy2Inmersión profunda en Tipos y Structs
Tipos básicos y compuestosDefiniciones de tipos personalizadosEtiquetas de StructsStructs anónimosStructs anidadosValores cero y por defectoRepaso - Libreta de contactos5Composición sobre herencia
Por qué Go no tiene herenciaConceptos básicos de incrustación de structsPromoción de métodosIncrustación de múltiples structsIncrustación vs AgregaciónShadowing de métodos incrustadosResumen - Jerarquía de empleados8Manejo de Errores y OOP
La interfaz errorTipos de errores personalizadosEnvoltura de errores (fmt.Errorf)Errores centinelaerrors.Is() y errors.As()Panic, Defer y RecoverResumen - Analizador de archivos3Punteros y Memoria
Fundamentos de punteros en GoPunteros a StructsPaso por valor vs referenciaLa función new()Garbage Collection en GoResumen - Constructor de Linked List6Polimorfismo en Go
Polimorfismo mediante interfacesDuck Typing en GoReglas de satisfacción de interfacesColecciones polimórficasInyección de dependenciasResumen - Procesador de pagos9Concurrencia y POO
Fundamentos de GoroutinesChannels y comunicaciónChannels con buffer vs. sin bufferSentencia Selectsync.Mutex y sync.RWMutexsync.WaitGroupDiseño de estructuras Thread-SafeResumen - Worker Pool