Pregunta

Aquí hay una versión simplificada de un método que tengo.
Todavía se ve muy complejo
¿Cómo refactorizaría esta locura?

protected function isTextValid()
{
    if( $this->data['allow_num'] ){
        if( $this->data['allow_space'] ){
            if( preg_match( '#^[a-zA-Z0-9\s]$#', $this->val ) ){
                return true;
            }
            else{
                $this->messages = foo ? foo : bar;
                return false;
            }
        }
        else{
            if( preg_match( '#^[a-zA-Z0-9]$#', $this->val ) ){
                return true;
            }
            else{
                $this->messages = foo? foor : bar;
                return false;
            }
        }
    }
    else{
        if( $this->data['allow_space'] ){
            if( preg_match( '#^[a-zA-Z\s]$#', $this->val ) ){
                return true;
            }
            else{
                $this->messages = foo ? foor : bar;
                return false;
            }
        }
        else{
            if( preg_match( '#^[a-zA-Z]$#', $this->val  ) ){
                return true;
            }
            else{
                $this->messages =  foo ? foo: bar;
                return false;
            }
        }
    }
}

Intento refactorizarlo usando el patrón de estado, pero hasta nada, ya que no estoy muy familiarizado con el patrón.
Esto es lo que hice, pero lo abondon rápido.

interface ValidatorState{
  public function isValid();
}

class AllowNumberAndSpace implement ValidatorState{
   protected $context;
   public function __construct(Context $context){$this->context = $context}

    public function isValid(){
       if( preg_match( .. ) ){
            return true;
        }
        else{
            $this->messages = foo ? foo : bar;
            return false;
        }
      $this->context->setState(OtherState);
    }
}

Class Context{
    protected $state;
    protected $allow_num_space_state;

    public function __construct(){
        $this->allow_num_space_state = new AllowNumberAndSpace($this);
       $this->state = $this->allow_num_space_state;
    }

   public function isValid(){
       return $this->state->isValid();
   }

  public function setState($state){$this->state = $state}
}

Obviamente esta única prueba primero if rama, ¿cómo puedo consultar automáticamente otra rama también?
Estoy bastante seguro de que hay algo mal con mi enfoque.
¿Hay alguna forma de arreglar este patrón de estado para probar a todos? if ¿rama?

Editado
Lo que hace este método es verificar si $this->value contener el valor esperado basado en el atributo de configuración almacenado en $this->data

Ejemplo $this->data = array('allow_num'=>true), si $this->value='a1' Se considera un ejemplo válido $this->data = array('allow_num'=>false), si $this->value='a1' es considerado inválido

¿Hay alguna forma de simplificar este método?

¿Fue útil?

Solución

En primer lugar, trate de no complicar en exceso esto. En mi opinión, el código no es lo suficientemente complejo como para justificar el uso de patrones de diseño orientados a objetos.

Como lo veo, su código básicamente se reduce a validar una entrada con diferentes expresiones regulares (que dependen de algunos indicadores especificados por el usuario como allow_num y allow_space.

Entonces, mi sugerencia es la siguiente (la refactorización básica es construir parte de la expresión regular basada en la configuración antes usando esta expresión en cualquier lógica de validación):

protected function isTextValid() {
    $allowedCharacters = 'A-Za-z';

    if ($this->data['allow_spaces']) {
        $allowedCharacters .= '\s';
    }
    if ($this->data['allow_num']) {
        $allowedCharacters .= '\d';
    }

    if (!preg_match("#^[{$allowedCharacters}]+\$#", $this->value)) {
        $this->messages = foo ? foor : bar;
        return false;
    }
    return true;
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top