Подтвердить что ты не робот

Должен ли класс проверять себя или создавать другой класс для его проверки?

Скажем, у меня есть класс вроде:

class NavigationData
{
  float roll;
  float pitch;
  double latitude;
  double longitude;
}

и если я хочу создать метод:

const bool validate() const;

который в основном проверяет, содержат ли 4 поля допустимые значения.

Должен ли validate() быть частью класса NavigationData или создавать что-то вроде NavigationDataValidator, содержащего метод validate (const NavigationData &).

Я просто даю простой пример, очевидно, что мой настоящий класс намного сложнее этого. Я ищу хорошие принципы OO.

По другому: с помощью метода, как мы узнаем, должен ли он принадлежать классу или должен принадлежать отдельному классу?

4b9b3361

Ответ 1

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

Однако "логически последовательная и действительная" отличается от "имеет смысл в домене", поэтому иногда ответственность внешнего класса заключается в обеспечении соблюдения правил домена. Например, PersonValidator может потребовать, чтобы Person имел номер телефона, который находится в США. Но Person не обязательно должен знать что-либо о том, есть ли PhoneNumber в США.

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

Ответ 2

Правильный ответ: зависит от.

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

Ответ 3

Ваш класс должен быть разработан таким образом и предоставлять такие методы, которые validate() всегда верны:

  • после вызова любого публичного конструктора
  • до и после вызова любого общедоступного метода
  • (в С++ - земля) до вызова деструктора

Такие методы validate() называются инвариантами класса и являются важной частью Design by Contract.

Ответ 4

Я бы сказал, это зависит. Если данные класса проверяются изолированно, я бы поместил этот метод в класс, но если для проверки требуется контекст, я бы создал класс проверки на основе некоторого интерфейса.

Ответ 5

В зависимости...

Иногда проверки не являются частью самого класса, но бизнес-логика и добавление ее в класс будет препятствовать повторному использованию, и поэтому использование проверяющего класса является хорошим. В противном случае класс должен иметь возможность проверять себя.

Ответ 6

Я бы сказал, что он проверяет себя до тех пор, пока действительные значения не зависят от того, что другие классы используют NavigationData.

В принципе, до тех пор, пока широта и высота тона должны всегда находиться между +/- 90 градусов, а долгота и валик всегда находятся между +/- 180 градусов, сохраните валидатор в классе.

(Кстати, как насчет заголовка?)

Ответ 7

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

Если у вас есть простой объект передачи данных, он, вероятно, не должен проверять себя.

Если у вас есть класс Domain Model, он должен выполнить некоторую проверку.

P.S. только мои личные предпочтения: isValid() вместо validate(), когда метод возвращает логическое значение.

Ответ 8

Как уже было сказано, это зависит.

Но в вашем случае я бы пошел на другое решение, создаю новый неизменный класс для геокоординат

class GeoCoordinates
{
    double Latitude;
    double Longitude;
}

И пусть этот класс проверяет, что широта и долгота находятся в допустимых пределах. Например, вам, вероятно, понадобятся и другие места.

class Airport
{
    GeoCoordinates Location;
    ...
}