Implementación del Patrón de Diseño Strategy en Go
Clase 13 de 19 • Curso de Go Avanzado: Concurrencia y Patrones de Diseño
Resumen
¿Qué es el patrón de diseño Strategy?
En el mundo de la programación, la implementación de patrones de diseño puede marcar una diferencia sustancial en la claridad y eficiencia del código. El patrón de diseño Strategy, conocido por su estilo de comportamiento, ofrece una forma excelente de definir una serie de algoritmos de manera que se puedan intercambiar sin cambiar el código que los utiliza. Este enfoque no solo mejora la organización del código, sino que también facilita su mantenimiento y escalabilidad. Vamos a explorar cómo este patrón puede ser implementado en Go, lo que permite la creación de aplicaciones limpias y modulares.
¿Cómo se estructura el patrón Strategy en Go?
Para implementar el patrón Strategy en Go, primero creamos un archivo nuevo denominado strategy.go
. Comenzamos por definir el paquete main y luego procedemos a crear un nuevo struct llamado PasswordProtector
. Este actuaría como un contenedor para diferentes algoritmos de hachís o hashing, plataforma a través de la cual el patrón Strategy muestra todo su potencial. Aquí se muestra cómo se implementa:
package main
type PasswordProtector struct {
user string
passwordName string
hashAlgo HashAlgorithm
}
type HashAlgorithm interface {
Hash(p PasswordProtector)
}
func NewPasswordProtector(user, passwordName string, algo HashAlgorithm) PasswordProtector {
return PasswordProtector{user: user, passwordName: passwordName, hashAlgo: algo}
}
func (p *PasswordProtector) SetHashAlgorithm(algo HashAlgorithm) {
p.hashAlgo = algo
}
func (p *PasswordProtector) Hash() {
p.hashAlgo.Hash(*p)
}
¿Cómo se implementan algoritmos de hash intercambiables?
Dentro de este marco, cada algoritmo de hashing se implementa como una clase aislada. Utilizaremos ejemplos como SHA y MD5, en donde ambos algoritmos pueden ser intercambiables gracias a la estructura del patrón Strategy.
type SHA struct{}
func (s SHA) Hash(p PasswordProtector) {
fmt.Printf("Hashing usando SHA para el password: %s\n", p.passwordName)
}
type MD5 struct{}
func (m MD5) Hash(p PasswordProtector) {
fmt.Printf("Hashing usando MD5 para el password: %s\n", p.passwordName)
}
En el ejemplo anterior, hemos creado dos algoritmos distintos (SHA
y MD5
) que implementan la interfaz HashAlgorithm
. Esta estructura permite que los algoritmos se intercambien dinámicamente según la necesidad.
¿Cómo se utiliza el patrón Strategy en una función main?
La funcionalidad del patrón Strategy se pone a prueba dentro de la función main, donde los algoritmos son fácilmente intercambiables sin necesidad de modificar el código que los invoca directamente. Eso se logra mediante la capacidad del PasswordProtector
de cambiar el algoritmo de hash en pleno vuelo.
func main() {
sha := SHA{}
md5 := MD5{}
passwordProtector := NewPasswordProtector("Nestor", "Gmail", sha)
passwordProtector.Hash()
passwordProtector.SetHashAlgorithm(md5)
passwordProtector.Hash()
}
Al ejecutar el código, se observa cómo inicialmente se utiliza el algoritmo de SHA
, y posteriormente se cambia a MD5
. Esta capacidad de intercambio demuestra la flexibilidad y adaptabilidad que el patrón Strategy confiere al desarrollo del software. Implementar este patrón no solo resulta en un código más limpio y reutilizable, sino que también se adhiere a principios como el de responsabilidad única y la apertura al cambio sin modificar estructuras existentes. Así se cultiva un ciclo de desarrollo robusto y adaptable a futuros cambios o mejoras.