Я часто сталкиваюсь с этой проблемой, особенно в Java, даже если я думаю, что это общая проблема ООП. То есть: поднятие исключения выявляет проблему дизайна.
Предположим, что у меня есть класс, который имеет String name
поле и String surname
поле.
Затем он использует эти поля, чтобы составить полное имя человека, чтобы отобразить его в каком-то документе, скажем, в счете.
public void String name;
public void String surname;
public String getCompleteName() {return name + " " + surname;}
public void displayCompleteNameOnInvoice() {
String completeName = getCompleteName();
//do something with it....
}
Теперь я хочу усилить поведение моего класса, выдавая ошибку, если displayCompleteNameOnInvoice
вызывается до того, как имя было присвоено. Это кажется хорошей идеей, не так ли?
Я могу добавить код, вызывающий исключение, в getCompleteName
метод. Но таким образом я нарушаю «неявный» контракт с пользователем класса; в общем случае геттеры не должны генерировать исключения, если их значения не установлены. Хорошо, это не стандартный метод получения, поскольку он не возвращает ни одного поля, но с точки зрения пользователя различие может быть слишком тонким, чтобы об этом думать.
Или я могу выбросить исключение изнутри displayCompleteNameOnInvoice
. Но чтобы сделать это, я должен проверить напрямую name
или surname
поля, и, делая это, я бы нарушил абстракцию, представленную getCompleteName
. Именно этот метод отвечает за проверку и создание полного имени. На основании других данных он может даже решить, что в некоторых случаях этого достаточно surname
.
Таким образом, единственная возможность, по-видимому, состоит в том, чтобы изменить семантику метода getCompleteName
на то composeCompleteName
, что предполагает более «активное» поведение и, соответственно, возможность генерировать исключение.
Это лучшее дизайнерское решение? Я всегда ищу лучший баланс между простотой и правильностью. Есть ли ссылка на дизайн для этой проблемы?
displayCompleteNameOnInvoice
можете просто вызвать исключение, если getCompleteName
вернетесь null
, не так ли?