Относится ли «скажи, не спрашивай» к проверке пользовательского ввода? - PullRequest
5 голосов
/ 18 февраля 2009

Я почему-то не обращал внимания на принцип ООП "говори, не спрашивай" все эти годы, потому что я впервые узнал об этом пару дней назад.

Но контекстом было обсуждение кода проверки, который был перемещен со страницы веб-формы ASP.NET в объект данных / бизнес, и не было метода «Validate ()», это был просто метод сохранения, который сам по себе сделал проверку и (предположительно) поднял исключение. Я спросил, почему это было разработано таким образом, и я был направлен на принцип ООП «говори, не спрашивай», о котором я никогда не слышал, поэтому мы вместе посмотрели на Google, и я сразу получил образование. ;)

Тем не менее, что-то не пахнет правильно, не следует ли очищать данные до того, как они будут переданы от пользователя в бизнес-уровень, где они обрабатываются и / или собираются, а не наоборот? Я не понимаю, как это можно сделать для хорошего дизайна.

Кажется, что правило "говори, не спрашивай" относится к идее, что вы не должны спрашивать целевой объект о состоянии целевого объекта, и что этот принцип никогда не предназначался для применения к данным. передал в целевой объект.

Ответы [ 3 ]

3 голосов
/ 18 февраля 2009

Я подумал, что это звучит так, будто множество «лучших практик» и «методологий проектирования» пошло не так, но теперь это для меня имеет смысл. Посмотрите на это так:

Представьте себе, что проверка достоверности включена в бизнес-объект, но «что мне делать, если проверка не удалась» на уровне представления. Это позволило бы нескольким различным уровням представления использовать одну и ту же логику проверки, но обрабатывать ошибки по-разному.

public Foo
{
  Validate(Baz bar)
  {
      if(!is_number(bar)) throw numberexception();
  }

  AssignBar(Baz bar)
  {
      Validate(bar);
  }
}


//...

try
{
  foo.AssignBar(bar);
}
catch(numberexception e)
{
  alert('Not a number!');
}

n.b. Вы можете спорить все, что вы хотите о создании исключений, это было задумано в качестве примера. Возвращайте состояния, bools, все, что вы хотите.

2 голосов
/ 18 февраля 2009

Я согласен с AviewAview, но генерирую исключения, только если пользователь скажет (не если он попросит):

public Foo
{
  bool Validate(Baz bar)
  {
        if(!is_number(bar)) return false;
        return true;
  }

  AssignBar(Baz bar)
  {
        if (!Validate(bar)) throw numberexception();
  }
}

Скажите:

try
{
  foo.AssignBar(bar);
}
catch(numberexception e)
{
  alert('Not a number!');
}

Спросите:

if (foo.Validate(bar)
{
  foo.AssignBar(bar);
}
else
{
  alert('Not a number!');
}

Таким образом, AssignBar ожидает строку VALID и выдает исключение, если это не так, но мы также предоставляем метод Validate, который не вызывает исключение.

0 голосов
/ 18 февраля 2009

Интересно, не является ли это вопросом «разделения интересов», а не вопросом «не говори» Кто несет ответственность за проверку данных? Возможно, именно эта вещь ответственна за сохранение этого.

Конечно, иногда бывает полезно проверить данные в несколько слоев. Если это так для вашего приложения, у меня нет проблем с отображением логики проверки на уровне «пользователя». Но я все еще хотел бы это на бизнес-уровне.

...