Я недавно столкнулся с этой проблемой в проекте: есть цепочка вложенных объектов, например: класс A содержит переменную экземпляра класса B, которая в свою очередь имеет переменную экземпляра класса C, ..., пока у нас не появится узел в дереве класса Z.
----- ----- ----- ----- -----
| A | ---> | B | ---> | C | ---> | D | ---> ... ---> | Z |
----- ----- ----- ----- -----
Каждый класс предоставляет методы получения и установки для своих членов. Родительский экземпляр A создается анализатором XML, и для любого объекта в цепочке допустимо иметь значение null.
Теперь представьте, что в определенной точке приложения у нас есть ссылка на экземпляр A, и только если он содержит объект Z, мы должны вызвать метод для него. Используя регулярные проверки, мы получаем этот код:
A parentObject;
if(parentObject.getB() != null &&
parentObject.getB().getC() != null &&
parentObject.getB().getC().getD() != null &&
parentObject.getB().getC().getD().getE() != null &&
...
parentObject.getB().getC().getD().getE().get...getZ() != null){
parentObject.getB().getC().getD().getE().get...getZ().doSomething();
}
Я знаю, что исключения не должны использоваться для обычного потока управления, но вместо предыдущего кода я видел, как некоторые программисты делают это:
try {
parentObject.getB().getC().getD().getE().get...getZ().doSomething();
} catch (NullPointerException e){}
Проблема с этим кодом заключается в том, что он может сбить с толку при его обслуживании, поскольку он не показывает, какие объекты могут быть нулевыми. Но, с другой стороны, гораздо более кратким и менее "телескопическим".
Допустимо ли это делать для экономии времени разработки?
Как можно изменить API, чтобы избежать этой проблемы?
Единственное, что я могу придумать, чтобы избежать длительной нулевой проверки, - предоставить пустые экземпляры вложенных объектов и предоставить методы isValid
для каждого из них, но это не приведет к созданию большого количества ненужных объектов в памяти
(я использовал код Java, но тот же вопрос может применяться к свойствам C #)
Спасибо.