Напишите текст проверки


Я использую этот узор в первый раз и хотел проверить, если это правильная реализация.

class.validator.strategy.php

abstract class ValidatorStrategy
{
    abstract public function check( $name, $val );

}

class.text.validator.php

class TextValidator extends ValidatorStrategy
{

    public function check( $name, $val )
    {
         //logic here
    }
}

class.number.validator.php

class NumberValidator extends ValidatorStrategy
{

    public function check( $name, $val )
    {
         //logic here
    }
}

class.validator.php

include('validator.strategy.php');
include('class.text.validator.php');
include('class.number.validator.php');
include('class.email.validator.php');

class Validator
{

    //holds strategy object
    protected $validatorStrategy = array();

    //holds form field
    protected $fields = array();

    public function __construct()
    {
        $this->validatorStrategy[ 'text' ] = new TextValidator();
        $this->validatorStrategy[ 'number' ] = new NumberValidator();
        $this->validatorStrategy[ 'email' ] = new EmailValidator();
    }

    public function ruleForTextField( $name, $value )
    {
        $this->fields[ $name ][ 'value' ] = $value;
        $this->fields[ $name ][ 'type' ] = 'text';
    }

    public function ruleForNumbertField( $name, $value )
    {
        $this->fields[ $name ][ 'value' ] = $value;
        $this->fields[ $name ][ 'type' ] = 'number';
    }

    public function ruleForEmailField( $name, $value )
    {
        $this->fields[ $name ][ 'value' ] = $value;
        $this->fields[ $name ][ 'type' ] = 'email';

    }

    public function isValidate()
    {
        $status = 0;

        foreach ( $this->fields as $key => $val )
        {
            if ( !$this->validatorStrategy[ $val[ 'type' ] ]->check( $key, $val ) )
            {
                $status++;
            }

        if ( $status == 0 )
        {
            return true;
        }
        else
        {
            return false;
        }
    }

}


Использует:

$validator = new Validator();
$validator->ruleForTextField('username', $_POST['username'] );
$validator->ruleForNumberField('age', $_POST['age'] );
$validator->ruleForEmailField('email', $_POST['email'] );

if($validator->isValidate())
{
    echo 'validated';
}
else
{
   echo 'fail validation';
}

Внутри isValidate() метод перебора против всех валидатор стратегии и проанализировать соответствующую логику.

Это правильный способ использовать этот шаблон?



Комментарии
3 ответа

Я не уверен, что это действительно стратегия схеме: вы никогда не полагаться на ValidatorStrategy интерфейс, нет никакого реального выбора стратегии (есть прямые призывы к валидатору методы) и нельзя добавить еще стратегии без торможения контекста объекта (валидатор класса).

Что вы можете сделать рефакторинг валидатор , чтобы ввести ValidatorStrategy экземпляр для каждого поля, для проверки. Назовем этот измененный класс FormValidatorвалидатор инстанции проверяет одно поле) и посмотреть, как она может быть реализована:

class FormValidator
{
/**
* @var array of StrategyValidator
*/
protected $validators;

/**
*
* @param string $name
* @param ValidatorStrategy $strategy
*/
public function addValidator($name, ValidatorStrategy $strategy)
{
$this->validators[$name] = $strategy;
}

/**
*
* @param array $form
*/
public function isValid($form)
{
foreach ($this->validators as $name => $validator)
{
if (!$validator->isValid($form[$name]))
{
return false;
}
}

return true;
}
}

$formValidator = new FormValidator();
$formValidator->addValidator('username', new TextValidator());
$formValidator->addValidator('age', new NumberValidator());
$formValidator->addValidator('email', new EmailValidator());

// Now you can reuse $formValidator where you want
$values = array(
'username' => $_POST['username'],
'age' => $_POST['age'],
'email' => $_POST['email'],
);

if($formValidator->isValid($values))
{
echo 'validated';
}
else
{
echo 'fail validation';
}

Некоторые советы:


  • Советы именования Джон Крафт отличный, Вы должны следовать за ними: метод, начиная с*, имеет* возвращает логическое значение, методы, начиная с* и комплект* средства доступа и т. д.

  • Всегда найдите минутку, чтобы думать о вы роли классов, и выводят их имя от него

  • При работе с логическими значениями, использовать логические переменные ($статус)

  • При использовании нового класса MyClass() в метод класса, спросите себя, если вы не закрываем классы к будущей эволюции, особенно если класс MyClass реализует интерфейс: это признак того, что класс может меняться, и мы должны полагаться на интерфейс (см. инъекции зависимостей)

Этот последний совет проиллюстрирован метод addValidator() в моем примере.

2
ответ дан 20 июня 2011 в 05:06 Источник Поделиться

Нет, шаблон стратегия опирается на интерфейс, позволяющий определить состав функций во время выполнения. Обратите внимание, что это проще расширить с новый выступая функциональности, и может быть использована для выполнения во время выполнения. Здесь вы не просто используя массив экземпляров интерфейс, чтобы сделать несколько проверок.

И. Е.

Интерфейс для шаблона

public interface Speak {
public void execute();
}

Реализации шаблона

public class Quack extends Speak {
public void execute() { /* Quack */ }
}

public class Bark extends Speak {
public void execute() { /* bark */ }
}

Класс, который использует стратегию

public Animal {
private Speak _speak;
public Animal(Speak s) { _speak = s; }
}

Пример использования

main() {
new Animal(new Bark()); /* creates animal that barks */
new Animal(new Quack()); /* creates animal that quacks */
}

4
ответ дан 20 июня 2011 в 01:06 Источник Поделиться

Я не пишу на PHP, поэтому, пожалуйста, медведь со мной; но я не люблю метод isValidate. В псевдо-код... я обычно пишу что-то вроде

foreach(var validator in validatorCollection)
if validator->Check = false
return false

return true

Кроме того, некоторые имена методов немного непонятно. Список имен я предпочитаю видеть...


  • Функция IsValid, а не проверить

  • Функция IsValid, а не IsValidate

Кроме того, я думаю, что ваш пример является плохим для использования шаблон стратегия, но я предполагаю, что это потому, что это простой пример.

Как пример, мы используем шаблон стратегии для определения способов доставки пакетов. У нас есть валидатор для UPS, и валидатор для USPS, и валидатор для FedEx. Мы передаем объект пакет для Каждый из валидаторов для определения права. Каждый из этих проверяющих есть список правил (вес, рост, опасных материалов и т. д.), Чтобы определить, что пакет может быть отправлен, что способ.

ListOfCarriers result
ListOfCarriers carriers
foreach(carrier in carriers)
if(carrier.canShip(package)
result.add(carrier)
return result

Способ перевозчика canShip может выглядеть как...

function canShip(package)
return weightRule.Applies(package)
and heightRule.Applies(package)
and hazmatRule.Applies(package)

и weightRule может выглядеть...

function Applies(package)
return package.weight < 70.0

1
ответ дан 20 июня 2011 в 04:06 Источник Поделиться