Валидация сущности

skwee

Новичок
Добрый день!
У меня в системе есть сущности (Entity) и есть объекты значения (Value Object).
Например:
PHP:
class ValueObject {
 public function __construct() {
   $this->validate();
 }

 protected function validate() {
 }
}

class EmailAddress extends ValueObject {
 private $email;
 public function __construct($email) {
  $this->email = $email;
  parent::__construct();
 }

 protected function validate() {
   if(not $this->email is valid email)
    throw new InvalidValueObjectException('Email address is invalid');
 }
}
Объекты значения умеют валедировать себя. то есть такое не прокатит:
PHP:
$email = new ValueObject\EmailAddress('foo');

Сущность содержит в себе объекты значения:
PHP:
class User extends Entity {
private $email;
public function getEmail() { return $this->email; }
public function setEmail($addr) { $this->email = new ValueObject\EmailAddress($addr); }
}

Теперь проблемы:
1. Можно создать только валидную сущность, то есть если при ее создании что то из ее value objectов не валидно то должен быть брошен эксепшен.
PHP:
public function User::__construct($username, $password, $emailAddress) {
  $this->username = new ValueObject\Username($username);
  $this->password = new ValueObject\PasswordHash($password);
  $this->email = new ValueObject\EmailAddress($emailAddress);
}
но ради удобства я бы хотел получить все ошибки при валидации, а как мы все знаем если username не валиден то проверка password и email уже не совершится из за эксепшена который бросит ValueObject\Username::validate()

2. Сущность не может иметь не валидное состояние, то есть это
PHP:
$user->setEmail('foo');
должно сразу кинуть эксепшен (это я говорю к тому что нельзя перенести валидацию например на этап сохранения сущности в БД или вызова некого метода $user->validate()).

3. При восстановлении из БД, сущность валедировать не надо (я предполагаю что если она уже в БД то прошла валидацию).

Посоветуйте пожалуйста способ валидации чтобы выполнялись все 3 условия.

Спасибо за ранее! :)
 

С.

Продвинутый новичок
Не надо создавать такие абстрактные объекты, коль сам в них запутывешься. Никому просто не интерестно рабираться в твоем огороде. Пусть объекты будут ближе к жизни, а лицо проще.
 

alekciy

Новичок
Поддержу С.. Нагорожен такой огород, что кроме "ну нахрена?!" ни чего в голову не приходит.

P.S. ООП ради ООП приводит к ООП головного мозга.
 

skwee

Новичок
Да я вот тоже сижу да мучаюсь, но очень удобна конструкция где можно написать
PHP:
$email = new EmailAddress('foo');
или более приблежонный к жизни вариант
PHP:
$currency = new Currency('EUR');
$countriesUsed = $currency->getCountriesUsed();
$sign = $currency->getSign();
//=============
$d100 = new Currency('USD', 100);
$inEur = new Currency_Convert_Service($d100, 'EUR');
не надо будет делать всякие там проверки есть ли такой currency EUR, USD просто если его нету будет брошен эксепшен.
 

С.

Продвинутый новичок
Да я вот тоже сижу да мучаюсь, но очень удобна конструкция где можно написать
PHP:
$email = new EmailAddress('foo');
Действительно удобно. Вместо одной операции проверки, надо сначала отловить эксепшн, а затем в нем проверить, по какому поводу сыр-бор

$inEur = new Currency_Convert_Service($d100, 'EUR');
А вот за такое надо подвешивать за яйца, до полного понимания, чем объект отличается от метода.
 

alekciy

Новичок
не надо будет делать всякие там проверки есть ли такой currency EUR, USD просто если его нету будет брошен эксепшен.
Ну так и в чем проблема-то? Задали не корректную валюту, бросился эксепшен, код остановился. Вполне нормально ибо не важно какие там дальше валидаторы сработали или нет, потому как если не сработал этот, то дальше выполнять обработку смысла нет, потому что дальше завязка шла на эти данные.

В общем не вижу в данных задачах ни какой проблемы кроме обильного использования объектов с крайне сомнительной целью.
 

alekciy

Новичок
А вот за такое надо подвешивать за яйца, до полного понимания, чем объект отличается от метода.
Поддержу. Писать какие-то ООП валидаторы рановато, если не понимать, что так писать нельзя. Правильно было, что-то в духе:
PHP:
$money = new Money();
$money->setAmount(100, 'USD');
$inEur = $money->getAmount('EUR');
 

skwee

Новичок
Действительно удобно. Вместо одной операции проверки, надо сначала отловить эксепшн, а затем в нем проверить, по какому поводу сыр-бор
PHP:
try{
$currency = new Currency('EUR');
}catch(InvalidCurrencyException $e) {
$this->view->errors[] = $e->getMessage();
return;
}
или
PHP:
$currency = new Currency('EUR');
if(!$currency->isValid()){
$this->view->errors[] = "bla bla bla";
return;
}
где профит\не профит?

А вот за такое надо подвешивать за яйца, до полного понимания, чем объект отличается от метода.
на подвешивай
http://framework.zend.com/manual/en/zend.currency.exchange.html

не надо хамить. У каждого свои задачи и те не знаешь почему написано так или эдак. к тому же я не буду приводить тут вес сорс код токо чтоб показать почему удобнее использовать объекты для email, currency etc..

Ну так и в чем проблема-то? Задали не корректную валюту, бросился эксепшен, код остановился. Вполне нормально ибо не важно какие там дальше валидаторы сработали или нет, потому как если не сработал этот, то дальше выполнять обработку смысла нет, потому что дальше завязка шла на эти данные.

В общем не вижу в данных задачах ни какой проблемы кроме обильного использования объектов с крайне сомнительной целью.
да все хорошо я не спорю, токо ты когда заполняешь форму на сайте ты же не получаешь ошибку за ошибкой аля "юзернейм занят" "порол не совпадает", а получаешь лист всех ошибок сразу.


Поддержу. Писать какие-то ООП валидаторы рановато, если не понимать, что так писать нельзя. Правильно было, что-то в духе:
PHP:
$money = new Money();
$money->setAmount(100, 'USD');
$inEur = $money->getAmount('EUR');
где написано что так писать нельзя?
так
PHP:
$foo = (new Foo())->getFoo();
тоже писать нельзя (как минимум а пхп до 5.4) но давай не будем придиратся к примерам на форумах =)
 
Сверху