No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Strategy

13/19
Recursos

Aportes 6

Preguntas 0

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

Usando funciones de hasheo reales.

package main

import (
	"crypto/md5"
	"crypto/sha1"
	"crypto/sha256"
	"encoding/hex"
	"fmt"
)

type HashAlgorithm interface {
	Hash(p *passwordProtector)
}

type passwordProtector struct {
	user          string
	passwordName  string
	hashAlgorithm HashAlgorithm
}

func NewPasswordProtector(user string, passName string, algorithm HashAlgorithm) *passwordProtector {
	return &passwordProtector{
		user:          user,
		passwordName:  passName,
		hashAlgorithm: algorithm,
	}
}

func (p *passwordProtector) setHashAlgorithm(hash HashAlgorithm) {
	p.hashAlgorithm = hash
}

func (p *passwordProtector) Protect() {
	p.hashAlgorithm.Hash(p)
}

type SHA struct{}
type SHA256 struct{}
type MD5 struct{}

func (SHA) Hash(p *passwordProtector) {
	h := sha1.New()
	h.Write([]byte(p.passwordName))
	sha1Hash := hex.EncodeToString(h.Sum(nil))
	fmt.Printf("Hashing using SHA: %s\n", sha1Hash)
}

func (SHA256) Hash(p *passwordProtector) {
	h := sha256.New()
	h.Write([]byte(p.passwordName))
	sha256Hash := hex.EncodeToString(h.Sum(nil))
	fmt.Printf("Hashing using SHA256: %s\n", sha256Hash)
}

func (MD5) Hash(p *passwordProtector) {
	h := md5.New()
	h.Write([]byte(p.passwordName))
	md5Hash := hex.EncodeToString(h.Sum(nil))
	fmt.Printf("Hashing using MD5: %s\n", md5Hash)
}

func main() {
	sha := SHA{}
	passProtector := NewPasswordProtector("usuario", "mipassword", sha)
	passProtector.Protect()

	// again new hash algorithm
	sha256 := SHA256{}
	passProtector.setHashAlgorithm(sha256)
	passProtector.Protect()

	// set new hash algorithm
	md5 := MD5{}
	passProtector.setHashAlgorithm(md5)
	passProtector.Protect()

}

La unica cosa que me no me gusto de esta clase es que la funcion Hash de PasswordProtector puede confundir con que PasswordProtector implementa la interface HashAlgorithm y no es asi.

package main

import "fmt"

type HashAlgorithm interface {
        Hash(p *passwordProtector)
}

type passwordProtector struct {
        user          string
        passwordName  string
        hashAlgorithm HashAlgorithm
}

func NewPasswordProtector(user string, passName string, algorithm HashAlgorithm) *passwordProtector {
        return &passwordProtector{
                user:          user,
                passwordName:  passName,
                hashAlgorithm: algorithm,
        }
}

func (p *passwordProtector) setHashAlgorithm(hash HashAlgorithm) {
        p.hashAlgorithm = hash
}

func (p *passwordProtector) Protect() {
        p.hashAlgorithm.Hash(p)
}

type SHA struct{}
type SHA256 struct{}
type MD5 struct{}

func (SHA) Hash(p *passwordProtector) {
        fmt.Printf("Hashing using SHA: %sSHA\n", p.passwordName)
}

func (SHA256) Hash(p *passwordProtector) {
        fmt.Printf("Hashing using SHA256: %s256SHA\n", p.passwordName)
}

func (MD5) Hash(p *passwordProtector) {
        fmt.Printf("Hashing using MD5: %sMD5\n", p.passwordName)
}

func main() {
        sha := SHA{}
        passProtector := NewPasswordProtector("juancsr", "juancasr_password", sha)
        passProtector.Protect()

        // set new hash algorithm
        md5 := MD5{}
        passProtector.setHashAlgorithm(md5)
        passProtector.Protect()

        // again new hash algorithm
        sha256 := SHA256{}
        passProtector.setHashAlgorithm(sha256)
        passProtector.Protect()
}

Strategy
Es un patrón de diseño de comportamiento, consiste en definir una familia de funciones similares en una clase base, en el caso de Go seria un struct. Parte desde los principios SOLID.

Vi que nadie anotó en este patrón la referencia a la web mágica https://refactoring.guru/es/design-patterns/strategy

Aquí otra explicación:
Patron Strategy

package main

// Definir una familia de algoritmos en structs separados
// Clase base que las usa y pueda ir intercambiando

type PasswordProtector struct {
	user          string
	passwordName  string
	hashAlgorithm HashAlgorithm
}

type HashAlgorithm interface {
	Hash(p *PasswordProtector)
}

// Constructor
func NewPasswordProtector(user, passwordName string, hash HashAlgorithm) *PasswordProtector {
	return &PasswordProtector{user: user, passwordName: passwordName, hashAlgorithm: hash}
}

// Poder intercalar el algoritmo de hash
func (p *PasswordProtector) SetHash(hash HashAlgorithm) {
	p.hashAlgorithm = hash
}

// Ejecutar el algoritmo de hash
func (p *PasswordProtector) Hash() {
	p.hashAlgorithm.Hash(p)
}

type SHA struct{}

func (SHA) Hash(p *PasswordProtector) {
	println("Using SHA hash for", p.user, p.passwordName)
}

type MD5 struct{}

func (MD5) Hash(p *PasswordProtector) {
	println("Using MD5 hash for", p.user, p.passwordName)
}

func main() {
	protector := NewPasswordProtector("carlos", "password", SHA{})
	protector.Hash()

	protector.SetHash(MD5{})
	protector.Hash()
}